--- a/.hgtags Fri Sep 14 09:47:14 2012 -0700
+++ b/.hgtags Fri Sep 14 10:14:02 2012 -0700
@@ -175,3 +175,5 @@
382651d28f2502d371eca751962232c0e535e57a jdk8-b51
b67041a6cb508da18d2f5c7687e6a31e08bea4fc jdk8-b52
c7aa5cca1c01689a7b1a92411daf83684af05a33 jdk8-b53
+7c6aa31ff1b2ae48c1c686ebe1aadf0c3da5be15 jdk8-b54
+319f583f66db47395fa86127dd3ddb729eb7c64f jdk8-b55
--- a/.hgtags-top-repo Fri Sep 14 09:47:14 2012 -0700
+++ b/.hgtags-top-repo Fri Sep 14 10:14:02 2012 -0700
@@ -175,3 +175,5 @@
57c0aee7309050b9d6cfcbd202dc704e9260b377 jdk8-b51
8d24def5ceb3b8f2e857f2e18b2804fc59eecf8d jdk8-b52
febd7ff5280067ca482faaeb9418ae88764c1a35 jdk8-b53
+c1a277c6022affbc6855bdfb039511e73fbe2395 jdk8-b54
+b85b44cced2406792cfb9baab1377ff03e7001d8 jdk8-b55
--- a/corba/.hgtags Fri Sep 14 09:47:14 2012 -0700
+++ b/corba/.hgtags Fri Sep 14 10:14:02 2012 -0700
@@ -175,3 +175,5 @@
9b0f841ca9f7ee9bacf16a5ab41c4f829276bc6b jdk8-b51
80689ff9cb499837513f18a1136dac7f0686cd55 jdk8-b52
63aeb7a2472fb299134ad7388e0a111a5340b02d jdk8-b53
+16c82fc74695bab9b9e0fb05c086a5a08ba0082f jdk8-b54
+e8a0e84383d6fbd303ce44bd355fb25972b13286 jdk8-b55
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaResponseWaitingRoomImpl.java Fri Sep 14 09:47:14 2012 -0700
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaResponseWaitingRoomImpl.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,10 @@
package com.sun.corba.se.impl.transport;
-import java.util.Hashtable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
import org.omg.CORBA.CompletionStatus;
import org.omg.CORBA.SystemException;
@@ -68,7 +71,7 @@
private CorbaConnection connection;
// Maps requestId to an OutCallDesc.
- private Hashtable out_calls = null; // REVISIT - use int hastable/map
+ final private Map<Integer, OutCallDesc> out_calls;
public CorbaResponseWaitingRoomImpl(ORB orb, CorbaConnection connection)
{
@@ -76,7 +79,8 @@
wrapper = ORBUtilSystemException.get( orb,
CORBALogDomains.RPC_TRANSPORT ) ;
this.connection = connection;
- out_calls = new Hashtable();
+ out_calls =
+ Collections.synchronizedMap(new HashMap<Integer, OutCallDesc>());
}
////////////////////////////////////////////////////
@@ -139,7 +143,7 @@
return null;
}
- OutCallDesc call = (OutCallDesc)out_calls.get(requestId);
+ OutCallDesc call = out_calls.get(requestId);
if (call == null) {
throw wrapper.nullOutCall(CompletionStatus.COMPLETED_MAYBE);
}
@@ -197,7 +201,7 @@
LocateReplyOrReplyMessage header = (LocateReplyOrReplyMessage)
inputObject.getMessageHeader();
Integer requestId = new Integer(header.getRequestId());
- OutCallDesc call = (OutCallDesc) out_calls.get(requestId);
+ OutCallDesc call = out_calls.get(requestId);
if (orb.transportDebugFlag) {
dprint(".responseReceived: id/"
@@ -248,7 +252,6 @@
public int numberRegistered()
{
- // Note: Hashtable.size() is not synchronized
return out_calls.size();
}
@@ -264,29 +267,41 @@
dprint(".signalExceptionToAllWaiters: " + systemException);
}
- OutCallDesc call;
- java.util.Enumeration e = out_calls.elements();
- while(e.hasMoreElements()) {
- call = (OutCallDesc) e.nextElement();
+ synchronized (out_calls) {
+ if (orb.transportDebugFlag) {
+ dprint(".signalExceptionToAllWaiters: out_calls size :" +
+ out_calls.size());
+ }
- synchronized(call.done){
- // anything waiting for BufferManagerRead's fragment queue
- // needs to be cancelled
- CorbaMessageMediator corbaMsgMediator =
- (CorbaMessageMediator)call.messageMediator;
- CDRInputObject inputObject =
- (CDRInputObject)corbaMsgMediator.getInputObject();
- // IMPORTANT: If inputObject is null, then no need to tell
- // BufferManagerRead to cancel request processing.
- if (inputObject != null) {
- BufferManagerReadStream bufferManager =
- (BufferManagerReadStream)inputObject.getBufferManager();
- int requestId = corbaMsgMediator.getRequestId();
- bufferManager.cancelProcessing(requestId);
+ for (OutCallDesc call : out_calls.values()) {
+ if (orb.transportDebugFlag) {
+ dprint(".signalExceptionToAllWaiters: signaling " +
+ call);
}
- call.inputObject = null;
- call.exception = systemException;
- call.done.notify();
+ synchronized(call.done) {
+ try {
+ // anything waiting for BufferManagerRead's fragment queue
+ // needs to be cancelled
+ CorbaMessageMediator corbaMsgMediator =
+ (CorbaMessageMediator)call.messageMediator;
+ CDRInputObject inputObject =
+ (CDRInputObject)corbaMsgMediator.getInputObject();
+ // IMPORTANT: If inputObject is null, then no need to tell
+ // BufferManagerRead to cancel request processing.
+ if (inputObject != null) {
+ BufferManagerReadStream bufferManager =
+ (BufferManagerReadStream)inputObject.getBufferManager();
+ int requestId = corbaMsgMediator.getRequestId();
+ bufferManager.cancelProcessing(requestId);
+ }
+ } catch (Exception e) {
+ } finally {
+ // attempt to wake up waiting threads in all cases
+ call.inputObject = null;
+ call.exception = systemException;
+ call.done.notifyAll();
+ }
+ }
}
}
}
@@ -294,7 +309,7 @@
public MessageMediator getMessageMediator(int requestId)
{
Integer id = new Integer(requestId);
- OutCallDesc call = (OutCallDesc) out_calls.get(id);
+ OutCallDesc call = out_calls.get(id);
if (call == null) {
// This can happen when getting early reply fragments for a
// request which has completed (e.g., client marshaling error).
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java Fri Sep 14 09:47:14 2012 -0700
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1521,7 +1521,7 @@
// connection and give them the SystemException;
responseWaitingRoom.signalExceptionToAllWaiters(systemException);
-
+ } finally {
if (contactInfo != null) {
((OutboundConnectionCache)getConnectionCache()).remove(contactInfo);
} else if (acceptor != null) {
@@ -1542,7 +1542,6 @@
writeUnlock();
- } finally {
if (orb.transportDebugFlag) {
dprint(".purgeCalls<-: "
+ minor_code + "/" + die + "/" + lockHeld
--- a/hotspot/.hgtags Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/.hgtags Fri Sep 14 10:14:02 2012 -0700
@@ -272,3 +272,6 @@
6d0436885201db3f581523344a734793bb989549 jdk8-b52
54240c1b8e87758f28da2c6a569a926fd9e0910a jdk8-b53
9e3ae661284dc04185b029d85440fe7811f1ed07 hs24-b21
+e8fb566b94667f88462164defa654203f0ab6820 jdk8-b54
+09ea7e0752b306b8ae74713aeb4eb6263e1c6836 hs24-b22
+af0c8a0808516317333dcf9af15567cdd52761ce jdk8-b55
--- a/hotspot/agent/make/saenv.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/make/saenv.sh Fri Sep 14 10:14:02 2012 -0700
@@ -26,7 +26,7 @@
# This file sets common environment variables for all SA scripts
OS=`uname`
-STARTDIR=`dirname $0`
+STARTDIR=`(cd \`dirname $0 \`; pwd)`
ARCH=`uname -m`
if [ "x$SA_JAVA" = "x" ]; then
--- a/hotspot/agent/make/start-debug-server-proc.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/make/start-debug-server-proc.sh Fri Sep 14 10:14:02 2012 -0700
@@ -25,10 +25,11 @@
. `dirname $0`/saenv.sh
-if [ -f $STARTDIR/sa.jar ] ; then
- CP=$STARTDIR/sa.jar
+if [ -f $STARTDIR/../lib/sa-jdi.jar ] ; then
+ CP=$STARTDIR/../lib/sa-jdi.jar
else
CP=$STARTDIR/../build/classes
fi
-$SA_JAVA -classpath $CP ${OPTIONS} -Djava.rmi.server.codebase=file:/$CP -Djava.security.policy=$STARTDIR\/grantAll.policy sun.jvm.hotspot.DebugServer $*
+$STARTDIR/java -classpath $CP ${OPTIONS} -Djava.rmi.server.codebase=file://$CP -Djava.security.policy=${STARTDIR}/grantAll.policy sun.jvm.hotspot.DebugServer $*
+
--- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,11 +55,11 @@
#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
-static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
+void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
(*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
}
-static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
+struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
return (struct ps_prochandle*)(intptr_t)ptr;
}
@@ -280,6 +280,7 @@
return (err == PS_OK)? array : 0;
}
+#if defined(i386) || defined(ia64) || defined(amd64) || defined(sparc) || defined(sparcv9)
JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
(JNIEnv *env, jobject this_obj, jint lwp_id) {
@@ -410,3 +411,4 @@
(*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
return array;
}
+#endif
--- a/hotspot/agent/src/os/linux/libproc.h Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/os/linux/libproc.h Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,15 @@
#ifndef _LIBPROC_H_
#define _LIBPROC_H_
+#include <jni.h>
#include <unistd.h>
#include <stdint.h>
#include "proc_service.h"
+#if defined(arm) || defined(ppc)
+#include "libproc_md.h"
+#endif
+
#if defined(sparc) || defined(sparcv9)
/*
If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64
@@ -139,4 +144,8 @@
// address->nearest symbol lookup. return NULL for no symbol
const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset);
+struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj);
+
+void throw_new_debugger_exception(JNIEnv* env, const char* errMsg);
+
#endif //__LIBPROC_H_
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -549,7 +549,13 @@
machDesc = new MachineDescriptionSPARC32Bit();
}
} else {
- throw new DebuggerException("Linux only supported on x86/ia64/amd64/sparc/sparc64");
+ try {
+ machDesc = (MachineDescription)
+ Class.forName("sun.jvm.hotspot.debugger.MachineDescription" +
+ cpu.toUpperCase()).newInstance();
+ } catch (Exception e) {
+ throw new DebuggerException("Linux not supported on machine type " + cpu);
+ }
}
LinuxDebuggerLocal dbg =
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -737,9 +737,16 @@
machDesc = new MachineDescriptionSPARC32Bit();
}
} else {
- throw new DebuggerException("Linux only supported on x86/ia64/amd64/sparc/sparc64");
+ try {
+ machDesc = (MachineDescription)
+ Class.forName("sun.jvm.hotspot.debugger.MachineDescription" +
+ cpu.toUpperCase()).newInstance();
+ } catch (Exception e) {
+ throw new DebuggerException("unsupported machine type");
+ }
}
+
// Note we do not use a cache for the local debugger in server
// mode; it will be taken care of on the client side (once remote
// debugging is implemented).
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ThreadContext.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ThreadContext.java Fri Sep 14 10:14:02 2012 -0700
@@ -24,6 +24,8 @@
package sun.jvm.hotspot.debugger;
+import sun.jvm.hotspot.debugger.cdbg.*;
+
/** This is a placeholder interface for a thread's context, containing
only integer registers (no floating-point ones). What it contains
is platform-dependent. Not all registers are guaranteed to be
@@ -54,4 +56,6 @@
/** Set the value of the specified register (0..getNumRegisters() -
1) as an Address */
public void setRegisterAsAddress(int index, Address value);
+
+ public CFrame getTopFrame(Debugger dbg);
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/amd64/AMD64ThreadContext.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/amd64/AMD64ThreadContext.java Fri Sep 14 10:14:02 2012 -0700
@@ -25,6 +25,7 @@
package sun.jvm.hotspot.debugger.amd64;
import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
/** Specifies the thread context on amd64 platforms; only a sub-portion
* of the context is guaranteed to be present on all operating
@@ -98,6 +99,10 @@
return data[index];
}
+ public CFrame getTopFrame(Debugger dbg) {
+ return null;
+ }
+
/** This can't be implemented in this class since we would have to
* tie the implementation to, for example, the debugging system */
public abstract void setRegisterAsAddress(int index, Address value);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ia64/IA64ThreadContext.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ia64/IA64ThreadContext.java Fri Sep 14 10:14:02 2012 -0700
@@ -25,6 +25,7 @@
package sun.jvm.hotspot.debugger.ia64;
import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
/** Specifies the thread context on ia64 platform; only a sub-portion
of the context is guaranteed to be present on all operating
@@ -172,6 +173,10 @@
return data[index];
}
+ public CFrame getTopFrame(Debugger dbg) {
+ return null;
+ }
+
/** This can't be implemented in this class since we would have to
tie the implementation to, for example, the debugging system */
public abstract void setRegisterAsAddress(int index, Address value);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -107,7 +107,9 @@
if (pc == null) return null;
return new LinuxSPARCCFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize());
} else {
- throw new DebuggerException(cpu + " is not yet supported");
+ // Runtime exception thrown by LinuxThreadContextFactory if unknown cpu
+ ThreadContext context = (ThreadContext) thread.getContext();
+ return context.getTopFrame(dbg);
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
package sun.jvm.hotspot.debugger.linux;
+import java.lang.reflect.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.linux.amd64.*;
import sun.jvm.hotspot.debugger.linux.ia64.*;
@@ -41,8 +42,16 @@
return new LinuxIA64ThreadContext(dbg);
} else if (cpu.equals("sparc")) {
return new LinuxSPARCThreadContext(dbg);
- } else {
- throw new RuntimeException("cpu " + cpu + " is not yet supported");
+ } else {
+ try {
+ Class tcc = Class.forName("sun.jvm.hotspot.debugger.linux." +
+ cpu.toLowerCase() + ".Linux" + cpu.toUpperCase() +
+ "ThreadContext");
+ Constructor[] ctcc = tcc.getConstructors();
+ return (ThreadContext)ctcc[0].newInstance(dbg);
+ } catch (Exception e) {
+ throw new RuntimeException("cpu " + cpu + " is not yet supported");
+ }
}
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
import java.io.*;
import java.net.*;
import java.util.*;
+import java.lang.reflect.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
import sun.jvm.hotspot.debugger.proc.amd64.*;
@@ -86,7 +87,16 @@
pcRegIndex = AMD64ThreadContext.RIP;
fpRegIndex = AMD64ThreadContext.RBP;
} else {
+ try {
+ Class tfc = Class.forName("sun.jvm.hotspot.debugger.proc." +
+ cpu.toLowerCase() + ".Proc" + cpu.toUpperCase() +
+ "ThreadFactory");
+ Constructor[] ctfc = tfc.getConstructors();
+ threadFactory = (ProcThreadFactory)ctfc[0].newInstance(this);
+ } catch (Exception e) {
throw new RuntimeException("Thread access for CPU architecture " + PlatformInfo.getCPU() + " not yet supported");
+ // Note: pcRegIndex and fpRegIndex do not appear to be referenced
+ }
}
if (useCache) {
// Cache portion of the remote process's address space.
@@ -375,7 +385,11 @@
int pagesize = getPageSize0();
if (pagesize == -1) {
// return the hard coded default value.
- pagesize = (PlatformInfo.getCPU().equals("x86"))? 4096 : 8192;
+ if (PlatformInfo.getCPU().equals("sparc") ||
+ PlatformInfo.getCPU().equals("amd64") )
+ pagesize = 8196;
+ else
+ pagesize = 4096;
}
return pagesize;
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
import java.rmi.*;
import java.util.*;
+import java.lang.reflect.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.debugger.cdbg.*;
@@ -70,7 +71,18 @@
cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize);
unalignedAccessesOkay = true;
} else {
- throw new DebuggerException("Thread access for CPU architecture " + cpu + " not yet supported");
+ try {
+ Class tf = Class.forName("sun.jvm.hotspot.debugger.remote." +
+ cpu.toLowerCase() + ".Remote" + cpu.toUpperCase() +
+ "ThreadFactory");
+ Constructor[] ctf = tf.getConstructors();
+ threadFactory = (RemoteThreadFactory)ctf[0].newInstance(this);
+ } catch (Exception e) {
+ throw new DebuggerException("Thread access for CPU architecture " + cpu + " not yet supported");
+ }
+ cachePageSize = 4096;
+ cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize);
+ unalignedAccessesOkay = false;
}
// Cache portion of the remote process's address space.
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/sparc/SPARCThreadContext.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/sparc/SPARCThreadContext.java Fri Sep 14 10:14:02 2012 -0700
@@ -25,6 +25,7 @@
package sun.jvm.hotspot.debugger.sparc;
import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
/** Currently provides just the minimal information necessary to get
stack traces working. FIXME: currently hardwired for v9 -- will
@@ -124,6 +125,10 @@
return data[index];
}
+ public CFrame getTopFrame(Debugger dbg) {
+ return null;
+ }
+
/** This can't be implemented in this class since we would have to
tie the implementation to, for example, the debugging system */
public abstract void setRegisterAsAddress(int index, Address value);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/x86/X86ThreadContext.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/x86/X86ThreadContext.java Fri Sep 14 10:14:02 2012 -0700
@@ -25,6 +25,7 @@
package sun.jvm.hotspot.debugger.x86;
import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
/** Specifies the thread context on x86 platforms; only a sub-portion
of the context is guaranteed to be present on all operating
@@ -109,6 +110,10 @@
return data[index];
}
+ public CFrame getTopFrame(Debugger dbg) {
+ return null;
+ }
+
/** This can't be implemented in this class since we would have to
tie the implementation to, for example, the debugging system */
public abstract void setRegisterAsAddress(int index, Address value);
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -91,6 +91,16 @@
access = new LinuxAMD64JavaThreadPDAccess();
} else if (cpu.equals("sparc")) {
access = new LinuxSPARCJavaThreadPDAccess();
+ } else {
+ try {
+ access = (JavaThreadPDAccess)
+ Class.forName("sun.jvm.hotspot.runtime.linux_" +
+ cpu.toLowerCase() + ".Linux" + cpu.toUpperCase() +
+ "JavaThreadPDAccess").newInstance();
+ } catch (Exception e) {
+ throw new RuntimeException("OS/CPU combination " + os + "/" + cpu +
+ " not yet supported");
+ }
}
} else if (os.equals("bsd")) {
if (cpu.equals("x86")) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Sep 14 10:14:02 2012 -0700
@@ -92,6 +92,8 @@
private boolean usingServerCompiler;
/** Flag indicating whether UseTLAB is turned on */
private boolean useTLAB;
+ /** Flag indicating whether invokedynamic support is on */
+ private boolean enableInvokeDynamic;
/** alignment constants */
private boolean isLP64;
private int bytesPerLong;
@@ -317,6 +319,7 @@
}
useTLAB = (db.lookupIntConstant("UseTLAB").intValue() != 0);
+ enableInvokeDynamic = (db.lookupIntConstant("EnableInvokeDynamic").intValue() != 0);
if (debugger != null) {
isLP64 = debugger.getMachineDescription().isLP64();
@@ -552,6 +555,10 @@
return useTLAB;
}
+ public boolean getEnableInvokeDynamic() {
+ return enableInvokeDynamic;
+ }
+
public TypeDataBase getTypeDataBase() {
return db;
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Fri Sep 14 10:14:02 2012 -0700
@@ -204,7 +204,13 @@
} else if (cpu.equals("ia64")) {
cpuHelper = new IA64Helper();
} else {
+ try {
+ cpuHelper = (CPUHelper)Class.forName("sun.jvm.hotspot.asm." +
+ cpu.toLowerCase() + "." + cpu.toUpperCase() +
+ "Helper").newInstance();
+ } catch (Exception e) {
throw new RuntimeException("cpu '" + cpu + "' is not yet supported!");
+ }
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/AltPlatformInfo.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.utilities;
+
+public interface AltPlatformInfo {
+ // Additional cpu types can be tested via this interface
+
+ public boolean knownCPU(String cpu);
+}
\ No newline at end of file
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java Fri Sep 14 10:14:02 2012 -0700
@@ -64,6 +64,13 @@
} else if (cpu.equals("ia64") || cpu.equals("amd64") || cpu.equals("x86_64")) {
return cpu;
} else {
+ try {
+ Class pic = Class.forName("sun.jvm.hotspot.utilities.PlatformInfoClosed");
+ AltPlatformInfo api = (AltPlatformInfo)pic.newInstance();
+ if (api.knownCPU(cpu)) {
+ return cpu;
+ }
+ } catch (Exception e) {}
throw new UnsupportedPlatformException("CPU type " + cpu + " not yet supported");
}
}
--- a/hotspot/make/defs.make Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/make/defs.make Fri Sep 14 10:14:02 2012 -0700
@@ -22,6 +22,14 @@
#
#
+ifeq ($(HS_ALT_MAKE),)
+ ifneq ($(OPENJDK),true)
+ HS_ALT_MAKE=$(GAMMADIR)/make/closed
+ else
+ HS_ALT_MAKE=NO_SUCH_PATH
+ endif
+endif
+
# The common definitions for hotspot builds.
# Optionally include SPEC file generated by configure.
@@ -327,3 +335,4 @@
ifndef JAVASE_EMBEDDED
EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jfr.h
endif
+
--- a/hotspot/make/hotspot_version Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/make/hotspot_version Fri Sep 14 10:14:02 2012 -0700
@@ -35,7 +35,7 @@
HS_MAJOR_VER=24
HS_MINOR_VER=0
-HS_BUILD_NUMBER=21
+HS_BUILD_NUMBER=22
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/linux/makefiles/defs.make Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/make/linux/makefiles/defs.make Fri Sep 14 10:14:02 2012 -0700
@@ -295,6 +295,8 @@
ADD_SA_BINARIES/arm =
ADD_SA_BINARIES/zero =
+-include $(HS_ALT_MAKE)/linux/makefiles/defs.make
+
EXPORT_LIST += $(ADD_SA_BINARIES/$(HS_ARCH))
--- a/hotspot/make/linux/makefiles/sa.make Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/make/linux/makefiles/sa.make Fri Sep 14 10:14:02 2012 -0700
@@ -30,10 +30,16 @@
include $(GAMMADIR)/make/linux/makefiles/rules.make
+include $(GAMMADIR)/make/defs.make
+include $(GAMMADIR)/make/altsrc.make
+
AGENT_DIR = $(GAMMADIR)/agent
include $(GAMMADIR)/make/sa.files
+-include $(HS_ALT_MAKE)/linux/makefiles/sa.make
+
+
TOPDIR = $(shell echo `pwd`)
GENERATED = $(TOPDIR)/../generated
@@ -52,17 +58,15 @@
SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties
# if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium, PowerPC, ARM or zero.
+# also, we don't build SA on Itanium or zero.
all:
if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" \
- -a "$(SRCARCH)" != "arm" \
- -a "$(SRCARCH)" != "ppc" \
-a "$(SRCARCH)" != "zero" ] ; then \
$(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \
fi
-$(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
+$(GENERATED)/sa-jdi.jar:: $(AGENT_FILES)
$(QUIETLY) echo "Making $@"
$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
@@ -111,3 +115,5 @@
rm -rf $(SA_CLASSDIR)
rm -rf $(GENERATED)/sa-jdi.jar
rm -rf $(AGENT_FILES_LIST)
+
+-include $(HS_ALT_MAKE)/linux/makefiles/sa-rules.make
--- a/hotspot/make/linux/makefiles/saproc.make Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/make/linux/makefiles/saproc.make Fri Sep 14 10:14:02 2012 -0700
@@ -21,6 +21,8 @@
# questions.
#
#
+include $(GAMMADIR)/make/defs.make
+include $(GAMMADIR)/make/altsrc.make
# Rules to build serviceability agent library, used by vm.make
@@ -48,6 +50,8 @@
$(SASRCDIR)/ps_core.c \
$(SASRCDIR)/LinuxDebuggerLocal.c
+-include $(HS_ALT_MAKE)/linux/makefiles/saproc.make
+
SAMAPFILE = $(SASRCDIR)/mapfile
DEST_SAPROC = $(JDK_LIBDIR)/$(LIBSAPROC)
@@ -60,15 +64,19 @@
endif
# if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium, PPC, ARM or zero.
+# also, we don't build SA on Itanium or zero.
ifneq ($(wildcard $(AGENT_DIR)),)
-ifneq ($(filter-out ia64 arm ppc zero,$(SRCARCH)),)
+ifneq ($(filter-out ia64 zero,$(SRCARCH)),)
BUILDLIBSAPROC = $(LIBSAPROC)
endif
endif
-
+ifneq ($(ALT_SASRCDIR),)
+ALT_SAINCDIR=-I$(ALT_SASRCDIR)
+else
+ALT_SAINCDIR=
+endif
SA_LFLAGS = $(MAPFLAG:FILENAME=$(SAMAPFILE)) $(LDFLAGS_HASH_STYLE)
$(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
@@ -84,6 +92,7 @@
-I$(GENERATED) \
-I$(BOOT_JAVA_HOME)/include \
-I$(BOOT_JAVA_HOME)/include/$(Platform_os_family) \
+ $(ALT_SAINCDIR) \
$(SASRCFILES) \
$(SA_LFLAGS) \
$(SA_DEBUG_CFLAGS) \
--- a/hotspot/make/pic.make Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/make/pic.make Fri Sep 14 10:14:02 2012 -0700
@@ -32,7 +32,7 @@
ifndef LP64
PARTIAL_NONPIC=1
endif
- PIC_ARCH = ppc
+ PIC_ARCH = ppc arm
ifneq ("$(filter $(PIC_ARCH),$(BUILDARCH))","")
PARTIAL_NONPIC=0
endif
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -75,4 +75,43 @@
// GC Ergo Flags
define_pd_global(intx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
+
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
+ \
+ product(intx, UseVIS, 99, \
+ "Highest supported VIS instructions set on Sparc") \
+ \
+ product(bool, UseCBCond, false, \
+ "Use compare and branch instruction on SPARC") \
+ \
+ product(bool, UseBlockZeroing, false, \
+ "Use special cpu instructions for block zeroing") \
+ \
+ product(intx, BlockZeroingLowLimit, 2048, \
+ "Minimum size in bytes when block zeroing will be used") \
+ \
+ product(bool, UseBlockCopy, false, \
+ "Use special cpu instructions for block copy") \
+ \
+ product(intx, BlockCopyLowLimit, 2048, \
+ "Minimum size in bytes when block copy will be used") \
+ \
+ develop(bool, UseV8InstrsOnly, false, \
+ "Use SPARC-V8 Compliant instruction subset") \
+ \
+ product(bool, UseNiagaraInstrs, false, \
+ "Use Niagara-efficient instruction subset") \
+ \
+ develop(bool, UseCASForSwap, false, \
+ "Do not use swap instructions, but only CAS (in a loop) on SPARC")\
+ \
+ product(uintx, ArraycopySrcPrefetchDistance, 0, \
+ "Distance to prefetch source array in arracopy") \
+ \
+ product(uintx, ArraycopyDstPrefetchDistance, 0, \
+ "Distance to prefetch destination array in arracopy") \
+ \
+ develop(intx, V8AtomicOperationUnderLockSpinCount, 50, \
+ "Number of times to spin wait on a v8 atomic operation lock") \
+
#endif // CPU_SPARC_VM_GLOBALS_SPARC_HPP
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -78,4 +78,53 @@
// GC Ergo Flags
define_pd_global(intx, CMSYoungGenPerWorker, 64*M); // default max size of CMS young gen, per GC worker thread
+
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
+ \
+ develop(bool, IEEEPrecision, true, \
+ "Enables IEEE precision (for INTEL only)") \
+ \
+ product(intx, FenceInstruction, 0, \
+ "(Unsafe,Unstable) Experimental") \
+ \
+ product(intx, ReadPrefetchInstr, 0, \
+ "Prefetch instruction to prefetch ahead") \
+ \
+ product(bool, UseStoreImmI16, true, \
+ "Use store immediate 16-bits value instruction on x86") \
+ \
+ product(intx, UseAVX, 99, \
+ "Highest supported AVX instructions set on x86/x64") \
+ \
+ diagnostic(bool, UseIncDec, true, \
+ "Use INC, DEC instructions on x86") \
+ \
+ product(bool, UseNewLongLShift, false, \
+ "Use optimized bitwise shift left") \
+ \
+ product(bool, UseAddressNop, false, \
+ "Use '0F 1F [addr]' NOP instructions on x86 cpus") \
+ \
+ product(bool, UseXmmLoadAndClearUpper, true, \
+ "Load low part of XMM register and clear upper part") \
+ \
+ product(bool, UseXmmRegToRegMoveAll, false, \
+ "Copy all XMM register bits when moving value between registers") \
+ \
+ product(bool, UseXmmI2D, false, \
+ "Use SSE2 CVTDQ2PD instruction to convert Integer to Double") \
+ \
+ product(bool, UseXmmI2F, false, \
+ "Use SSE2 CVTDQ2PS instruction to convert Integer to Float") \
+ \
+ product(bool, UseUnalignedLoadStores, false, \
+ "Use SSE2 MOVDQU instruction for Arraycopy") \
+ \
+ /* assembler */ \
+ product(bool, Use486InstrsOnly, false, \
+ "Use 80486 Compliant instruction subset") \
+ \
+ product(bool, UseCountLeadingZerosInstruction, false, \
+ "Use count leading zeros instruction") \
+
#endif // CPU_X86_VM_GLOBALS_X86_HPP
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -60,4 +60,7 @@
// GC Ergo Flags
define_pd_global(intx, CMSYoungGenPerWorker, 16*M); // default max size of CMS young gen, per GC worker thread
+
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct)
+
#endif // CPU_ZERO_VM_GLOBALS_ZERO_HPP
--- a/hotspot/src/os/bsd/vm/os_bsd.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/os/bsd/vm/os_bsd.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -202,7 +202,7 @@
static void fast_thread_clock_init(void);
#endif
- static bool supports_monotonic_clock() {
+ static inline bool supports_monotonic_clock() {
return _clock_gettime != NULL;
}
--- a/hotspot/src/os/linux/vm/os_linux.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -178,7 +178,7 @@
// fast POSIX clocks support
static void fast_thread_clock_init(void);
- static bool supports_monotonic_clock() {
+ static inline bool supports_monotonic_clock() {
return _clock_gettime != NULL;
}
--- a/hotspot/src/os/posix/launcher/launcher.script Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/os/posix/launcher/launcher.script Fri Sep 14 10:14:02 2012 -0700
@@ -29,7 +29,7 @@
# inside Emacs".
#
# If the first parameter is "-dbx", HotSpot will be launched inside dbx.
-#
+#
# If the first parameter is "-valgrind", HotSpot will be launched
# inside Valgrind (http://valgrind.kde.org) using the Memcheck skin,
# and with memory leak detection enabled. This currently (2005jan19)
@@ -45,19 +45,19 @@
# This is the name of the gdb binary to use
if [ ! "$GDB" ]
-then
+then
GDB=gdb
fi
# This is the name of the gdb binary to use
if [ ! "$DBX" ]
-then
+then
DBX=dbx
fi
# This is the name of the Valgrind binary to use
if [ ! "$VALGRIND" ]
-then
+then
VALGRIND=valgrind
fi
@@ -98,7 +98,7 @@
JDK=
if [ "${ALT_JAVA_HOME}" = "" ]; then
. ${MYDIR}/jdkpath.sh
-else
+else
JDK=${ALT_JAVA_HOME%%/jre};
fi
@@ -114,22 +114,34 @@
# any.
JRE=$JDK/jre
JAVA_HOME=$JDK
+export JAVA_HOME
+
ARCH=@@LIBARCH@@
-
SBP=${MYDIR}:${JRE}/lib/${ARCH}
-# Set up a suitable LD_LIBRARY_PATH
-if [ -z "$LD_LIBRARY_PATH" ]
+# Set up a suitable LD_LIBRARY_PATH or DYLD_LIBRARY_PATH
+OS=`uname -s`
+if [ "${OS}" = "Darwin" ]
then
- LD_LIBRARY_PATH="$SBP"
+ if [ -z "$DYLD_LIBRARY_PATH" ]
+ then
+ DYLD_LIBRARY_PATH="$SBP"
+ else
+ DYLD_LIBRARY_PATH="$SBP:$DYLD_LIBRARY_PATH"
+ fi
+ export DYLD_LIBRARY_PATH
else
- LD_LIBRARY_PATH="$SBP:$LD_LIBRARY_PATH"
+ # not 'Darwin'
+ if [ -z "$LD_LIBRARY_PATH" ]
+ then
+ LD_LIBRARY_PATH="$SBP"
+ else
+ LD_LIBRARY_PATH="$SBP:$LD_LIBRARY_PATH"
+ fi
+ export LD_LIBRARY_PATH
fi
-export LD_LIBRARY_PATH
-export JAVA_HOME
-
JPARMS="$@ $JAVA_ARGS";
# Locate the gamma development launcher
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -1646,15 +1646,15 @@
void GraphBuilder::invoke(Bytecodes::Code code) {
- const bool is_invokedynamic = (code == Bytecodes::_invokedynamic);
-
bool will_link;
- ciMethod* target = stream()->get_method(will_link);
+ ciSignature* declared_signature = NULL;
+ ciMethod* target = stream()->get_method(will_link, &declared_signature);
ciKlass* holder = stream()->get_declared_method_holder();
const Bytecodes::Code bc_raw = stream()->cur_bc_raw();
+ assert(declared_signature != NULL, "cannot be null");
// FIXME bail out for now
- if ((bc_raw == Bytecodes::_invokehandle || is_invokedynamic) && !will_link) {
+ if (Bytecodes::has_optional_appendix(bc_raw) && !will_link) {
BAILOUT("unlinked call site (FIXME needs patching or recompile support)");
}
@@ -1840,7 +1840,7 @@
bool success = false;
if (target->is_method_handle_intrinsic()) {
// method handle invokes
- success = for_method_handle_inline(target);
+ success = try_method_handle_inline(target);
} else {
// static binding => check if callee is ok
success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver);
@@ -1877,7 +1877,7 @@
// inlining not successful => standard invoke
bool is_loaded = target->is_loaded();
- ValueType* result_type = as_ValueType(target->return_type());
+ ValueType* result_type = as_ValueType(declared_signature->return_type());
ValueStack* state_before = copy_state_exhandling();
// The bytecode (code) might change in this method so we are checking this very late.
@@ -3823,7 +3823,7 @@
}
-bool GraphBuilder::for_method_handle_inline(ciMethod* callee) {
+bool GraphBuilder::try_method_handle_inline(ciMethod* callee) {
ValueStack* state_before = state()->copy_for_parsing();
vmIntrinsics::ID iid = callee->intrinsic_id();
switch (iid) {
@@ -3858,7 +3858,7 @@
// If the target is another method handle invoke try recursivly to get
// a better target.
if (target->is_method_handle_intrinsic()) {
- if (for_method_handle_inline(target)) {
+ if (try_method_handle_inline(target)) {
return true;
}
} else {
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -346,7 +346,7 @@
const char* should_not_inline(ciMethod* callee) const;
// JSR 292 support
- bool for_method_handle_inline(ciMethod* callee);
+ bool try_method_handle_inline(ciMethod* callee);
// helpers
void inline_bailout(const char* msg);
--- a/hotspot/src/share/vm/c1/c1_globals.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/c1/c1_globals.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -156,18 +156,12 @@
develop(bool, CanonicalizeNodes, true, \
"Canonicalize graph nodes") \
\
- develop(bool, CanonicalizeExperimental, false, \
- "Canonicalize graph nodes, experimental code") \
- \
develop(bool, PrintCanonicalization, false, \
"Print graph node canonicalization") \
\
develop(bool, UseTableRanges, true, \
"Faster versions of lookup table using ranges") \
\
- develop(bool, UseFastExceptionHandling, true, \
- "Faster handling of exceptions") \
- \
develop_pd(bool, RoundFPResults, \
"Indicates whether rounding is needed for floating point results")\
\
@@ -224,9 +218,6 @@
develop(bool, PinAllInstructions, false, \
"All instructions are pinned") \
\
- develop(bool, ValueStackPinStackAll, true, \
- "Pinning in ValueStack pin everything") \
- \
develop(bool, UseFastNewInstance, true, \
"Use fast inlined instance allocation") \
\
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -236,12 +236,16 @@
ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
ciInstanceKlass* actual_recv = callee_holder;
- // some methods are obviously bindable without any type checks so
- // convert them directly to an invokespecial.
+ // Some methods are obviously bindable without any type checks so
+ // convert them directly to an invokespecial or invokestatic.
if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
switch (code) {
- case Bytecodes::_invokevirtual: code = Bytecodes::_invokespecial; break;
- case Bytecodes::_invokehandle: code = Bytecodes::_invokestatic; break;
+ case Bytecodes::_invokevirtual:
+ code = Bytecodes::_invokespecial;
+ break;
+ case Bytecodes::_invokehandle:
+ code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial;
+ break;
}
}
@@ -826,8 +830,8 @@
break;
case Bytecodes::_getstatic:
case Bytecodes::_getfield:
- { bool will_link;
- ciField* field = s.get_field(will_link);
+ { bool ignored_will_link;
+ ciField* field = s.get_field(ignored_will_link);
BasicType field_type = field->type()->basic_type();
if (s.cur_bc() != Bytecodes::_getstatic) {
set_method_escape(state.apop());
@@ -865,16 +869,21 @@
case Bytecodes::_invokestatic:
case Bytecodes::_invokedynamic:
case Bytecodes::_invokeinterface:
- { bool will_link;
- ciMethod* target = s.get_method(will_link);
- ciKlass* holder = s.get_declared_method_holder();
+ { bool ignored_will_link;
+ ciSignature* declared_signature = NULL;
+ ciMethod* target = s.get_method(ignored_will_link, &declared_signature);
+ ciKlass* holder = s.get_declared_method_holder();
+ assert(declared_signature != NULL, "cannot be null");
// Push appendix argument, if one.
if (s.has_appendix()) {
state.apush(unknown_obj);
}
// Pass in raw bytecode because we need to see invokehandle instructions.
invoke(state, s.cur_bc_raw(), target, holder);
- ciType* return_type = target->return_type();
+ // We are using the return type of the declared signature here because
+ // it might be a more concrete type than the one from the target (for
+ // e.g. invokedynamic and invokehandle).
+ ciType* return_type = declared_signature->return_type();
if (!return_type->is_primitive_type()) {
state.apush(unknown_obj);
} else if (return_type->is_one_word()) {
--- a/hotspot/src/share/vm/ci/ciEnv.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -738,91 +738,81 @@
ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
int index, Bytecodes::Code bc,
ciInstanceKlass* accessor) {
- int holder_index = cpool->klass_ref_index_at(index);
- bool holder_is_accessible;
- ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
- ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
-
- // Get the method's name and signature.
- Symbol* name_sym = cpool->name_ref_at(index);
- Symbol* sig_sym = cpool->signature_ref_at(index);
-
- if (cpool->has_preresolution()
- || (holder == ciEnv::MethodHandle_klass() &&
- MethodHandles::is_signature_polymorphic_name(holder->get_klassOop(), name_sym))) {
- // Short-circuit lookups for JSR 292-related call sites.
- // That is, do not rely only on name-based lookups, because they may fail
- // if the names are not resolvable in the boot class loader (7056328).
- switch (bc) {
- case Bytecodes::_invokevirtual:
- case Bytecodes::_invokeinterface:
- case Bytecodes::_invokespecial:
- case Bytecodes::_invokestatic:
- {
- oop appendix_oop = NULL;
- methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index);
- if (m != NULL) {
- return get_object(m)->as_method();
- }
- }
- break;
- }
- }
+ if (bc == Bytecodes::_invokedynamic) {
+ ConstantPoolCacheEntry* secondary_entry = cpool->cache()->secondary_entry_at(index);
+ const bool is_resolved = !secondary_entry->is_f1_null();
+ // FIXME: code generation could allow for null (unlinked) call site
+ // The call site could be made patchable as follows:
+ // Load the appendix argument from the constant pool.
+ // Test the appendix argument and jump to a known deopt routine if it is null.
+ // Jump through a patchable call site, which is initially a deopt routine.
+ // Patch the call site to the nmethod entry point of the static compiled lambda form.
+ // As with other two-component call sites, both values must be independently verified.
- if (holder_is_accessible) { // Our declared holder is loaded.
- instanceKlass* lookup = declared_holder->get_instanceKlass();
- methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);
- if (m != NULL &&
- (bc == Bytecodes::_invokestatic
- ? instanceKlass::cast(m->method_holder())->is_not_initialized()
- : !instanceKlass::cast(m->method_holder())->is_loaded())) {
- m = NULL;
+ if (is_resolved) {
+ // Get the invoker methodOop and the extra argument from the constant pool.
+ methodOop adapter = secondary_entry->f2_as_vfinal_method();
+ return get_object(adapter)->as_method();
}
- if (m != NULL) {
- // We found the method.
- return get_object(m)->as_method();
- }
- }
-
- // Either the declared holder was not loaded, or the method could
- // not be found. Create a dummy ciMethod to represent the failed
- // lookup.
- ciSymbol* name = get_symbol(name_sym);
- ciSymbol* signature = get_symbol(sig_sym);
- return get_unloaded_method(declared_holder, name, signature, accessor);
-}
-
-// ------------------------------------------------------------------
-// ciEnv::get_fake_invokedynamic_method_impl
-ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
- int index, Bytecodes::Code bc,
- ciInstanceKlass* accessor) {
- // Compare the following logic with InterpreterRuntime::resolve_invokedynamic.
- assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic");
-
- ConstantPoolCacheEntry* secondary_entry = cpool->cache()->secondary_entry_at(index);
- bool is_resolved = !secondary_entry->is_f1_null();
- // FIXME: code generation could allow for null (unlinked) call site
- // The call site could be made patchable as follows:
- // Load the appendix argument from the constant pool.
- // Test the appendix argument and jump to a known deopt routine if it is null.
- // Jump through a patchable call site, which is initially a deopt routine.
- // Patch the call site to the nmethod entry point of the static compiled lambda form.
- // As with other two-component call sites, both values must be independently verified.
-
- // Call site might not be resolved yet.
- // Stop the code path here with an unlinked method.
- if (!is_resolved) {
+ // Fake a method that is equivalent to a declared method.
ciInstanceKlass* holder = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
ciSymbol* name = ciSymbol::invokeBasic_name();
ciSymbol* signature = get_symbol(cpool->signature_ref_at(index));
return get_unloaded_method(holder, name, signature, accessor);
- }
+ } else {
+ const int holder_index = cpool->klass_ref_index_at(index);
+ bool holder_is_accessible;
+ ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
+ ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
+
+ // Get the method's name and signature.
+ Symbol* name_sym = cpool->name_ref_at(index);
+ Symbol* sig_sym = cpool->signature_ref_at(index);
- // Get the invoker methodOop and the extra argument from the constant pool.
- methodOop adapter = secondary_entry->f2_as_vfinal_method();
- return get_object(adapter)->as_method();
+ if (cpool->has_preresolution()
+ || (holder == ciEnv::MethodHandle_klass() &&
+ MethodHandles::is_signature_polymorphic_name(holder->get_klassOop(), name_sym))) {
+ // Short-circuit lookups for JSR 292-related call sites.
+ // That is, do not rely only on name-based lookups, because they may fail
+ // if the names are not resolvable in the boot class loader (7056328).
+ switch (bc) {
+ case Bytecodes::_invokevirtual:
+ case Bytecodes::_invokeinterface:
+ case Bytecodes::_invokespecial:
+ case Bytecodes::_invokestatic:
+ {
+ methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index);
+ if (m != NULL) {
+ return get_object(m)->as_method();
+ }
+ }
+ break;
+ }
+ }
+
+ if (holder_is_accessible) { // Our declared holder is loaded.
+ instanceKlass* lookup = declared_holder->get_instanceKlass();
+ methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);
+ if (m != NULL &&
+ (bc == Bytecodes::_invokestatic
+ ? instanceKlass::cast(m->method_holder())->is_not_initialized()
+ : !instanceKlass::cast(m->method_holder())->is_loaded())) {
+ m = NULL;
+ }
+ if (m != NULL) {
+ // We found the method.
+ return get_object(m)->as_method();
+ }
+ }
+
+ // Either the declared holder was not loaded, or the method could
+ // not be found. Create a dummy ciMethod to represent the failed
+ // lookup.
+ ciSymbol* name = get_symbol(name_sym);
+ ciSymbol* signature = get_symbol(sig_sym);
+ return get_unloaded_method(declared_holder, name, signature, accessor);
+ }
}
@@ -853,11 +843,7 @@
ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool,
int index, Bytecodes::Code bc,
ciInstanceKlass* accessor) {
- if (bc == Bytecodes::_invokedynamic) {
- GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc, accessor);)
- } else {
- GUARDED_VM_ENTRY(return get_method_by_index_impl( cpool, index, bc, accessor);)
- }
+ GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);)
}
--- a/hotspot/src/share/vm/ci/ciEnv.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -152,9 +152,6 @@
ciMethod* get_method_by_index_impl(constantPoolHandle cpool,
int method_index, Bytecodes::Code bc,
ciInstanceKlass* loading_klass);
- ciMethod* get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
- int index, Bytecodes::Code bc,
- ciInstanceKlass* accessor);
// Helper methods
bool check_klass_accessibility(ciKlass* accessing_klass,
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -1215,9 +1215,10 @@
holder()->print_name_on(st);
st->print(" signature=");
signature()->as_symbol()->print_symbol_on(st);
- st->print(" arg_size=%d", arg_size());
if (is_loaded()) {
- st->print(" loaded=true flags=");
+ st->print(" loaded=true");
+ st->print(" arg_size=%d", arg_size());
+ st->print(" flags=");
flags().print_member_flags(st);
} else {
st->print(" loaded=false");
--- a/hotspot/src/share/vm/ci/ciStreams.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/ci/ciStreams.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -355,11 +355,23 @@
// ciBytecodeStream::get_method
//
// If this is a method invocation bytecode, get the invoked method.
-ciMethod* ciBytecodeStream::get_method(bool& will_link) {
+// Additionally return the declared signature to get more concrete
+// type information if required (Cf. invokedynamic and invokehandle).
+ciMethod* ciBytecodeStream::get_method(bool& will_link, ciSignature* *declared_signature_result) {
VM_ENTRY_MARK;
+ ciEnv* env = CURRENT_ENV;
constantPoolHandle cpool(_method->get_methodOop()->constants());
- ciMethod* m = CURRENT_ENV->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
+ ciMethod* m = env->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
will_link = m->is_loaded();
+ // Get declared method signature and return it.
+ if (has_optional_appendix()) {
+ const int sig_index = get_method_signature_index();
+ Symbol* sig_sym = cpool->symbol_at(sig_index);
+ ciKlass* pool_holder = env->get_object(cpool->pool_holder())->as_klass();
+ (*declared_signature_result) = new (env->arena()) ciSignature(pool_holder, cpool, env->get_symbol(sig_sym));
+ } else {
+ (*declared_signature_result) = m->signature();
+ }
return m;
}
@@ -419,35 +431,18 @@
}
// ------------------------------------------------------------------
-// ciBytecodeStream::get_declared_method_signature
-//
-// Get the declared signature of the currently referenced method.
-//
-// This is always the same as the signature of the resolved method
-// itself, except for _invokehandle and _invokedynamic calls.
-//
-ciSignature* ciBytecodeStream::get_declared_method_signature() {
- int sig_index = get_method_signature_index();
- VM_ENTRY_MARK;
- ciEnv* env = CURRENT_ENV;
- constantPoolHandle cpool(_method->get_methodOop()->constants());
- Symbol* sig_sym = cpool->symbol_at(sig_index);
- ciKlass* pool_holder = env->get_object(cpool->pool_holder())->as_klass();
- return new (env->arena()) ciSignature(pool_holder, cpool, env->get_symbol(sig_sym));
-}
-
-// ------------------------------------------------------------------
// ciBytecodeStream::get_method_signature_index
//
// Get the constant pool index of the signature of the method
// referenced by the current bytecode. Used for generating
// deoptimization information.
int ciBytecodeStream::get_method_signature_index() {
- VM_ENTRY_MARK;
- constantPoolOop cpool = _holder->get_instanceKlass()->constants();
- int method_index = get_method_index();
- int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
- return cpool->signature_ref_index_at(name_and_type_index);
+ GUARDED_VM_ENTRY(
+ constantPoolOop cpool = _holder->get_instanceKlass()->constants();
+ const int method_index = get_method_index();
+ const int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
+ return cpool->signature_ref_index_at(name_and_type_index);
+ )
}
// ------------------------------------------------------------------
--- a/hotspot/src/share/vm/ci/ciStreams.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/ci/ciStreams.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -151,6 +151,8 @@
// Does this instruction contain an index which refes into the CP cache?
bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); }
+ bool has_optional_appendix() { return Bytecodes::has_optional_appendix(cur_bc_raw()); }
+
int get_index_u1() const {
return bytecode().get_index_u1(cur_bc_raw());
}
@@ -257,13 +259,11 @@
int get_field_holder_index();
int get_field_signature_index();
- // If this is a method invocation bytecode, get the invoked method.
- ciMethod* get_method(bool& will_link);
+ ciMethod* get_method(bool& will_link, ciSignature* *declared_signature_result);
bool has_appendix();
ciObject* get_appendix();
ciKlass* get_declared_method_holder();
int get_method_holder_index();
- ciSignature* get_declared_method_signature();
int get_method_signature_index();
ciCPCache* get_cpcache() const;
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -643,9 +643,11 @@
// ------------------------------------------------------------------
// ciTypeFlow::StateVector::do_invoke
void ciTypeFlow::StateVector::do_invoke(ciBytecodeStream* str,
- bool has_receiver_foo) {
+ bool has_receiver) {
bool will_link;
- ciMethod* callee = str->get_method(will_link);
+ ciSignature* declared_signature = NULL;
+ ciMethod* callee = str->get_method(will_link, &declared_signature);
+ assert(declared_signature != NULL, "cannot be null");
if (!will_link) {
// We weren't able to find the method.
if (str->cur_bc() == Bytecodes::_invokedynamic) {
@@ -658,22 +660,12 @@
trap(str, unloaded_holder, str->get_method_holder_index());
}
} else {
- // TODO Use Bytecode_invoke after metadata changes.
- //Bytecode_invoke inv(str->method(), str->cur_bci());
- //const bool has_receiver = callee->is_loaded() ? !callee->is_static() : inv.has_receiver();
- Bytecode inv(str);
- Bytecodes::Code code = inv.invoke_code();
- const bool has_receiver = callee->is_loaded() ? !callee->is_static() : code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic;
-
- ciSignature* signature = callee->signature();
- ciSignatureStream sigstr(signature);
- // Push appendix argument, if one.
- if (str->has_appendix()) {
- ciObject* appendix = str->get_appendix();
- push_object(appendix->klass());
- }
- int arg_size = signature->size();
- int stack_base = stack_size() - arg_size;
+ // We are using the declared signature here because it might be
+ // different from the callee signature (Cf. invokedynamic and
+ // invokehandle).
+ ciSignatureStream sigstr(declared_signature);
+ const int arg_size = declared_signature->size();
+ const int stack_base = stack_size() - arg_size;
int i = 0;
for( ; !sigstr.at_return_type(); sigstr.next()) {
ciType* type = sigstr.type();
@@ -689,7 +681,6 @@
for (int j = 0; j < arg_size; j++) {
pop();
}
- assert(!callee->is_loaded() || has_receiver == !callee->is_static(), "mismatch");
if (has_receiver) {
// Check this?
pop_object();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -1246,6 +1246,31 @@
heap_region_iterate(&cl);
}
+double G1CollectedHeap::verify(bool guard, const char* msg) {
+ double verify_time_ms = 0.0;
+
+ if (guard && total_collections() >= VerifyGCStartAt) {
+ double verify_start = os::elapsedTime();
+ HandleMark hm; // Discard invalid handles created during verification
+ gclog_or_tty->print(msg);
+ prepare_for_verify();
+ Universe::verify(false /* silent */, VerifyOption_G1UsePrevMarking);
+ verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
+ }
+
+ return verify_time_ms;
+}
+
+void G1CollectedHeap::verify_before_gc() {
+ double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:");
+ g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
+}
+
+void G1CollectedHeap::verify_after_gc() {
+ double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:");
+ g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
+}
+
bool G1CollectedHeap::do_collection(bool explicit_gc,
bool clear_all_soft_refs,
size_t word_size) {
@@ -1304,14 +1329,8 @@
size_t g1h_prev_used = used();
assert(used() == recalculate_used(), "Should be equal");
- if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) {
- HandleMark hm; // Discard invalid handles created during verification
- gclog_or_tty->print(" VerifyBeforeGC:");
- prepare_for_verify();
- Universe::verify(/* silent */ false,
- /* option */ VerifyOption_G1UsePrevMarking);
-
- }
+ verify_before_gc();
+
pre_full_gc_dump();
COMPILER2_PRESENT(DerivedPointerTable::clear());
@@ -1378,14 +1397,7 @@
MemoryService::track_memory_usage();
- if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
- HandleMark hm; // Discard invalid handles created during verification
- gclog_or_tty->print(" VerifyAfterGC:");
- prepare_for_verify();
- Universe::verify(/* silent */ false,
- /* option */ VerifyOption_G1UsePrevMarking);
-
- }
+ verify_after_gc();
assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
ref_processor_stw()->verify_no_references_recorded();
@@ -1933,6 +1945,9 @@
clear_cset_start_regions();
+ // Initialize the G1EvacuationFailureALot counters and flags.
+ NOT_PRODUCT(reset_evacuation_should_fail();)
+
guarantee(_task_queues != NULL, "task_queues allocation failure.");
#ifdef SPARC
// Issue a stern warning, but allow use for experimentation and debugging.
@@ -2327,8 +2342,7 @@
while (dcqs.apply_closure_to_completed_buffer(cl, worker_i, 0, true)) {
n_completed_buffers++;
}
- g1_policy()->phase_times()->record_update_rs_processed_buffers(worker_i,
- (double) n_completed_buffers);
+ g1_policy()->phase_times()->record_update_rs_processed_buffers(worker_i, n_completed_buffers);
dcqs.clear_n_completed_buffers();
assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!");
}
@@ -3735,8 +3749,9 @@
int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
workers()->active_workers() : 1);
- g1_policy()->phase_times()->note_gc_start(os::elapsedTime(), active_workers,
- g1_policy()->gcs_are_young(), g1_policy()->during_initial_mark_pause(), gc_cause());
+ double pause_start_sec = os::elapsedTime();
+ g1_policy()->phase_times()->note_gc_start(active_workers);
+ bool initial_mark_gc = g1_policy()->during_initial_mark_pause();
TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
@@ -3765,13 +3780,7 @@
increment_total_collections(false /* full gc */);
increment_gc_time_stamp();
- if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) {
- HandleMark hm; // Discard invalid handles created during verification
- gclog_or_tty->print(" VerifyBeforeGC:");
- prepare_for_verify();
- Universe::verify(/* silent */ false,
- /* option */ VerifyOption_G1UsePrevMarking);
- }
+ verify_before_gc();
COMPILER2_PRESENT(DerivedPointerTable::clear());
@@ -3984,10 +3993,6 @@
true /* verify_fingers */);
_cm->note_end_of_gc();
- // Collect thread local data to allow the ergonomics to use
- // the collected information
- g1_policy()->phase_times()->collapse_par_times();
-
// This timing is only used by the ergonomics to handle our pause target.
// It is unclear why this should not include the full pause. We will
// investigate this in CR 7178365.
@@ -4020,13 +4025,7 @@
// scanning cards (see CR 7039627).
increment_gc_time_stamp();
- if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
- HandleMark hm; // Discard invalid handles created during verification
- gclog_or_tty->print(" VerifyAfterGC:");
- prepare_for_verify();
- Universe::verify(/* silent */ false,
- /* option */ VerifyOption_G1UsePrevMarking);
- }
+ verify_after_gc();
assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
ref_processor_stw()->verify_no_references_recorded();
@@ -4050,10 +4049,35 @@
gc_epilogue(false);
- g1_policy()->phase_times()->note_gc_end(os::elapsedTime());
-
- // We have to do this after we decide whether to expand the heap or not.
+ if (G1Log::fine()) {
+ if (PrintGCTimeStamps) {
+ gclog_or_tty->stamp();
+ gclog_or_tty->print(": ");
+ }
+
+ GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause())
+ .append(g1_policy()->gcs_are_young() ? " (young)" : " (mixed)")
+ .append(initial_mark_gc ? " (initial-mark)" : "");
+
+ double pause_time_sec = os::elapsedTime() - pause_start_sec;
+
+ if (G1Log::finer()) {
+ if (evacuation_failed()) {
+ gc_cause_str.append(" (to-space exhausted)");
+ }
+ gclog_or_tty->print_cr("[%s, %3.7f secs]", (const char*)gc_cause_str, pause_time_sec);
+ g1_policy()->phase_times()->note_gc_end();
+ g1_policy()->phase_times()->print(pause_time_sec);
+ g1_policy()->print_detailed_heap_transition();
+ } else {
+ if (evacuation_failed()) {
+ gc_cause_str.append("--");
+ }
+ gclog_or_tty->print("[%s", (const char*)gc_cause_str);
g1_policy()->print_heap_transition();
+ gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec);
+ }
+ }
}
// It is not yet to safe to tell the concurrent mark to
@@ -4543,7 +4567,15 @@
GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
word_sz);
HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz);
- oop obj = oop(obj_ptr);
+#ifndef PRODUCT
+ // Should this evacuation fail?
+ if (_g1->evacuation_should_fail()) {
+ if (obj_ptr != NULL) {
+ _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz);
+ obj_ptr = NULL;
+ }
+ }
+#endif // !PRODUCT
if (obj_ptr == NULL) {
// This will either forward-to-self, or detect that someone else has
@@ -4552,6 +4584,8 @@
return _g1->handle_evacuation_failure_par(cl, old);
}
+ oop obj = oop(obj_ptr);
+
// We're going to allocate linearly, so might as well prefetch ahead.
Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes);
@@ -4863,7 +4897,7 @@
evac.do_void();
double elapsed_ms = (os::elapsedTime()-start)*1000.0;
double term_ms = pss.term_time()*1000.0;
- _g1h->g1_policy()->phase_times()->record_obj_copy_time(worker_id, elapsed_ms-term_ms);
+ _g1h->g1_policy()->phase_times()->add_obj_copy_time(worker_id, elapsed_ms-term_ms);
_g1h->g1_policy()->phase_times()->record_termination(worker_id, term_ms, pss.term_attempts());
}
_g1h->g1_policy()->record_thread_age_table(pss.age_table());
@@ -4991,27 +5025,28 @@
buf_scan_non_heap_roots.done();
buf_scan_perm.done();
- double ext_roots_end = os::elapsedTime();
-
- g1_policy()->phase_times()->reset_obj_copy_time(worker_i);
double obj_copy_time_sec = buf_scan_perm.closure_app_seconds() +
buf_scan_non_heap_roots.closure_app_seconds();
g1_policy()->phase_times()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
double ext_root_time_ms =
- ((ext_roots_end - ext_roots_start) - obj_copy_time_sec) * 1000.0;
+ ((os::elapsedTime() - ext_roots_start) - obj_copy_time_sec) * 1000.0;
g1_policy()->phase_times()->record_ext_root_scan_time(worker_i, ext_root_time_ms);
// During conc marking we have to filter the per-thread SATB buffers
// to make sure we remove any oops into the CSet (which will show up
// as implicitly live).
+ double satb_filtering_ms = 0.0;
if (!_process_strong_tasks->is_task_claimed(G1H_PS_filter_satb_buffers)) {
if (mark_in_progress()) {
+ double satb_filter_start = os::elapsedTime();
+
JavaThread::satb_mark_queue_set().filter_thread_buffers();
+
+ satb_filtering_ms = (os::elapsedTime() - satb_filter_start) * 1000.0;
}
}
- double satb_filtering_ms = (os::elapsedTime() - ext_roots_end) * 1000.0;
g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms);
// Now scan the complement of the collection set.
@@ -5556,6 +5591,9 @@
_expand_heap_after_alloc_failure = true;
set_evacuation_failed(false);
+ // Should G1EvacuationFailureALot be in effect for this GC?
+ NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
+
g1_rem_set()->prepare_for_oops_into_collection_set_do();
concurrent_g1_refine()->set_use_cache(false);
concurrent_g1_refine()->clear_hot_cache_claimed_index();
@@ -5647,11 +5685,11 @@
if (evacuation_failed()) {
remove_self_forwarding_pointers();
- if (G1Log::finer()) {
- gclog_or_tty->print(" (to-space exhausted)");
- } else if (G1Log::fine()) {
- gclog_or_tty->print("--");
- }
+
+ // Reset the G1EvacuationFailureALot counters and flags
+ // Note: the values are reset only when an actual
+ // evacuation failure occurs.
+ NOT_PRODUCT(reset_evacuation_should_fail();)
}
// Enqueue any remaining references remaining on the STW
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -405,6 +405,10 @@
// heap after a compaction.
void print_hrs_post_compaction();
+ double verify(bool guard, const char* msg);
+ void verify_before_gc();
+ void verify_after_gc();
+
// These are macros so that, if the assert fires, we get the correct
// line number, file, etc.
@@ -911,6 +915,39 @@
oop handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, oop obj);
void handle_evacuation_failure_common(oop obj, markOop m);
+#ifndef PRODUCT
+ // Support for forcing evacuation failures. Analogous to
+ // PromotionFailureALot for the other collectors.
+
+ // Records whether G1EvacuationFailureALot should be in effect
+ // for the current GC
+ bool _evacuation_failure_alot_for_current_gc;
+
+ // Used to record the GC number for interval checking when
+ // determining whether G1EvaucationFailureALot is in effect
+ // for the current GC.
+ size_t _evacuation_failure_alot_gc_number;
+
+ // Count of the number of evacuations between failures.
+ volatile size_t _evacuation_failure_alot_count;
+
+ // Set whether G1EvacuationFailureALot should be in effect
+ // for the current GC (based upon the type of GC and which
+ // command line flags are set);
+ inline bool evacuation_failure_alot_for_gc_type(bool gcs_are_young,
+ bool during_initial_mark,
+ bool during_marking);
+
+ inline void set_evacuation_failure_alot_for_current_gc();
+
+ // Return true if it's time to cause an evacuation failure.
+ inline bool evacuation_should_fail();
+
+ // Reset the G1EvacuationFailureALot counters. Should be called at
+ // the end of an evacuation pause in which an evacuation failure ocurred.
+ inline void reset_evacuation_should_fail();
+#endif // !PRODUCT
+
// ("Weak") Reference processing support.
//
// G1 has 2 instances of the referece processor class. One
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -138,7 +138,7 @@
return _task_queues->queue(i);
}
-inline bool G1CollectedHeap::isMarkedPrev(oop obj) const {
+inline bool G1CollectedHeap::isMarkedPrev(oop obj) const {
return _cm->prevMarkBitMap()->isMarked((HeapWord *)obj);
}
@@ -146,4 +146,77 @@
return _cm->nextMarkBitMap()->isMarked((HeapWord *)obj);
}
+#ifndef PRODUCT
+// Support for G1EvacuationFailureALot
+
+inline bool
+G1CollectedHeap::evacuation_failure_alot_for_gc_type(bool gcs_are_young,
+ bool during_initial_mark,
+ bool during_marking) {
+ bool res = false;
+ if (during_marking) {
+ res |= G1EvacuationFailureALotDuringConcMark;
+ }
+ if (during_initial_mark) {
+ res |= G1EvacuationFailureALotDuringInitialMark;
+ }
+ if (gcs_are_young) {
+ res |= G1EvacuationFailureALotDuringYoungGC;
+ } else {
+ // GCs are mixed
+ res |= G1EvacuationFailureALotDuringMixedGC;
+ }
+ return res;
+}
+
+inline void
+G1CollectedHeap::set_evacuation_failure_alot_for_current_gc() {
+ if (G1EvacuationFailureALot) {
+ // Note we can't assert that _evacuation_failure_alot_for_current_gc
+ // is clear here. It may have been set during a previous GC but that GC
+ // did not copy enough objects (i.e. G1EvacuationFailureALotCount) to
+ // trigger an evacuation failure and clear the flags and and counts.
+
+ // Check if we have gone over the interval.
+ const size_t gc_num = total_collections();
+ const size_t elapsed_gcs = gc_num - _evacuation_failure_alot_gc_number;
+
+ _evacuation_failure_alot_for_current_gc = (elapsed_gcs >= G1EvacuationFailureALotInterval);
+
+ // Now check if G1EvacuationFailureALot is enabled for the current GC type.
+ const bool gcs_are_young = g1_policy()->gcs_are_young();
+ const bool during_im = g1_policy()->during_initial_mark_pause();
+ const bool during_marking = mark_in_progress();
+
+ _evacuation_failure_alot_for_current_gc &=
+ evacuation_failure_alot_for_gc_type(gcs_are_young,
+ during_im,
+ during_marking);
+ }
+}
+
+inline bool
+G1CollectedHeap::evacuation_should_fail() {
+ if (!G1EvacuationFailureALot || !_evacuation_failure_alot_for_current_gc) {
+ return false;
+ }
+ // G1EvacuationFailureALot is in effect for current GC
+ // Access to _evacuation_failure_alot_count is not atomic;
+ // the value does not have to be exact.
+ if (++_evacuation_failure_alot_count < G1EvacuationFailureALotCount) {
+ return false;
+ }
+ _evacuation_failure_alot_count = 0;
+ return true;
+}
+
+inline void G1CollectedHeap::reset_evacuation_should_fail() {
+ if (G1EvacuationFailureALot) {
+ _evacuation_failure_alot_gc_number = total_collections();
+ _evacuation_failure_alot_count = 0;
+ _evacuation_failure_alot_for_current_gc = false;
+ }
+}
+#endif // #ifndef PRODUCT
+
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_INLINE_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -795,7 +795,7 @@
_trace_gen0_time_data.record_start_collection(s_w_t_ms);
_stop_world_start = 0.0;
- phase_times()->_cur_collection_start_sec = start_time_sec;
+ phase_times()->record_cur_collection_start_sec(start_time_sec);
_cur_collection_pause_used_at_start_bytes = start_used;
_cur_collection_pause_used_regions_at_start = _g1->used_regions();
_pending_cards = _g1->pending_card_num();
@@ -947,7 +947,7 @@
_trace_gen0_time_data.record_end_collection(pause_time_ms, phase_times());
// this is where we update the allocation rate of the application
double app_time_ms =
- (phase_times()->_cur_collection_start_sec * 1000.0 - _prev_collection_pause_end_ms);
+ (phase_times()->cur_collection_start_sec() * 1000.0 - _prev_collection_pause_end_ms);
if (app_time_ms < MIN_TIMER_GRANULARITY) {
// This usually happens due to the timer not having the required
// granularity. Some Linuxes are the usual culprits.
@@ -1035,7 +1035,7 @@
if (update_stats) {
double cost_per_card_ms = 0.0;
if (_pending_cards > 0) {
- cost_per_card_ms = phase_times()->_update_rs_time / (double) _pending_cards;
+ cost_per_card_ms = phase_times()->average_last_update_rs_time() / (double) _pending_cards;
_cost_per_card_ms_seq->add(cost_per_card_ms);
}
@@ -1043,7 +1043,7 @@
double cost_per_entry_ms = 0.0;
if (cards_scanned > 10) {
- cost_per_entry_ms = phase_times()->_scan_rs_time / (double) cards_scanned;
+ cost_per_entry_ms = phase_times()->average_last_scan_rs_time() / (double) cards_scanned;
if (_last_gc_was_young) {
_cost_per_entry_ms_seq->add(cost_per_entry_ms);
} else {
@@ -1083,7 +1083,7 @@
size_t copied_bytes = surviving_bytes;
double cost_per_byte_ms = 0.0;
if (copied_bytes > 0) {
- cost_per_byte_ms = phase_times()->_obj_copy_time / (double) copied_bytes;
+ cost_per_byte_ms = phase_times()->average_last_obj_copy_time() / (double) copied_bytes;
if (_in_marking_window) {
_cost_per_byte_ms_during_cm_seq->add(cost_per_byte_ms);
} else {
@@ -1092,21 +1092,22 @@
}
double all_other_time_ms = pause_time_ms -
- (phase_times()->_update_rs_time + phase_times()->_scan_rs_time + phase_times()->_obj_copy_time + phase_times()->_termination_time);
+ (phase_times()->average_last_update_rs_time() + phase_times()->average_last_scan_rs_time()
+ + phase_times()->average_last_obj_copy_time() + phase_times()->average_last_termination_time());
double young_other_time_ms = 0.0;
if (young_cset_region_length() > 0) {
young_other_time_ms =
- phase_times()->_recorded_young_cset_choice_time_ms +
- phase_times()->_recorded_young_free_cset_time_ms;
+ phase_times()->young_cset_choice_time_ms() +
+ phase_times()->young_free_cset_time_ms();
_young_other_cost_per_region_ms_seq->add(young_other_time_ms /
(double) young_cset_region_length());
}
double non_young_other_time_ms = 0.0;
if (old_cset_region_length() > 0) {
non_young_other_time_ms =
- phase_times()->_recorded_non_young_cset_choice_time_ms +
- phase_times()->_recorded_non_young_free_cset_time_ms;
+ phase_times()->non_young_cset_choice_time_ms() +
+ phase_times()->non_young_free_cset_time_ms();
_non_young_other_cost_per_region_ms_seq->add(non_young_other_time_ms /
(double) old_cset_region_length());
@@ -1133,7 +1134,8 @@
// Note that _mmu_tracker->max_gc_time() returns the time in seconds.
double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
- adjust_concurrent_refinement(phase_times()->_update_rs_time, phase_times()->_update_rs_processed_buffers, update_rs_time_goal_ms);
+ adjust_concurrent_refinement(phase_times()->average_last_update_rs_time(),
+ phase_times()->sum_last_update_rs_processed_buffers(), update_rs_time_goal_ms);
_collectionSetChooser->verify();
}
@@ -1144,7 +1146,11 @@
proper_unit_for_byte_size((bytes))
void G1CollectorPolicy::print_heap_transition() {
- if (G1Log::finer()) {
+ _g1->print_size_transition(gclog_or_tty,
+ _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity());
+}
+
+void G1CollectorPolicy::print_detailed_heap_transition() {
YoungList* young_list = _g1->young_list();
size_t eden_bytes = young_list->eden_used_bytes();
size_t survivor_bytes = young_list->survivor_used_bytes();
@@ -1171,11 +1177,6 @@
EXT_SIZE_PARAMS(capacity));
_prev_eden_capacity = eden_capacity;
- } else if (G1Log::fine()) {
- _g1->print_size_transition(gclog_or_tty,
- _cur_collection_pause_used_at_start_bytes,
- _g1->used(), _g1->capacity());
- }
}
void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
@@ -1900,8 +1901,7 @@
set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths);
double young_end_time_sec = os::elapsedTime();
- phase_times()->_recorded_young_cset_choice_time_ms =
- (young_end_time_sec - young_start_time_sec) * 1000.0;
+ phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
// Set the start of the non-young choice time.
double non_young_start_time_sec = young_end_time_sec;
@@ -2015,8 +2015,7 @@
predicted_pause_time_ms, target_pause_time_ms);
double non_young_end_time_sec = os::elapsedTime();
- phase_times()->_recorded_non_young_cset_choice_time_ms =
- (non_young_end_time_sec - non_young_start_time_sec) * 1000.0;
+ phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
}
void TraceGen0TimeData::record_start_collection(double time_to_stop_the_world_ms) {
@@ -2035,25 +2034,25 @@
if(TraceGen0Time) {
_total.add(pause_time_ms);
_other.add(pause_time_ms - phase_times->accounted_time_ms());
- _root_region_scan_wait.add(phase_times->_root_region_scan_wait_time_ms);
- _parallel.add(phase_times->_cur_collection_par_time_ms);
- _ext_root_scan.add(phase_times->_ext_root_scan_time);
- _satb_filtering.add(phase_times->_satb_filtering_time);
- _update_rs.add(phase_times->_update_rs_time);
- _scan_rs.add(phase_times->_scan_rs_time);
- _obj_copy.add(phase_times->_obj_copy_time);
- _termination.add(phase_times->_termination_time);
+ _root_region_scan_wait.add(phase_times->root_region_scan_wait_time_ms());
+ _parallel.add(phase_times->cur_collection_par_time_ms());
+ _ext_root_scan.add(phase_times->average_last_ext_root_scan_time());
+ _satb_filtering.add(phase_times->average_last_satb_filtering_times_ms());
+ _update_rs.add(phase_times->average_last_update_rs_time());
+ _scan_rs.add(phase_times->average_last_scan_rs_time());
+ _obj_copy.add(phase_times->average_last_obj_copy_time());
+ _termination.add(phase_times->average_last_termination_time());
- double parallel_known_time = phase_times->_ext_root_scan_time +
- phase_times->_satb_filtering_time +
- phase_times->_update_rs_time +
- phase_times->_scan_rs_time +
- phase_times->_obj_copy_time +
- + phase_times->_termination_time;
+ double parallel_known_time = phase_times->average_last_ext_root_scan_time() +
+ phase_times->average_last_satb_filtering_times_ms() +
+ phase_times->average_last_update_rs_time() +
+ phase_times->average_last_scan_rs_time() +
+ phase_times->average_last_obj_copy_time() +
+ + phase_times->average_last_termination_time();
- double parallel_other_time = phase_times->_cur_collection_par_time_ms - parallel_known_time;
+ double parallel_other_time = phase_times->cur_collection_par_time_ms() - parallel_known_time;
_parallel_other.add(parallel_other_time);
- _clear_ct.add(phase_times->_cur_clear_ct_time_ms);
+ _clear_ct.add(phase_times->cur_clear_ct_time_ms());
}
}
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -683,6 +683,7 @@
void record_collection_pause_end(double pause_time);
void print_heap_transition();
+ void print_detailed_heap_transition();
// Record the fact that a full collection occurred.
void record_full_collection_start();
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -79,119 +79,145 @@
}
};
+template <class T>
+void WorkerDataArray<T>::print(int level, const char* title) {
+ if (_length == 1) {
+ // No need for min, max, average and sum for only one worker
+ LineBuffer buf(level);
+ buf.append("[%s: ", title);
+ buf.append(_print_format, _data[0]);
+ buf.append_and_print_cr("]");
+ return;
+ }
+
+ T min = _data[0];
+ T max = _data[0];
+ T sum = 0;
+
+ LineBuffer buf(level);
+ buf.append("[%s:", title);
+ for (uint i = 0; i < _length; ++i) {
+ T val = _data[i];
+ min = MIN2(val, min);
+ max = MAX2(val, max);
+ sum += val;
+ if (G1Log::finest()) {
+ buf.append(" ");
+ buf.append(_print_format, val);
+ }
+ }
+
+ if (G1Log::finest()) {
+ buf.append_and_print_cr("");
+ }
+
+ double avg = (double)sum / (double)_length;
+ buf.append(" Min: ");
+ buf.append(_print_format, min);
+ buf.append(", Avg: ");
+ buf.append("%.1lf", avg); // Always print average as a double
+ buf.append(", Max: ");
+ buf.append(_print_format, max);
+ buf.append(", Diff: ");
+ buf.append(_print_format, max - min);
+ if (_print_sum) {
+ // for things like the start and end times the sum is not
+ // that relevant
+ buf.append(", Sum: ");
+ buf.append(_print_format, sum);
+ }
+ buf.append_and_print_cr("]");
+}
+
+#ifdef ASSERT
+
+template <class T>
+void WorkerDataArray<T>::reset() {
+ for (uint i = 0; i < _length; i++) {
+ _data[i] = (T)-1;
+ }
+}
+
+template <class T>
+void WorkerDataArray<T>::verify() {
+ for (uint i = 0; i < _length; i++) {
+ assert(_data[i] >= (T)0, err_msg("Invalid data for worker %d", i));
+ }
+}
+
+#endif
+
G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
_max_gc_threads(max_gc_threads),
_min_clear_cc_time_ms(-1.0),
_max_clear_cc_time_ms(-1.0),
_cur_clear_cc_time_ms(0.0),
_cum_clear_cc_time_ms(0.0),
- _num_cc_clears(0L)
+ _num_cc_clears(0L),
+ _last_gc_worker_start_times_ms(_max_gc_threads, "%.1lf", false),
+ _last_ext_root_scan_times_ms(_max_gc_threads, "%.1lf"),
+ _last_satb_filtering_times_ms(_max_gc_threads, "%.1lf"),
+ _last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
+ _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
+ _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
+ _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
+ _last_termination_times_ms(_max_gc_threads, "%.1lf"),
+ _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
+ _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false),
+ _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"),
+ _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf")
{
assert(max_gc_threads > 0, "Must have some GC threads");
- _par_last_gc_worker_start_times_ms = new double[_max_gc_threads];
- _par_last_ext_root_scan_times_ms = new double[_max_gc_threads];
- _par_last_satb_filtering_times_ms = new double[_max_gc_threads];
- _par_last_update_rs_times_ms = new double[_max_gc_threads];
- _par_last_update_rs_processed_buffers = new double[_max_gc_threads];
- _par_last_scan_rs_times_ms = new double[_max_gc_threads];
- _par_last_obj_copy_times_ms = new double[_max_gc_threads];
- _par_last_termination_times_ms = new double[_max_gc_threads];
- _par_last_termination_attempts = new double[_max_gc_threads];
- _par_last_gc_worker_end_times_ms = new double[_max_gc_threads];
- _par_last_gc_worker_times_ms = new double[_max_gc_threads];
- _par_last_gc_worker_other_times_ms = new double[_max_gc_threads];
}
-void G1GCPhaseTimes::note_gc_start(double pause_start_time_sec, uint active_gc_threads,
- bool is_young_gc, bool is_initial_mark_gc, GCCause::Cause gc_cause) {
+void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
assert(active_gc_threads > 0, "The number of threads must be > 0");
assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max nubmer of threads");
_active_gc_threads = active_gc_threads;
- _pause_start_time_sec = pause_start_time_sec;
- _is_young_gc = is_young_gc;
- _is_initial_mark_gc = is_initial_mark_gc;
- _gc_cause = gc_cause;
-#ifdef ASSERT
- // initialise the timing data to something well known so that we can spot
- // if something is not set properly
-
- for (uint i = 0; i < _max_gc_threads; ++i) {
- _par_last_gc_worker_start_times_ms[i] = -1234.0;
- _par_last_ext_root_scan_times_ms[i] = -1234.0;
- _par_last_satb_filtering_times_ms[i] = -1234.0;
- _par_last_update_rs_times_ms[i] = -1234.0;
- _par_last_update_rs_processed_buffers[i] = -1234.0;
- _par_last_scan_rs_times_ms[i] = -1234.0;
- _par_last_obj_copy_times_ms[i] = -1234.0;
- _par_last_termination_times_ms[i] = -1234.0;
- _par_last_termination_attempts[i] = -1234.0;
- _par_last_gc_worker_end_times_ms[i] = -1234.0;
- _par_last_gc_worker_times_ms[i] = -1234.0;
- _par_last_gc_worker_other_times_ms[i] = -1234.0;
- }
-#endif
+ _last_gc_worker_start_times_ms.reset();
+ _last_ext_root_scan_times_ms.reset();
+ _last_satb_filtering_times_ms.reset();
+ _last_update_rs_times_ms.reset();
+ _last_update_rs_processed_buffers.reset();
+ _last_scan_rs_times_ms.reset();
+ _last_obj_copy_times_ms.reset();
+ _last_termination_times_ms.reset();
+ _last_termination_attempts.reset();
+ _last_gc_worker_end_times_ms.reset();
+ _last_gc_worker_times_ms.reset();
+ _last_gc_worker_other_times_ms.reset();
}
-void G1GCPhaseTimes::note_gc_end(double pause_end_time_sec) {
- if (G1Log::fine()) {
- double pause_time_ms = (pause_end_time_sec - _pause_start_time_sec) * MILLIUNITS;
+void G1GCPhaseTimes::note_gc_end() {
+ _last_gc_worker_start_times_ms.verify();
+ _last_ext_root_scan_times_ms.verify();
+ _last_satb_filtering_times_ms.verify();
+ _last_update_rs_times_ms.verify();
+ _last_update_rs_processed_buffers.verify();
+ _last_scan_rs_times_ms.verify();
+ _last_obj_copy_times_ms.verify();
+ _last_termination_times_ms.verify();
+ _last_termination_attempts.verify();
+ _last_gc_worker_end_times_ms.verify();
for (uint i = 0; i < _active_gc_threads; i++) {
- _par_last_gc_worker_times_ms[i] = _par_last_gc_worker_end_times_ms[i] -
- _par_last_gc_worker_start_times_ms[i];
+ double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i);
+ _last_gc_worker_times_ms.set(i, worker_time);
- double worker_known_time = _par_last_ext_root_scan_times_ms[i] +
- _par_last_satb_filtering_times_ms[i] +
- _par_last_update_rs_times_ms[i] +
- _par_last_scan_rs_times_ms[i] +
- _par_last_obj_copy_times_ms[i] +
- _par_last_termination_times_ms[i];
+ double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
+ _last_satb_filtering_times_ms.get(i) +
+ _last_update_rs_times_ms.get(i) +
+ _last_scan_rs_times_ms.get(i) +
+ _last_obj_copy_times_ms.get(i) +
+ _last_termination_times_ms.get(i);
- _par_last_gc_worker_other_times_ms[i] = _par_last_gc_worker_times_ms[i] -
- worker_known_time;
+ double worker_other_time = worker_time - worker_known_time;
+ _last_gc_worker_other_times_ms.set(i, worker_other_time);
}
- print(pause_time_ms);
- }
-
-}
-
-void G1GCPhaseTimes::print_par_stats(int level,
- const char* str,
- double* data,
- bool showDecimals) {
- double min = data[0], max = data[0];
- double total = 0.0;
- LineBuffer buf(level);
- buf.append("[%s (ms):", str);
- for (uint i = 0; i < _active_gc_threads; ++i) {
- double val = data[i];
- if (val < min)
- min = val;
- if (val > max)
- max = val;
- total += val;
- if (G1Log::finest()) {
- if (showDecimals) {
- buf.append(" %.1lf", val);
- } else {
- buf.append(" %d", (int)val);
- }
- }
- }
-
- if (G1Log::finest()) {
- buf.append_and_print_cr("");
- }
- double avg = total / (double) _active_gc_threads;
- if (showDecimals) {
- buf.append_and_print_cr(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf, Sum: %.1lf]",
- min, avg, max, max - min, total);
- } else {
- buf.append_and_print_cr(" Min: %d, Avg: %d, Max: %d, Diff: %d, Sum: %d]",
- (int)min, (int)avg, (int)max, (int)max - (int)min, (int)total);
- }
+ _last_gc_worker_times_ms.verify();
+ _last_gc_worker_other_times_ms.verify();
}
void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
@@ -202,73 +228,6 @@
LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %d]", str, value, workers);
}
-void G1GCPhaseTimes::print_stats(int level, const char* str, int value) {
- LineBuffer(level).append_and_print_cr("[%s: %d]", str, value);
-}
-
-double G1GCPhaseTimes::avg_value(double* data) {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- double ret = 0.0;
- for (uint i = 0; i < _active_gc_threads; ++i) {
- ret += data[i];
- }
- return ret / (double) _active_gc_threads;
- } else {
- return data[0];
- }
-}
-
-double G1GCPhaseTimes::max_value(double* data) {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- double ret = data[0];
- for (uint i = 1; i < _active_gc_threads; ++i) {
- if (data[i] > ret) {
- ret = data[i];
- }
- }
- return ret;
- } else {
- return data[0];
- }
-}
-
-double G1GCPhaseTimes::sum_of_values(double* data) {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- double sum = 0.0;
- for (uint i = 0; i < _active_gc_threads; i++) {
- sum += data[i];
- }
- return sum;
- } else {
- return data[0];
- }
-}
-
-double G1GCPhaseTimes::max_sum(double* data1, double* data2) {
- double ret = data1[0] + data2[0];
-
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- for (uint i = 1; i < _active_gc_threads; ++i) {
- double data = data1[i] + data2[i];
- if (data > ret) {
- ret = data;
- }
- }
- }
- return ret;
-}
-
-void G1GCPhaseTimes::collapse_par_times() {
- _ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms);
- _satb_filtering_time = avg_value(_par_last_satb_filtering_times_ms);
- _update_rs_time = avg_value(_par_last_update_rs_times_ms);
- _update_rs_processed_buffers =
- sum_of_values(_par_last_update_rs_processed_buffers);
- _scan_rs_time = avg_value(_par_last_scan_rs_times_ms);
- _obj_copy_time = avg_value(_par_last_obj_copy_times_ms);
- _termination_time = avg_value(_par_last_termination_times_ms);
-}
-
double G1GCPhaseTimes::accounted_time_ms() {
// Subtract the root region scanning wait time. It's initialized to
// zero at the start of the pause.
@@ -286,58 +245,37 @@
return misc_time_ms;
}
-void G1GCPhaseTimes::print(double pause_time_ms) {
-
- if (PrintGCTimeStamps) {
- gclog_or_tty->stamp();
- gclog_or_tty->print(": ");
- }
-
- GCCauseString gc_cause_str = GCCauseString("GC pause", _gc_cause)
- .append(_is_young_gc ? " (young)" : " (mixed)")
- .append(_is_initial_mark_gc ? " (initial-mark)" : "");
- gclog_or_tty->print_cr("[%s, %3.7f secs]", (const char*)gc_cause_str, pause_time_ms / 1000.0);
-
- if (!G1Log::finer()) {
- return;
- }
-
+void G1GCPhaseTimes::print(double pause_time_sec) {
if (_root_region_scan_wait_time_ms > 0.0) {
print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
}
if (G1CollectedHeap::use_parallel_gc_threads()) {
print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
- print_par_stats(2, "GC Worker Start", _par_last_gc_worker_start_times_ms);
- print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
- if (_satb_filtering_time > 0.0) {
- print_par_stats(2, "SATB Filtering", _par_last_satb_filtering_times_ms);
+ _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
+ _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
+ if (_last_satb_filtering_times_ms.sum() > 0.0) {
+ _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
}
- print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
- if (G1Log::finest()) {
- print_par_stats(3, "Processed Buffers", _par_last_update_rs_processed_buffers,
- false /* showDecimals */);
- }
- print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms);
- print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms);
- print_par_stats(2, "Termination", _par_last_termination_times_ms);
+ _last_update_rs_times_ms.print(2, "Update RS (ms)");
+ _last_update_rs_processed_buffers.print(3, "Processed Buffers");
+ _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
+ _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
+ _last_termination_times_ms.print(2, "Termination (ms)");
if (G1Log::finest()) {
- print_par_stats(3, "Termination Attempts", _par_last_termination_attempts,
- false /* showDecimals */);
+ _last_termination_attempts.print(3, "Termination Attempts");
}
- print_par_stats(2, "GC Worker Other", _par_last_gc_worker_other_times_ms);
- print_par_stats(2, "GC Worker Total", _par_last_gc_worker_times_ms);
- print_par_stats(2, "GC Worker End", _par_last_gc_worker_end_times_ms);
+ _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
+ _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
+ _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
} else {
- print_stats(1, "Ext Root Scanning", _ext_root_scan_time);
- if (_satb_filtering_time > 0.0) {
- print_stats(1, "SATB Filtering", _satb_filtering_time);
+ _last_ext_root_scan_times_ms.print(1, "Ext Root Scanning (ms)");
+ if (_last_satb_filtering_times_ms.sum() > 0.0) {
+ _last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
}
- print_stats(1, "Update RS", _update_rs_time);
- if (G1Log::finest()) {
- print_stats(2, "Processed Buffers", (int)_update_rs_processed_buffers);
- }
- print_stats(1, "Scan RS", _scan_rs_time);
- print_stats(1, "Object Copying", _obj_copy_time);
+ _last_update_rs_times_ms.print(1, "Update RS (ms)");
+ _last_update_rs_processed_buffers.print(2, "Processed Buffers");
+ _last_scan_rs_times_ms.print(1, "Scan RS (ms)");
+ _last_obj_copy_times_ms.print(1, "Object Copy (ms)");
}
print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
@@ -350,8 +288,11 @@
print_stats(1, "Avg Clear CC", _cum_clear_cc_time_ms / ((double)_num_cc_clears));
}
}
- double misc_time_ms = pause_time_ms - accounted_time_ms();
+ double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
print_stats(1, "Other", misc_time_ms);
+ if (_cur_verify_before_time_ms > 0.0) {
+ print_stats(2, "Verify Before", _cur_verify_before_time_ms);
+ }
print_stats(2, "Choose CSet",
(_recorded_young_cset_choice_time_ms +
_recorded_non_young_cset_choice_time_ms));
@@ -360,6 +301,9 @@
print_stats(2, "Free CSet",
(_recorded_young_free_cset_time_ms +
_recorded_non_young_free_cset_time_ms));
+ if (_cur_verify_after_time_ms > 0.0) {
+ print_stats(2, "Verify After", _cur_verify_after_time_ms);
+ }
}
void G1GCPhaseTimes::record_cc_clear_time_ms(double ms) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -28,52 +28,109 @@
#include "memory/allocation.hpp"
#include "gc_interface/gcCause.hpp"
+template <class T>
+class WorkerDataArray : public CHeapObj<mtGC> {
+ T* _data;
+ uint _length;
+ const char* _print_format;
+ bool _print_sum;
+
+ // We are caching the sum and average to only have to calculate them once.
+ // This is not done in an MT-safe way. It is intetened to allow single
+ // threaded code to call sum() and average() multiple times in any order
+ // without having to worry about the cost.
+ bool _has_new_data;
+ T _sum;
+ double _average;
+
+ public:
+ WorkerDataArray(uint length, const char* print_format, bool print_sum = true) :
+ _length(length), _print_format(print_format), _print_sum(print_sum), _has_new_data(true) {
+ assert(length > 0, "Must have some workers to store data for");
+ _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
+ }
+
+ ~WorkerDataArray() {
+ FREE_C_HEAP_ARRAY(T, _data, mtGC);
+ }
+
+ void set(uint worker_i, T value) {
+ assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+ assert(_data[worker_i] == (T)-1, err_msg("Overwriting data for worker %d", worker_i));
+ _data[worker_i] = value;
+ _has_new_data = true;
+ }
+
+ T get(uint worker_i) {
+ assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+ assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
+ return _data[worker_i];
+ }
+
+ void add(uint worker_i, T value) {
+ assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+ assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
+ _data[worker_i] += value;
+ _has_new_data = true;
+ }
+
+ double average(){
+ if (_has_new_data) {
+ calculate_totals();
+ }
+ return _average;
+ }
+
+ T sum() {
+ if (_has_new_data) {
+ calculate_totals();
+ }
+ return _sum;
+ }
+
+ void print(int level, const char* title);
+
+ void reset() PRODUCT_RETURN;
+ void verify() PRODUCT_RETURN;
+
+ private:
+
+ void calculate_totals(){
+ _sum = (T)0;
+ for (uint i = 0; i < _length; ++i) {
+ _sum += _data[i];
+ }
+ _average = (double)_sum / (double)_length;
+ _has_new_data = false;
+ }
+};
+
class G1GCPhaseTimes : public CHeapObj<mtGC> {
- friend class G1CollectorPolicy;
- friend class TraceGen0TimeData;
private:
uint _active_gc_threads;
uint _max_gc_threads;
- GCCause::Cause _gc_cause;
- bool _is_young_gc;
- bool _is_initial_mark_gc;
-
- double _pause_start_time_sec;
-
- double* _par_last_gc_worker_start_times_ms;
- double* _par_last_ext_root_scan_times_ms;
- double* _par_last_satb_filtering_times_ms;
- double* _par_last_update_rs_times_ms;
- double* _par_last_update_rs_processed_buffers;
- double* _par_last_scan_rs_times_ms;
- double* _par_last_obj_copy_times_ms;
- double* _par_last_termination_times_ms;
- double* _par_last_termination_attempts;
- double* _par_last_gc_worker_end_times_ms;
- double* _par_last_gc_worker_times_ms;
- double* _par_last_gc_worker_other_times_ms;
+ WorkerDataArray<double> _last_gc_worker_start_times_ms;
+ WorkerDataArray<double> _last_ext_root_scan_times_ms;
+ WorkerDataArray<double> _last_satb_filtering_times_ms;
+ WorkerDataArray<double> _last_update_rs_times_ms;
+ WorkerDataArray<int> _last_update_rs_processed_buffers;
+ WorkerDataArray<double> _last_scan_rs_times_ms;
+ WorkerDataArray<double> _last_obj_copy_times_ms;
+ WorkerDataArray<double> _last_termination_times_ms;
+ WorkerDataArray<size_t> _last_termination_attempts;
+ WorkerDataArray<double> _last_gc_worker_end_times_ms;
+ WorkerDataArray<double> _last_gc_worker_times_ms;
+ WorkerDataArray<double> _last_gc_worker_other_times_ms;
double _cur_collection_par_time_ms;
-
double _cur_collection_code_root_fixup_time_ms;
double _cur_clear_ct_time_ms;
double _cur_ref_proc_time_ms;
double _cur_ref_enq_time_ms;
- // Helper methods for detailed logging
- void print_par_stats(int level, const char* str, double* data, bool showDecimals = true);
- void print_stats(int level, const char* str, double value);
- void print_stats(int level, const char* str, double value, int workers);
- void print_stats(int level, const char* str, int value);
- double avg_value(double* data);
- double max_value(double* data);
- double sum_of_values(double* data);
- double max_sum(double* data1, double* data2);
- double accounted_time_ms();
-
// Card Table Count Cache stats
double _min_clear_cc_time_ms; // min
double _max_clear_cc_time_ms; // max
@@ -81,19 +138,6 @@
double _cum_clear_cc_time_ms; // cummulative clearing time
jlong _num_cc_clears; // number of times the card count cache has been cleared
- // The following insance variables are directly accessed by G1CollectorPolicy
- // and TraceGen0TimeData. This is why those classes are declared friends.
- // An alternative is to add getters and setters for all of these fields.
- // It might also be possible to restructure the code to reduce these
- // dependencies.
- double _ext_root_scan_time;
- double _satb_filtering_time;
- double _update_rs_time;
- double _update_rs_processed_buffers;
- double _scan_rs_time;
- double _obj_copy_time;
- double _termination_time;
-
double _cur_collection_start_sec;
double _root_region_scan_wait_time_ms;
@@ -103,79 +147,58 @@
double _recorded_young_free_cset_time_ms;
double _recorded_non_young_free_cset_time_ms;
- void print(double pause_time_ms);
+ double _cur_verify_before_time_ms;
+ double _cur_verify_after_time_ms;
+
+ // Helper methods for detailed logging
+ void print_stats(int level, const char* str, double value);
+ void print_stats(int level, const char* str, double value, int workers);
public:
G1GCPhaseTimes(uint max_gc_threads);
- void note_gc_start(double pause_start_time_sec, uint active_gc_threads,
- bool is_young_gc, bool is_initial_mark_gc, GCCause::Cause gc_cause);
- void note_gc_end(double pause_end_time_sec);
- void collapse_par_times();
+ void note_gc_start(uint active_gc_threads);
+ void note_gc_end();
+ void print(double pause_time_sec);
void record_gc_worker_start_time(uint worker_i, double ms) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_gc_worker_start_times_ms[worker_i] = ms;
+ _last_gc_worker_start_times_ms.set(worker_i, ms);
}
void record_ext_root_scan_time(uint worker_i, double ms) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_ext_root_scan_times_ms[worker_i] = ms;
+ _last_ext_root_scan_times_ms.set(worker_i, ms);
}
void record_satb_filtering_time(uint worker_i, double ms) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_satb_filtering_times_ms[worker_i] = ms;
+ _last_satb_filtering_times_ms.set(worker_i, ms);
}
void record_update_rs_time(uint worker_i, double ms) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_update_rs_times_ms[worker_i] = ms;
+ _last_update_rs_times_ms.set(worker_i, ms);
}
- void record_update_rs_processed_buffers (uint worker_i,
- double processed_buffers) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_update_rs_processed_buffers[worker_i] = processed_buffers;
+ void record_update_rs_processed_buffers(uint worker_i, int processed_buffers) {
+ _last_update_rs_processed_buffers.set(worker_i, processed_buffers);
}
void record_scan_rs_time(uint worker_i, double ms) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_scan_rs_times_ms[worker_i] = ms;
- }
-
- void reset_obj_copy_time(uint worker_i) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_obj_copy_times_ms[worker_i] = 0.0;
- }
-
- void reset_obj_copy_time() {
- reset_obj_copy_time(0);
+ _last_scan_rs_times_ms.set(worker_i, ms);
}
void record_obj_copy_time(uint worker_i, double ms) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_obj_copy_times_ms[worker_i] += ms;
+ _last_obj_copy_times_ms.set(worker_i, ms);
+ }
+
+ void add_obj_copy_time(uint worker_i, double ms) {
+ _last_obj_copy_times_ms.add(worker_i, ms);
}
void record_termination(uint worker_i, double ms, size_t attempts) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_termination_times_ms[worker_i] = ms;
- _par_last_termination_attempts[worker_i] = (double) attempts;
+ _last_termination_times_ms.set(worker_i, ms);
+ _last_termination_attempts.set(worker_i, attempts);
}
void record_gc_worker_end_time(uint worker_i, double ms) {
- assert(worker_i >= 0, "worker index must be > 0");
- assert(worker_i < _active_gc_threads, "worker index out of bounds");
- _par_last_gc_worker_end_times_ms[worker_i] = ms;
+ _last_gc_worker_end_times_ms.set(worker_i, ms);
}
void record_clear_ct_time(double ms) {
@@ -211,6 +234,88 @@
void record_non_young_free_cset_time_ms(double time_ms) {
_recorded_non_young_free_cset_time_ms = time_ms;
}
+
+ void record_young_cset_choice_time_ms(double time_ms) {
+ _recorded_young_cset_choice_time_ms = time_ms;
+ }
+
+ void record_non_young_cset_choice_time_ms(double time_ms) {
+ _recorded_non_young_cset_choice_time_ms = time_ms;
+ }
+
+ void record_cur_collection_start_sec(double time_ms) {
+ _cur_collection_start_sec = time_ms;
+ }
+
+ void record_verify_before_time_ms(double time_ms) {
+ _cur_verify_before_time_ms = time_ms;
+ }
+
+ void record_verify_after_time_ms(double time_ms) {
+ _cur_verify_after_time_ms = time_ms;
+ }
+
+ double accounted_time_ms();
+
+ double cur_collection_start_sec() {
+ return _cur_collection_start_sec;
+ }
+
+ double cur_collection_par_time_ms() {
+ return _cur_collection_par_time_ms;
+ }
+
+ double cur_clear_ct_time_ms() {
+ return _cur_clear_ct_time_ms;
+ }
+
+ double root_region_scan_wait_time_ms() {
+ return _root_region_scan_wait_time_ms;
+ }
+
+ double young_cset_choice_time_ms() {
+ return _recorded_young_cset_choice_time_ms;
+ }
+
+ double young_free_cset_time_ms() {
+ return _recorded_young_free_cset_time_ms;
+ }
+
+ double non_young_cset_choice_time_ms() {
+ return _recorded_non_young_cset_choice_time_ms;
+ }
+
+ double non_young_free_cset_time_ms() {
+ return _recorded_non_young_free_cset_time_ms;
+ }
+
+ double average_last_update_rs_time() {
+ return _last_update_rs_times_ms.average();
+ }
+
+ int sum_last_update_rs_processed_buffers() {
+ return _last_update_rs_processed_buffers.sum();
+ }
+
+ double average_last_scan_rs_time(){
+ return _last_scan_rs_times_ms.average();
+ }
+
+ double average_last_obj_copy_time() {
+ return _last_obj_copy_times_ms.average();
+ }
+
+ double average_last_termination_time() {
+ return _last_termination_times_ms.average();
+ }
+
+ double average_last_ext_root_scan_time() {
+ return _last_ext_root_scan_times_ms.average();
+ }
+
+ double average_last_satb_filtering_times_ms() {
+ return _last_satb_filtering_times_ms.average();
+ }
};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -324,7 +324,7 @@
if (G1UseParallelRSetUpdating || (worker_i == 0)) {
updateRS(&into_cset_dcq, worker_i);
} else {
- _g1p->phase_times()->record_update_rs_processed_buffers(worker_i, 0.0);
+ _g1p->phase_times()->record_update_rs_processed_buffers(worker_i, 0);
_g1p->phase_times()->record_update_rs_time(worker_i, 0.0);
}
if (G1UseParallelRSetScanning || (worker_i == 0)) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -311,7 +311,35 @@
"as a percentage of the heap size.") \
\
experimental(ccstr, G1LogLevel, NULL, \
- "Log level for G1 logging: fine, finer, finest")
+ "Log level for G1 logging: fine, finer, finest") \
+ \
+ notproduct(bool, G1EvacuationFailureALot, false, \
+ "Force use of evacuation failure handling during certain " \
+ "evacuation pauses") \
+ \
+ develop(uintx, G1EvacuationFailureALotCount, 1000, \
+ "Number of successful evacuations between evacuation failures " \
+ "occurring at object copying") \
+ \
+ develop(uintx, G1EvacuationFailureALotInterval, 5, \
+ "Total collections between forced triggering of evacuation " \
+ "failures") \
+ \
+ develop(bool, G1EvacuationFailureALotDuringConcMark, true, \
+ "Force use of evacuation failure handling during evacuation " \
+ "pauses when marking is in progress") \
+ \
+ develop(bool, G1EvacuationFailureALotDuringInitialMark, true, \
+ "Force use of evacuation failure handling during initial mark " \
+ "evacuation pauses") \
+ \
+ develop(bool, G1EvacuationFailureALotDuringYoungGC, true, \
+ "Force use of evacuation failure handling during young " \
+ "evacuation pauses") \
+ \
+ develop(bool, G1EvacuationFailureALotDuringMixedGC, true, \
+ "Force use of evacuation failure handling during mixed " \
+ "evacuation pauses")
G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -424,6 +424,8 @@
|| code == _fconst_0 || code == _dconst_0); }
static bool is_invoke (Code code) { return (_invokevirtual <= code && code <= _invokedynamic); }
+ static bool has_optional_appendix(Code code) { return code == _invokedynamic || code == _invokehandle; }
+
static int compute_flags (const char* format, int more_flags = 0); // compute the flags
static int flags (int code, bool is_wide) {
assert(code == (u_char)code, "must be a byte");
--- a/hotspot/src/share/vm/opto/c2_globals.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -353,27 +353,9 @@
develop(bool, StressRecompilation, false, \
"Recompile each compiled method without subsuming loads or escape analysis.") \
\
- /* controls for tier 1 compilations */ \
- \
- develop(bool, Tier1CountInvocations, true, \
- "Generate code, during tier 1, to update invocation counter") \
- \
- product(intx, Tier1Inline, false, \
- "enable inlining during tier 1") \
- \
- product(intx, Tier1MaxInlineSize, 8, \
- "maximum bytecode size of a method to be inlined, during tier 1") \
- \
- product(intx, Tier1FreqInlineSize, 35, \
- "max bytecode size of a frequent method to be inlined, tier 1") \
- \
develop(intx, ImplicitNullCheckThreshold, 3, \
"Don't do implicit null checks if NPE's in a method exceeds limit") \
\
- /* controls for loop optimization */ \
- product(intx, Tier1LoopOptsCount, 0, \
- "Set level of loop optimization for tier 1 compiles") \
- \
product(intx, LoopOptsCount, 43, \
"Set level of loop optimization for tier 1 compiles") \
\
@@ -505,6 +487,116 @@
\
product(bool, BlockLayoutRotateLoops, true, \
"Allow back branches to be fall throughs in the block layour") \
+ \
+ develop(bool, InlineReflectionGetCallerClass, true, \
+ "inline sun.reflect.Reflection.getCallerClass(), known to be part "\
+ "of base library DLL") \
+ \
+ develop(bool, InlineObjectCopy, true, \
+ "inline Object.clone and Arrays.copyOf[Range] intrinsics") \
+ \
+ develop(bool, SpecialStringCompareTo, true, \
+ "special version of string compareTo") \
+ \
+ develop(bool, SpecialStringIndexOf, true, \
+ "special version of string indexOf") \
+ \
+ develop(bool, SpecialStringEquals, true, \
+ "special version of string equals") \
+ \
+ develop(bool, SpecialArraysEquals, true, \
+ "special version of Arrays.equals(char[],char[])") \
+ \
+ develop(bool, BailoutToInterpreterForThrows, false, \
+ "Compiled methods which throws/catches exceptions will be " \
+ "deopt and intp.") \
+ \
+ develop(bool, ConvertCmpD2CmpF, true, \
+ "Convert cmpD to cmpF when one input is constant in float range") \
+ \
+ develop(bool, ConvertFloat2IntClipping, true, \
+ "Convert float2int clipping idiom to integer clipping") \
+ \
+ develop(bool, Use24BitFPMode, true, \
+ "Set 24-bit FPU mode on a per-compile basis ") \
+ \
+ develop(bool, Use24BitFP, true, \
+ "use FP instructions that produce 24-bit precise results") \
+ \
+ develop(bool, MonomorphicArrayCheck, true, \
+ "Uncommon-trap array store checks that require full type check") \
+ \
+ notproduct(bool, TracePhaseCCP, false, \
+ "Print progress during Conditional Constant Propagation") \
+ \
+ develop(bool, PrintDominators, false, \
+ "Print out dominator trees for GVN") \
+ \
+ notproduct(bool, TraceSpilling, false, \
+ "Trace spilling") \
+ \
+ notproduct(bool, TraceTypeProfile, false, \
+ "Trace type profile") \
+ \
+ develop(bool, PoisonOSREntry, true, \
+ "Detect abnormal calls to OSR code") \
+ \
+ product(bool, UseCondCardMark, false, \
+ "Check for already marked card before updating card table") \
+ \
+ develop(bool, SoftMatchFailure, trueInProduct, \
+ "If the DFA fails to match a node, print a message and bail out") \
+ \
+ develop(bool, InlineAccessors, true, \
+ "inline accessor methods (get/set)") \
+ \
+ product(intx, TypeProfileMajorReceiverPercent, 90, \
+ "% of major receiver type to all profiled receivers") \
+ \
+ notproduct(bool, TimeCompiler2, false, \
+ "detailed time the compiler (requires +TimeCompiler)") \
+ \
+ diagnostic(bool, PrintIntrinsics, false, \
+ "prints attempted and successful inlining of intrinsics") \
+ \
+ diagnostic(ccstrlist, DisableIntrinsic, "", \
+ "do not expand intrinsics whose (internal) names appear here") \
+ \
+ develop(bool, StressReflectiveCode, false, \
+ "Use inexact types at allocations, etc., to test reflection") \
+ \
+ diagnostic(bool, DebugInlinedCalls, true, \
+ "If false, restricts profiled locations to the root method only") \
+ \
+ notproduct(bool, VerifyLoopOptimizations, false, \
+ "verify major loop optimizations") \
+ \
+ diagnostic(bool, ProfileDynamicTypes, true, \
+ "do extra type profiling and use it more aggressively") \
+ \
+ develop(bool, TraceIterativeGVN, false, \
+ "Print progress during Iterative Global Value Numbering") \
+ \
+ develop(bool, VerifyIterativeGVN, false, \
+ "Verify Def-Use modifications during sparse Iterative Global " \
+ "Value Numbering") \
+ \
+ notproduct(bool, TraceCISCSpill, false, \
+ "Trace allocators use of cisc spillable instructions") \
+ \
+ product(bool, SplitIfBlocks, true, \
+ "Clone compares and control flow through merge points to fold " \
+ "some branches") \
+ \
+ develop(intx, FreqCountInvocations, 1, \
+ "Scaling factor for branch frequencies (deprecated)") \
+ \
+ product(intx, AliasLevel, 3, \
+ "0 for no aliasing, 1 for oop/field/static/array split, " \
+ "2 for class split, 3 for unique instances") \
+ \
+ develop(bool, VerifyAliases, false, \
+ "perform extra checks on the results of alias analysis") \
C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
--- a/hotspot/src/share/vm/opto/chaitin.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -222,6 +222,7 @@
_alternate = 0;
_matcher._allocation_started = true;
+ ResourceArea split_arena; // Arena for Split local resources
ResourceArea live_arena; // Arena for liveness & IFG info
ResourceMark rm(&live_arena);
@@ -324,7 +325,7 @@
// Bail out if unique gets too large (ie - unique > MaxNodeLimit)
C->check_node_count(10*must_spill, "out of nodes before split");
if (C->failing()) return;
- _maxlrg = Split( _maxlrg ); // Split spilling LRG everywhere
+ _maxlrg = Split(_maxlrg, &split_arena); // Split spilling LRG everywhere
// Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
// or we failed to split
C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
@@ -390,7 +391,7 @@
}
if( !_maxlrg ) return;
- _maxlrg = Split( _maxlrg ); // Split spilling LRG everywhere
+ _maxlrg = Split(_maxlrg, &split_arena); // Split spilling LRG everywhere
// Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
if (C->failing()) return;
--- a/hotspot/src/share/vm/opto/chaitin.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -470,7 +470,7 @@
// Split uncolorable live ranges
// Return new number of live ranges
- uint Split( uint maxlrg );
+ uint Split(uint maxlrg, ResourceArea* split_arena);
// Copy 'was_spilled'-edness from one Node to another.
void copy_was_spilled( Node *src, Node *dst );
--- a/hotspot/src/share/vm/opto/doCall.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/doCall.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -341,25 +341,26 @@
kill_dead_locals();
// Set frequently used booleans
- bool is_virtual = bc() == Bytecodes::_invokevirtual;
- bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface;
- bool has_receiver = is_virtual_or_interface || bc() == Bytecodes::_invokespecial;
- bool is_invokedynamic = bc() == Bytecodes::_invokedynamic;
+ const bool is_virtual = bc() == Bytecodes::_invokevirtual;
+ const bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface;
+ const bool has_receiver = is_virtual_or_interface || bc() == Bytecodes::_invokespecial;
// Find target being called
bool will_link;
- ciMethod* bc_callee = iter().get_method(will_link); // actual callee from bytecode
- ciInstanceKlass* holder_klass = bc_callee->holder();
- ciKlass* holder = iter().get_declared_method_holder();
+ ciSignature* declared_signature = NULL;
+ ciMethod* orig_callee = iter().get_method(will_link, &declared_signature); // callee in the bytecode
+ ciInstanceKlass* holder_klass = orig_callee->holder();
+ ciKlass* holder = iter().get_declared_method_holder();
ciInstanceKlass* klass = ciEnv::get_instance_klass_for_declared_method_holder(holder);
+ assert(declared_signature != NULL, "cannot be null");
// uncommon-trap when callee is unloaded, uninitialized or will not link
// bailout when too many arguments for register representation
- if (!will_link || can_not_compile_call_site(bc_callee, klass)) {
+ if (!will_link || can_not_compile_call_site(orig_callee, klass)) {
#ifndef PRODUCT
if (PrintOpto && (Verbose || WizardMode)) {
method()->print_name(); tty->print_cr(" can not compile call at bci %d to:", bci());
- bc_callee->print_name(); tty->cr();
+ orig_callee->print_name(); tty->cr();
}
#endif
return;
@@ -372,7 +373,7 @@
// Note: In the absence of miranda methods, an abstract class K can perform
// an invokevirtual directly on an interface method I.m if K implements I.
- const int nargs = bc_callee->arg_size();
+ const int nargs = orig_callee->arg_size();
// Push appendix argument (MethodType, CallSite, etc.), if one.
if (iter().has_appendix()) {
@@ -392,13 +393,13 @@
// Choose call strategy.
bool call_is_virtual = is_virtual_or_interface;
int vtable_index = methodOopDesc::invalid_vtable_index;
- ciMethod* callee = bc_callee;
+ ciMethod* callee = orig_callee;
// Try to get the most accurate receiver type
if (is_virtual_or_interface) {
Node* receiver_node = stack(sp() - nargs);
const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr();
- ciMethod* optimized_virtual_method = optimize_inlining(method(), bci(), klass, bc_callee, receiver_type);
+ ciMethod* optimized_virtual_method = optimize_inlining(method(), bci(), klass, orig_callee, receiver_type);
// Have the call been sufficiently improved such that it is no longer a virtual?
if (optimized_virtual_method != NULL) {
@@ -425,7 +426,8 @@
// It decides whether inlining is desirable or not.
CallGenerator* cg = C->call_generator(callee, vtable_index, call_is_virtual, jvms, try_inline, prof_factor());
- bc_callee = callee = NULL; // don't use bc_callee and callee after this point
+ // NOTE: Don't use orig_callee and callee after this point! Use cg->method() instead.
+ orig_callee = callee = NULL;
// ---------------------
// Round double arguments before call
@@ -497,9 +499,9 @@
round_double_result(cg->method());
ciType* rtype = cg->method()->return_type();
- if (iter().cur_bc_raw() == Bytecodes::_invokehandle || is_invokedynamic) {
+ if (Bytecodes::has_optional_appendix(iter().cur_bc_raw())) {
// Be careful here with return types.
- ciType* ctype = iter().get_declared_method_signature()->return_type();
+ ciType* ctype = declared_signature->return_type();
if (ctype != rtype) {
BasicType rt = rtype->basic_type();
BasicType ct = ctype->basic_type();
@@ -528,15 +530,13 @@
} else if (rt == T_OBJECT || rt == T_ARRAY) {
assert(ct == T_OBJECT || ct == T_ARRAY, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct)));
if (ctype->is_loaded()) {
- Node* if_fail = top();
- retnode = gen_checkcast(retnode, makecon(TypeKlassPtr::make(ctype->as_klass())), &if_fail);
- if (if_fail != top()) {
- PreserveJVMState pjvms(this);
- set_control(if_fail);
- builtin_throw(Deoptimization::Reason_class_check);
+ const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass());
+ const Type* sig_type = TypeOopPtr::make_from_klass(ctype->as_klass());
+ if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
+ Node* cast_obj = _gvn.transform(new (C, 2) CheckCastPPNode(control(), retnode, sig_type));
+ pop();
+ push(cast_obj);
}
- pop();
- push(retnode);
}
} else {
assert(ct == rt, err_msg_res("unexpected mismatch rt=%d, ct=%d", rt, ct));
--- a/hotspot/src/share/vm/opto/graphKit.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -1006,11 +1006,11 @@
case Bytecodes::_putfield:
{
bool is_get = (depth >= 0), is_static = (depth & 1);
- bool ignore;
ciBytecodeStream iter(method());
iter.reset_to_bci(bci());
iter.next();
- ciField* field = iter.get_field(ignore);
+ bool ignored_will_link;
+ ciField* field = iter.get_field(ignored_will_link);
int size = field->type()->size();
inputs = (is_static ? 0 : 1);
if (is_get) {
@@ -1028,11 +1028,13 @@
case Bytecodes::_invokedynamic:
case Bytecodes::_invokeinterface:
{
- bool ignore;
ciBytecodeStream iter(method());
iter.reset_to_bci(bci());
iter.next();
- ciMethod* callee = iter.get_method(ignore);
+ bool ignored_will_link;
+ ciSignature* declared_signature = NULL;
+ ciMethod* callee = iter.get_method(ignored_will_link, &declared_signature);
+ assert(declared_signature != NULL, "cannot be null");
// (Do not use ciMethod::arg_size(), because
// it might be an unloaded method, which doesn't
// know whether it is static or not.)
@@ -1046,7 +1048,7 @@
// remove any appendix arguments that were popped.
inputs = callee->invoke_arg_size(code) - (callee->has_member_arg() ? 1 : 0);
}
- int size = callee->return_type()->size();
+ int size = declared_signature->return_type()->size();
depth = size - inputs;
}
break;
--- a/hotspot/src/share/vm/opto/loopTransform.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -547,11 +547,6 @@
Node *nnn = old_new[old->_idx];
if (!has_ctrl(nnn))
set_idom(nnn, idom(nnn), dd-1);
- // While we're at it, remove any SafePoints from the peeled code
- if (old->Opcode() == Op_SafePoint) {
- Node *nnn = old_new[old->_idx];
- lazy_replace(nnn,nnn->in(TypeFunc::Control));
- }
}
// Now force out all loop-invariant dominating tests. The optimizer
--- a/hotspot/src/share/vm/opto/loopnode.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/loopnode.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -577,6 +577,9 @@
Node *sfpt = x->in(LoopNode::LoopBackControl);
if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
lazy_replace( sfpt, iftrue );
+ if (loop->_safepts != NULL) {
+ loop->_safepts->yank(sfpt);
+ }
loop->_tail = iftrue;
}
@@ -668,8 +671,12 @@
// Check for immediately preceding SafePoint and remove
Node *sfpt2 = le->in(0);
- if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2))
+ if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2)) {
lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
+ if (loop->_safepts != NULL) {
+ loop->_safepts->yank(sfpt2);
+ }
+ }
// Free up intermediate goo
_igvn.remove_dead_node(hook);
@@ -1526,10 +1533,8 @@
void IdealLoopTree::check_safepts(VectorSet &visited, Node_List &stack) {
// Bottom up traversal
IdealLoopTree* ch = _child;
- while (ch != NULL) {
- ch->check_safepts(visited, stack);
- ch = ch->_next;
- }
+ if (_child) _child->check_safepts(visited, stack);
+ if (_next) _next ->check_safepts(visited, stack);
if (!_head->is_CountedLoop() && !_has_sfpt && _parent != NULL && !_irreducible) {
bool has_call = false; // call on dom-path
@@ -1702,29 +1707,39 @@
phase->is_counted_loop(_head, this)) {
_has_sfpt = 1; // Indicate we do not need a safepoint here
- // Look for a safepoint to remove
- for (Node* n = tail(); n != _head; n = phase->idom(n))
- if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this &&
- phase->is_deleteable_safept(n))
- phase->lazy_replace(n,n->in(TypeFunc::Control));
+ // Look for safepoints to remove.
+ Node_List* sfpts = _safepts;
+ if (sfpts != NULL) {
+ for (uint i = 0; i < sfpts->size(); i++) {
+ Node* n = sfpts->at(i);
+ assert(phase->get_loop(n) == this, "");
+ if (phase->is_deleteable_safept(n)) {
+ phase->lazy_replace(n, n->in(TypeFunc::Control));
+ }
+ }
+ }
// Look for induction variables
phase->replace_parallel_iv(this);
} else if (_parent != NULL && !_irreducible) {
// Not a counted loop.
- // Look for a safepoint on the idom-path to remove, preserving the first one
- bool found = false;
- Node* n = tail();
- for (; n != _head && !found; n = phase->idom(n)) {
- if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this)
- found = true; // Found one
+ // Look for a safepoint on the idom-path.
+ Node* sfpt = tail();
+ for (; sfpt != _head; sfpt = phase->idom(sfpt)) {
+ if (sfpt->Opcode() == Op_SafePoint && phase->get_loop(sfpt) == this)
+ break; // Found one
}
- // Skip past it and delete the others
- for (; n != _head; n = phase->idom(n)) {
- if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this &&
- phase->is_deleteable_safept(n))
- phase->lazy_replace(n,n->in(TypeFunc::Control));
+ // Delete other safepoints in this loop.
+ Node_List* sfpts = _safepts;
+ if (sfpts != NULL && sfpt != _head && sfpt->Opcode() == Op_SafePoint) {
+ for (uint i = 0; i < sfpts->size(); i++) {
+ Node* n = sfpts->at(i);
+ assert(phase->get_loop(n) == this, "");
+ if (n != sfpt && phase->is_deleteable_safept(n)) {
+ phase->lazy_replace(n, n->in(TypeFunc::Control));
+ }
+ }
}
}
@@ -2766,6 +2781,10 @@
// if the allocation is not eliminated for some reason.
innermost->_allow_optimizations = false;
innermost->_has_call = 1; // = true
+ } else if (n->Opcode() == Op_SafePoint) {
+ // Record all safepoints in this loop.
+ if (innermost->_safepts == NULL) innermost->_safepts = new Node_List();
+ innermost->_safepts->push(n);
}
}
}
@@ -2816,6 +2835,9 @@
is_deleteable_safept(n)) {
Node *in = n->in(TypeFunc::Control);
lazy_replace(n,in); // Pull safepoint now
+ if (ilt->_safepts != NULL) {
+ ilt->_safepts->yank(n);
+ }
// Carry on with the recursion "as if" we are walking
// only the control input
if( !visited.test_set( in->_idx ) ) {
--- a/hotspot/src/share/vm/opto/loopnode.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/loopnode.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -336,6 +336,7 @@
_has_sfpt:1, // True if has non-call safepoint
_rce_candidate:1; // True if candidate for range check elimination
+ Node_List* _safepts; // List of safepoints in this loop
Node_List* _required_safept; // A inner loop cannot delete these safepts;
bool _allow_optimizations; // Allow loop optimizations
@@ -343,6 +344,7 @@
: _parent(0), _next(0), _child(0),
_head(head), _tail(tail),
_phase(phase),
+ _safepts(NULL),
_required_safept(NULL),
_allow_optimizations(true),
_nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0)
--- a/hotspot/src/share/vm/opto/reg_split.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/reg_split.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -449,9 +449,12 @@
// USES: If USE is in HRP, split at use to leave main LRG on stack.
// Else, hoist LRG back up to register only (ie - split is also DEF)
// We will compute a new maxlrg as we go
-uint PhaseChaitin::Split( uint maxlrg ) {
+uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
NOT_PRODUCT( Compile::TracePhase t3("regAllocSplit", &_t_regAllocSplit, TimeCompiler); )
+ // Free thread local resources used by this method on exit.
+ ResourceMark rm(split_arena);
+
uint bidx, pidx, slidx, insidx, inpidx, twoidx;
uint non_phi = 1, spill_cnt = 0;
Node **Reachblock;
@@ -461,14 +464,17 @@
bool u1, u2, u3;
Block *b, *pred;
PhiNode *phi;
- GrowableArray<uint> lidxs;
+ GrowableArray<uint> lidxs(split_arena, _maxlrg, 0, 0);
// Array of counters to count splits per live range
- GrowableArray<uint> splits;
+ GrowableArray<uint> splits(split_arena, _maxlrg, 0, 0);
+
+#define NEW_SPLIT_ARRAY(type, size)\
+ (type*) split_arena->allocate_bytes((size) * sizeof(type))
//----------Setup Code----------
// Create a convenient mapping from lrg numbers to reaches/leaves indices
- uint *lrg2reach = NEW_RESOURCE_ARRAY( uint, _maxlrg );
+ uint *lrg2reach = NEW_SPLIT_ARRAY( uint, _maxlrg );
// Keep track of DEFS & Phis for later passes
defs = new Node_List();
phis = new Node_List();
@@ -500,15 +506,15 @@
// a Def is UP or DOWN. UP means that it should get a register (ie -
// it is always in LRP regions), and DOWN means that it is probably
// on the stack (ie - it crosses HRP regions).
- Node ***Reaches = NEW_RESOURCE_ARRAY( Node**, _cfg._num_blocks+1 );
- bool **UP = NEW_RESOURCE_ARRAY( bool*, _cfg._num_blocks+1 );
- Node **debug_defs = NEW_RESOURCE_ARRAY( Node*, spill_cnt );
- VectorSet **UP_entry= NEW_RESOURCE_ARRAY( VectorSet*, spill_cnt );
+ Node ***Reaches = NEW_SPLIT_ARRAY( Node**, _cfg._num_blocks+1 );
+ bool **UP = NEW_SPLIT_ARRAY( bool*, _cfg._num_blocks+1 );
+ Node **debug_defs = NEW_SPLIT_ARRAY( Node*, spill_cnt );
+ VectorSet **UP_entry= NEW_SPLIT_ARRAY( VectorSet*, spill_cnt );
// Initialize Reaches & UP
for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) {
- Reaches[bidx] = NEW_RESOURCE_ARRAY( Node*, spill_cnt );
- UP[bidx] = NEW_RESOURCE_ARRAY( bool, spill_cnt );
+ Reaches[bidx] = NEW_SPLIT_ARRAY( Node*, spill_cnt );
+ UP[bidx] = NEW_SPLIT_ARRAY( bool, spill_cnt );
Node **Reachblock = Reaches[bidx];
bool *UPblock = UP[bidx];
for( slidx = 0; slidx < spill_cnt; slidx++ ) {
@@ -517,9 +523,11 @@
}
}
+#undef NEW_SPLIT_ARRAY
+
// Initialize to array of empty vectorsets
for( slidx = 0; slidx < spill_cnt; slidx++ )
- UP_entry[slidx] = new VectorSet(Thread::current()->resource_area());
+ UP_entry[slidx] = new VectorSet(split_arena);
//----------PASS 1----------
//----------Propagation & Node Insertion Code----------
--- a/hotspot/src/share/vm/opto/runtime.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/opto/runtime.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -880,46 +880,6 @@
}
JRT_END
-//-----------------------------------------------------------------------------
-// implicit exception support.
-
-static void report_null_exception_in_code_cache(address exception_pc) {
- ResourceMark rm;
- CodeBlob* n = CodeCache::find_blob(exception_pc);
- if (n != NULL) {
- tty->print_cr("#");
- tty->print_cr("# HotSpot Runtime Error, null exception in generated code");
- tty->print_cr("#");
- tty->print_cr("# pc where exception happened = " INTPTR_FORMAT, exception_pc);
-
- if (n->is_nmethod()) {
- methodOop method = ((nmethod*)n)->method();
- tty->print_cr("# Method where it happened %s.%s ", Klass::cast(method->method_holder())->name()->as_C_string(), method->name()->as_C_string());
- tty->print_cr("#");
- if (ShowMessageBoxOnError && UpdateHotSpotCompilerFileOnError &&
- CompilerOracle::has_command_file()) {
- const char* title = "HotSpot Runtime Error";
- const char* question = "Do you want to exclude compilation of this method in future runs?";
- if (os::message_box(title, question)) {
- CompilerOracle::append_comment_to_file("");
- CompilerOracle::append_comment_to_file("Null exception in compiled code resulted in the following exclude");
- CompilerOracle::append_comment_to_file("");
- CompilerOracle::append_exclude_to_file(method);
- tty->print_cr("#");
- tty->print_cr("# %s has been updated to exclude the specified method", CompileCommandFile);
- tty->print_cr("#");
- }
- }
- fatal("Implicit null exception happened in compiled method");
- } else {
- n->print();
- fatal("Implicit null exception happened in generated stub");
- }
- }
- fatal("Implicit null exception at wrong place");
-}
-
-
//-------------------------------------------------------------------------------------
// register policy
--- a/hotspot/src/share/vm/runtime/arguments.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -1916,7 +1916,7 @@
(ExplicitGCInvokesConcurrent ||
ExplicitGCInvokesConcurrentAndUnloadsClasses)) {
jio_fprintf(defaultStream::error_stream(),
- "error: +ExplictGCInvokesConcurrent[AndUnloadsClasses] conflicts"
+ "error: +ExplicitGCInvokesConcurrent[AndUnloadsClasses] conflicts"
" with -UseAsyncConcMarkSweepGC");
status = false;
}
--- a/hotspot/src/share/vm/runtime/globals.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -43,7 +43,6 @@
#include "shark/shark_globals.hpp"
#endif
-
RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \
MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \
@@ -55,6 +54,10 @@
MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
+ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, \
+ MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \
+ MATERIALIZE_NOTPRODUCT_FLAG)
+
MATERIALIZE_FLAGS_EXT
@@ -212,7 +215,6 @@
#define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1 notproduct}", DEFAULT },
#endif
-
#define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 product}", DEFAULT },
#define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 pd product}", DEFAULT },
#define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 diagnostic}", DEFAULT },
@@ -227,6 +229,17 @@
#define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2 notproduct}", DEFAULT },
#endif
+#define ARCH_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH product}", DEFAULT },
+#define ARCH_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH diagnostic}", DEFAULT },
+#define ARCH_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH experimental}", DEFAULT },
+#ifdef PRODUCT
+ #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
+ #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
+#else
+ #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH}", DEFAULT },
+ #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH notproduct}", DEFAULT },
+#endif
+
#define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark product}", DEFAULT },
#define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark pd product}", DEFAULT },
#define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark diagnostic}", DEFAULT },
@@ -255,6 +268,7 @@
#ifdef SHARK
SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, SHARK_PD_DEVELOP_FLAG_STRUCT, SHARK_PRODUCT_FLAG_STRUCT, SHARK_PD_PRODUCT_FLAG_STRUCT, SHARK_DIAGNOSTIC_FLAG_STRUCT, SHARK_NOTPRODUCT_FLAG_STRUCT)
#endif
+ ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, ARCH_PRODUCT_FLAG_STRUCT, ARCH_DIAGNOSTIC_FLAG_STRUCT, ARCH_EXPERIMENTAL_FLAG_STRUCT, ARCH_NOTPRODUCT_FLAG_STRUCT)
FLAGTABLE_EXT
{0, NULL, NULL}
};
--- a/hotspot/src/share/vm/runtime/globals.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -530,12 +530,6 @@
product(intx, UseSSE, 99, \
"Highest supported SSE instructions set on x86/x64") \
\
- product(intx, UseAVX, 99, \
- "Highest supported AVX instructions set on x86/x64") \
- \
- product(intx, UseVIS, 99, \
- "Highest supported VIS instructions set on Sparc") \
- \
product(uintx, LargePageSizeInBytes, 0, \
"Large page size (0 to let VM choose the page size") \
\
@@ -572,10 +566,6 @@
product(bool, PrintVMQWaitTime, false, \
"Prints out the waiting time in VM operation queue") \
\
- develop(bool, BailoutToInterpreterForThrows, false, \
- "Compiled methods which throws/catches exceptions will be " \
- "deopt and intp.") \
- \
develop(bool, NoYieldsInMicrolock, false, \
"Disable yields in microlock") \
\
@@ -618,9 +608,6 @@
"inline Object::hashCode() native that is known to be part " \
"of base library DLL") \
\
- develop(bool, InlineObjectCopy, true, \
- "inline Object.clone and Arrays.copyOf[Range] intrinsics") \
- \
develop(bool, InlineNatives, true, \
"inline natives that are known to be part of base library DLL") \
\
@@ -633,31 +620,9 @@
develop(bool, InlineThreadNatives, true, \
"inline Thread.currentThread, etc") \
\
- develop(bool, InlineReflectionGetCallerClass, true, \
- "inline sun.reflect.Reflection.getCallerClass(), known to be part "\
- "of base library DLL") \
- \
develop(bool, InlineUnsafeOps, true, \
"inline memory ops (native methods) from sun.misc.Unsafe") \
\
- develop(bool, ConvertCmpD2CmpF, true, \
- "Convert cmpD to cmpF when one input is constant in float range") \
- \
- develop(bool, ConvertFloat2IntClipping, true, \
- "Convert float2int clipping idiom to integer clipping") \
- \
- develop(bool, SpecialStringCompareTo, true, \
- "special version of string compareTo") \
- \
- develop(bool, SpecialStringIndexOf, true, \
- "special version of string indexOf") \
- \
- develop(bool, SpecialStringEquals, true, \
- "special version of string equals") \
- \
- develop(bool, SpecialArraysEquals, true, \
- "special version of Arrays.equals(char[],char[])") \
- \
product(bool, CriticalJNINatives, true, \
"check for critical JNI entry points") \
\
@@ -667,9 +632,6 @@
product(bool, UseSSE42Intrinsics, false, \
"SSE4.2 versions of intrinsics") \
\
- product(bool, UseCondCardMark, false, \
- "Check for already marked card before updating card table") \
- \
develop(bool, TraceCallFixup, false, \
"traces all call fixups") \
\
@@ -756,9 +718,6 @@
develop(bool, ForceFloatExceptions, trueInDebug, \
"Force exceptions on FP stack under/overflow") \
\
- develop(bool, SoftMatchFailure, trueInProduct, \
- "If the DFA fails to match a node, print a message and bail out") \
- \
develop(bool, VerifyStackAtCalls, false, \
"Verify that the stack pointer is unchanged after calls") \
\
@@ -915,15 +874,6 @@
"1: allow scavenging from the code cache; " \
"2: emit as many constants as the compiler can see") \
\
- diagnostic(bool, TraceOSRBreakpoint, false, \
- "Trace OSR Breakpoint ") \
- \
- diagnostic(bool, TraceCompileTriggered, false, \
- "Trace compile triggered") \
- \
- diagnostic(bool, TraceTriggers, false, \
- "Trace triggers") \
- \
product(bool, AlwaysRestoreFPU, false, \
"Restore the FPU control word after every JNI call (expensive)") \
\
@@ -1037,9 +987,6 @@
develop(bool, UsePrivilegedStack, true, \
"Enable the security JVM functions") \
\
- develop(bool, IEEEPrecision, true, \
- "Enables IEEE precision (for INTEL only)") \
- \
develop(bool, ProtectionDomainVerification, true, \
"Verifies protection domain before resolution in system " \
"dictionary") \
@@ -1109,8 +1056,6 @@
"(Unsafe,Unstable) " \
" Controls emission of inline sync fast-path code") \
\
- product(intx, AlwaysInflate, 0, "(Unstable) Force inflation") \
- \
product(intx, MonitorBound, 0, "Bound Monitor population") \
\
product(bool, MonitorInUseLists, false, "Track Monitors for Deflation") \
@@ -1118,9 +1063,6 @@
product(intx, Atomics, 0, \
"(Unsafe,Unstable) Diagnostic - Controls emission of atomics") \
\
- product(intx, FenceInstruction, 0, \
- "(Unsafe,Unstable) Experimental") \
- \
product(intx, SyncFlags, 0, "(Unsafe,Unstable) Experimental Sync flags" ) \
\
product(intx, SyncVerbose, 0, "(Unstable)" ) \
@@ -1150,10 +1092,6 @@
"call thr_setconcurrency at thread create time to avoid " \
"LWP starvation on MP systems (For Solaris Only)") \
\
- develop(bool, UpdateHotSpotCompilerFileOnError, true, \
- "Should the system attempt to update the compiler file when " \
- "an error occurs?") \
- \
product(bool, ReduceSignalUsage, false, \
"Reduce the use of OS signals in Java and/or the VM") \
\
@@ -1188,15 +1126,6 @@
"Use alternate signals instead of SIGUSR1 & SIGUSR2 for VM " \
"internal signals (Solaris only)") \
\
- product(bool, UseSpinning, false, \
- "Use spinning in monitor inflation and before entry") \
- \
- product(bool, PreSpinYield, false, \
- "Yield before inner spinning loop") \
- \
- product(bool, PostSpinYield, true, \
- "Yield after inner spinning loop") \
- \
product(bool, AllowJNIEnvProxy, false, \
"Allow JNIEnv proxies for jdbx") \
\
@@ -1225,39 +1154,9 @@
product(bool, LazyBootClassLoader, true, \
"Enable/disable lazy opening of boot class path entries") \
\
- diagnostic(bool, UseIncDec, true, \
- "Use INC, DEC instructions on x86") \
- \
- product(bool, UseNewLongLShift, false, \
- "Use optimized bitwise shift left") \
- \
- product(bool, UseStoreImmI16, true, \
- "Use store immediate 16-bits value instruction on x86") \
- \
- product(bool, UseAddressNop, false, \
- "Use '0F 1F [addr]' NOP instructions on x86 cpus") \
- \
- product(bool, UseXmmLoadAndClearUpper, true, \
- "Load low part of XMM register and clear upper part") \
- \
- product(bool, UseXmmRegToRegMoveAll, false, \
- "Copy all XMM register bits when moving value between registers") \
- \
- product(bool, UseXmmI2D, false, \
- "Use SSE2 CVTDQ2PD instruction to convert Integer to Double") \
- \
- product(bool, UseXmmI2F, false, \
- "Use SSE2 CVTDQ2PS instruction to convert Integer to Float") \
- \
product(bool, UseXMMForArrayCopy, false, \
"Use SSE2 MOVQ instruction for Arraycopy") \
\
- product(bool, UseUnalignedLoadStores, false, \
- "Use SSE2 MOVDQU instruction for Arraycopy") \
- \
- product(bool, UseCBCond, false, \
- "Use compare and branch instruction on SPARC") \
- \
product(intx, FieldsAllocationStyle, 1, \
"0 - type based with oops first, 1 - with oops last, " \
"2 - oops in super and sub classes are together") \
@@ -1387,9 +1286,6 @@
develop(bool, TraceStartupTime, false, \
"Trace setup time") \
\
- product(ccstr, HPILibPath, NULL, \
- "Specify alternate path to HPI library") \
- \
develop(bool, TraceProtectionDomainVerification, false, \
"Trace protection domain verifcation") \
\
@@ -1405,10 +1301,6 @@
product(bool, TraceMonitorInflation, false, \
"Trace monitor inflation in JVM") \
\
- /* assembler */ \
- product(bool, Use486InstrsOnly, false, \
- "Use 80486 Compliant instruction subset") \
- \
/* gc */ \
\
product(bool, UseSerialGC, false, \
@@ -1467,9 +1359,6 @@
develop(uintx, ParallelOldGCSplitInterval, 3, \
"How often to provoke splitting a young gen space") \
\
- develop(bool, TraceRegionTasksQueuing, false, \
- "Trace the queuing of the region tasks") \
- \
product(uintx, ConcGCThreads, 0, \
"Number of threads concurrent gc will use") \
\
@@ -1621,10 +1510,6 @@
"The gain in the feedback loop for on-the-fly PLAB resizing" \
" during a scavenge") \
\
- product(uintx, CMSOldPLABReactivityCeiling, 10, \
- "The clamping of the gain in the feedback loop for on-the-fly" \
- " PLAB resizing during a scavenge") \
- \
product(bool, AlwaysPreTouch, false, \
"It forces all freshly committed pages to be pre-touched.") \
\
@@ -1632,12 +1517,6 @@
"The maximum size of young gen chosen by default per GC worker " \
"thread available") \
\
- product(bool, GCOverheadReporting, false, \
- "Enables the GC overhead reporting facility") \
- \
- product(intx, GCOverheadReportingPeriodMS, 100, \
- "Reporting period for conc GC overhead reporting, in ms ") \
- \
product(bool, CMSIncrementalMode, false, \
"Whether CMS GC should operate in \"incremental\" mode") \
\
@@ -2017,9 +1896,6 @@
experimental(uintx, WorkStealingSpinToYieldRatio, 10, \
"Ratio of hard spins to calls to yield") \
\
- product(uintx, PreserveMarkStackSize, 1024, \
- "Size for stack used in promotion failure handling") \
- \
develop(uintx, ObjArrayMarkingStride, 512, \
"Number of ObjArray elements to push onto the marking stack" \
"before pushing a continuation entry") \
@@ -2044,18 +1920,6 @@
product(bool, TLABStats, true, \
"Print various TLAB related information") \
\
- product(bool, UseBlockZeroing, false, \
- "Use special cpu instructions for block zeroing") \
- \
- product(intx, BlockZeroingLowLimit, 2048, \
- "Minimum size in bytes when block zeroing will be used") \
- \
- product(bool, UseBlockCopy, false, \
- "Use special cpu instructions for block copy") \
- \
- product(intx, BlockCopyLowLimit, 2048, \
- "Minimum size in bytes when block copy will be used") \
- \
product(bool, PrintRevisitStats, false, \
"Print revisit (klass and MDO) stack related information") \
\
@@ -2248,9 +2112,6 @@
product(intx, PrefetchFieldsAhead, -1, \
"How many fields ahead to prefetch in oop scan (<= 0 means off)") \
\
- develop(bool, UsePrefetchQueue, true, \
- "Use the prefetch queue during PS promotion") \
- \
diagnostic(bool, VerifyBeforeExit, trueInDebug, \
"Verify system before exiting") \
\
@@ -2486,27 +2347,9 @@
develop(bool, CITraceTypeFlow, false, \
"detailed per-bytecode tracing of ciTypeFlow analysis") \
\
- develop(intx, CICloneLoopTestLimit, 100, \
- "size limit for blocks heuristically cloned in ciTypeFlow") \
- \
develop(intx, OSROnlyBCI, -1, \
"OSR only at this bci. Negative values mean exclude that bci") \
\
- /* temp diagnostics */ \
- \
- diagnostic(bool, TraceRedundantCompiles, false, \
- "Have compile broker print when a request already in the queue is"\
- " requested again") \
- \
- diagnostic(bool, InitialCompileFast, false, \
- "Initial compile at CompLevel_fast_compile") \
- \
- diagnostic(bool, InitialCompileReallyFast, false, \
- "Initial compile at CompLevel_really_fast_compile (no profile)") \
- \
- diagnostic(bool, FullProfileOnReInterpret, true, \
- "On re-interpret unc-trap compile next at CompLevel_fast_compile")\
- \
/* compiler */ \
\
product(intx, CICompilerCount, CI_COMPILER_COUNT, \
@@ -2520,12 +2363,6 @@
"proper StackOverflow handling; disable only to measure cost " \
"of stackbanging)") \
\
- develop(bool, Use24BitFPMode, true, \
- "Set 24-bit FPU mode on a per-compile basis ") \
- \
- develop(bool, Use24BitFP, true, \
- "use FP instructions that produce 24-bit precise results") \
- \
develop(bool, UseStrictFP, true, \
"use strict fp if modifier strictfp is set") \
\
@@ -2557,9 +2394,6 @@
"print the break down of clean up tasks performed during" \
" safepoint") \
\
- develop(bool, InlineAccessors, true, \
- "inline accessor methods (get/set)") \
- \
product(bool, Inline, true, \
"enable inlining") \
\
@@ -2572,33 +2406,15 @@
product(bool, UseTypeProfile, true, \
"Check interpreter profile for historically monomorphic calls") \
\
- product(intx, TypeProfileMajorReceiverPercent, 90, \
- "% of major receiver type to all profiled receivers") \
- \
notproduct(bool, TimeCompiler, false, \
"time the compiler") \
\
- notproduct(bool, TimeCompiler2, false, \
- "detailed time the compiler (requires +TimeCompiler)") \
- \
diagnostic(bool, PrintInlining, false, \
"prints inlining optimizations") \
\
- diagnostic(bool, PrintIntrinsics, false, \
- "prints attempted and successful inlining of intrinsics") \
- \
- product(bool, UseCountLeadingZerosInstruction, false, \
- "Use count leading zeros instruction") \
- \
product(bool, UsePopCountInstruction, false, \
"Use population count instruction") \
\
- diagnostic(ccstrlist, DisableIntrinsic, "", \
- "do not expand intrinsics whose (internal) names appear here") \
- \
- develop(bool, StressReflectiveCode, false, \
- "Use inexact types at allocations, etc., to test reflection") \
- \
develop(bool, EagerInitialization, false, \
"Eagerly initialize classes if possible") \
\
@@ -2608,10 +2424,6 @@
develop(bool, PrintMethodFlushing, false, \
"print the nmethods being flushed") \
\
- notproduct(bool, LogMultipleMutexLocking, false, \
- "log locking and unlocking of mutexes (only if multiple locks " \
- "are held)") \
- \
develop(bool, UseRelocIndex, false, \
"use an index to speed random access to relocations") \
\
@@ -2621,9 +2433,6 @@
diagnostic(bool, DebugNonSafepoints, trueInDebug, \
"Generate extra debugging info for non-safepoints in nmethods") \
\
- diagnostic(bool, DebugInlinedCalls, true, \
- "If false, restricts profiled locations to the root method only") \
- \
product(bool, PrintVMOptions, false, \
"Print flags that appeared on the command line") \
\
@@ -2700,9 +2509,6 @@
notproduct(bool, IgnoreLockingAssertions, false, \
"disable locking assertions (for speed)") \
\
- notproduct(bool, VerifyLoopOptimizations, false, \
- "verify major loop optimizations") \
- \
product(bool, RangeCheckElimination, true, \
"Split loop iterations to eliminate range checks") \
\
@@ -2712,12 +2518,6 @@
develop(bool, TypeProfileCasts, true, \
"treat casts like calls for purposes of type profiling") \
\
- develop(bool, MonomorphicArrayCheck, true, \
- "Uncommon-trap array store checks that require full type check") \
- \
- diagnostic(bool, ProfileDynamicTypes, true, \
- "do extra type profiling and use it more aggressively") \
- \
develop(bool, DelayCompilationDuringStartup, true, \
"Delay invoking the compiler until main application class is " \
"loaded") \
@@ -2732,19 +2532,9 @@
notproduct(intx, CompileTheWorldSafepointInterval, 100, \
"Force a safepoint every n compiles so sweeper can keep up") \
\
- develop(bool, TraceIterativeGVN, false, \
- "Print progress during Iterative Global Value Numbering") \
- \
develop(bool, FillDelaySlots, true, \
"Fill delay slots (on SPARC only)") \
\
- develop(bool, VerifyIterativeGVN, false, \
- "Verify Def-Use modifications during sparse Iterative Global " \
- "Value Numbering") \
- \
- notproduct(bool, TracePhaseCCP, false, \
- "Print progress during Conditional Constant Propagation") \
- \
develop(bool, TimeLivenessAnalysis, false, \
"Time computation of bytecode liveness analysis") \
\
@@ -2757,22 +2547,9 @@
notproduct(bool, CollectIndexSetStatistics, false, \
"Collect information about IndexSets") \
\
- develop(bool, PrintDominators, false, \
- "Print out dominator trees for GVN") \
- \
develop(bool, UseLoopSafepoints, true, \
"Generate Safepoint nodes in every loop") \
\
- notproduct(bool, TraceCISCSpill, false, \
- "Trace allocators use of cisc spillable instructions") \
- \
- notproduct(bool, TraceSpilling, false, \
- "Trace spilling") \
- \
- product(bool, SplitIfBlocks, true, \
- "Clone compares and control flow through merge points to fold " \
- "some branches") \
- \
develop(intx, FastAllocateSizeLimit, 128*K, \
/* Note: This value is zero mod 1<<13 for a cheap sparc set. */ \
"Inline allocations larger than this in doublewords must go slow")\
@@ -2829,15 +2606,6 @@
develop(bool, UseFastSignatureHandlers, true, \
"Use fast signature handlers for native calls") \
\
- develop(bool, UseV8InstrsOnly, false, \
- "Use SPARC-V8 Compliant instruction subset") \
- \
- product(bool, UseNiagaraInstrs, false, \
- "Use Niagara-efficient instruction subset") \
- \
- develop(bool, UseCASForSwap, false, \
- "Do not use swap instructions, but only CAS (in a loop) on SPARC")\
- \
product(bool, UseLoopCounter, true, \
"Increment invocation counter on backward branch") \
\
@@ -2854,9 +2622,6 @@
notproduct(bool, TraceOnStackReplacement, false, \
"Trace on stack replacement") \
\
- develop(bool, PoisonOSREntry, true, \
- "Detect abnormal calls to OSR code") \
- \
product_pd(bool, PreferInterpreterNativeStubs, \
"Use always interpreter stubs for native methods invoked via " \
"interpreter") \
@@ -2899,9 +2664,6 @@
develop(bool, TraceFrequencyInlining, false, \
"Trace frequency based inlining") \
\
- notproduct(bool, TraceTypeProfile, false, \
- "Trace type profile") \
- \
develop_pd(bool, InlineIntrinsics, \
"Inline intrinsics that can be statically resolved") \
\
@@ -2989,15 +2751,6 @@
product(intx, AllocatePrefetchInstr, 0, \
"Prefetch instruction to prefetch ahead of allocation pointer") \
\
- product(intx, ReadPrefetchInstr, 0, \
- "Prefetch instruction to prefetch ahead") \
- \
- product(uintx, ArraycopySrcPrefetchDistance, 0, \
- "Distance to prefetch source array in arracopy") \
- \
- product(uintx, ArraycopyDstPrefetchDistance, 0, \
- "Distance to prefetch destination array in arracopy") \
- \
/* deoptimization */ \
develop(bool, TraceDeoptimization, false, \
"Trace deoptimization") \
@@ -3088,9 +2841,6 @@
product(intx, MinInliningThreshold, 250, \
"min. invocation count a method needs to have to be inlined") \
\
- develop(intx, AlignEntryCode, 4, \
- "aligns entry code to specified value (in bytes)") \
- \
develop(intx, MethodHistogramCutoff, 100, \
"cutoff value for method invoc. histogram (+CountCalls)") \
\
@@ -3130,9 +2880,6 @@
"Minimum sleep() interval (milliseconds) when " \
"ConvertSleepToYield is off (used for SOLARIS)") \
\
- product(intx, EventLogLength, 2000, \
- "maximum nof events in event log") \
- \
develop(intx, ProfilerPCTickThreshold, 15, \
"Number of ticks in a PC buckets to be a hotspot") \
\
@@ -3171,9 +2918,6 @@
product(intx, PerBytecodeTrapLimit, 4, \
"Limit on traps (of one kind) at a particular BCI") \
\
- develop(intx, FreqCountInvocations, 1, \
- "Scaling factor for branch frequencies (deprecated)") \
- \
develop(intx, InlineFrequencyRatio, 20, \
"Ratio of call site execution to caller method invocation") \
\
@@ -3187,29 +2931,12 @@
develop(intx, InlineThrowMaxSize, 200, \
"Force inlining of throwing methods smaller than this") \
\
- product(intx, AliasLevel, 3, \
- "0 for no aliasing, 1 for oop/field/static/array split, " \
- "2 for class split, 3 for unique instances") \
- \
- develop(bool, VerifyAliases, false, \
- "perform extra checks on the results of alias analysis") \
- \
develop(intx, ProfilerNodeSize, 1024, \
"Size in K to allocate for the Profile Nodes of each thread") \
\
- develop(intx, V8AtomicOperationUnderLockSpinCount, 50, \
- "Number of times to spin wait on a v8 atomic operation lock") \
- \
- product(intx, ReadSpinIterations, 100, \
- "Number of read attempts before a yield (spin inner loop)") \
- \
product_pd(intx, PreInflateSpin, \
"Number of times to spin wait before inflation") \
\
- product(intx, PreBlockSpin, 10, \
- "Number of times to spin in an inflated lock before going to " \
- "an OS lock") \
- \
/* gc parameters */ \
product(uintx, InitialHeapSize, 0, \
"Initial heap size (in bytes); zero means OldSize + NewSize") \
@@ -3466,10 +3193,6 @@
"(non-negative value throws OOM after this many CI accesses " \
"in each compile)") \
\
- develop(intx, CIFireOOMAtDelay, -1, \
- "Wait for this many CI accesses to occur in all compiles before " \
- "beginning to throw OutOfMemoryErrors in each compile") \
- \
notproduct(bool, CIObjectFactoryVerify, false, \
"enable potentially expensive verification in ciObjectFactory") \
\
@@ -3663,9 +3386,6 @@
product(bool, PrintTieredEvents, false, \
"Print tiered events notifications") \
\
- product(bool, StressTieredRuntime, false, \
- "Alternate client and server compiler on compile requests") \
- \
product_pd(intx, OnStackReplacePercentage, \
"NON_TIERED number of method invocations/branches (expressed as %"\
"of CompileThreshold) before (re-)compiling OSR code") \
@@ -3835,9 +3555,6 @@
"support JSR 292 (method handles, invokedynamic, " \
"anonymous classes") \
\
- product(bool, AnonymousClasses, false, \
- "support sun.misc.Unsafe.defineAnonymousClass (deprecated)") \
- \
diagnostic(bool, PrintMethodHandleStubs, false, \
"Print generated stub code for method handles") \
\
@@ -3952,6 +3669,8 @@
RUNTIME_OS_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
+ARCH_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
+
// Extensions
#include "runtime/globals_ext.hpp"
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -66,7 +66,6 @@
#define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#endif
-
#define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc) FLAG_MEMBER(name),
#define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
@@ -81,6 +80,17 @@
#define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
#endif
+#define ARCH_PRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
+#define ARCH_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
+#define ARCH_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
+#ifdef PRODUCT
+ #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc) /* flag is constant */
+ #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
+#else
+ #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
+ #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc) FLAG_MEMBER(name),
+#endif
+
typedef enum {
RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER, RUNTIME_LP64_PRODUCT_FLAG_MEMBER)
RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER)
@@ -93,6 +103,7 @@
#ifdef COMPILER2
C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, C2_PD_DEVELOP_FLAG_MEMBER, C2_PRODUCT_FLAG_MEMBER, C2_PD_PRODUCT_FLAG_MEMBER, C2_DIAGNOSTIC_FLAG_MEMBER, C2_EXPERIMENTAL_FLAG_MEMBER, C2_NOTPRODUCT_FLAG_MEMBER)
#endif
+ ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER, ARCH_PRODUCT_FLAG_MEMBER, ARCH_DIAGNOSTIC_FLAG_MEMBER, ARCH_EXPERIMENTAL_FLAG_MEMBER, ARCH_NOTPRODUCT_FLAG_MEMBER)
COMMANDLINEFLAG_EXT
NUM_CommandLineFlag
} CommandLineFlag;
@@ -134,7 +145,6 @@
#define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */
#endif // _LP64
-
#define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
@@ -149,6 +159,17 @@
#define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
#endif
+#define ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
+#define ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
+#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
+#ifdef PRODUCT
+ #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) /* flag is constant */
+ #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
+#else
+ #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
+ #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc) FLAG_MEMBER_WITH_TYPE(name,type),
+#endif
+
typedef enum {
RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
@@ -193,6 +214,11 @@
C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
#endif
+ ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE,
+ ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE,
+ ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
+ ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
+ ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
COMMANDLINEFLAGWITHTYPE_EXT
NUM_CommandLineFlagWithType
} CommandLineFlagWithType;
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -2135,6 +2135,7 @@
/******************/ \
\
declare_constant(UseTLAB) \
+ declare_constant(EnableInvokeDynamic) \
\
/**************/ \
/* Stack bias */ \
--- a/hotspot/test/compiler/6894807/Test6894807.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/test/compiler/6894807/Test6894807.sh Fri Sep 14 10:14:02 2012 -0700
@@ -31,6 +31,11 @@
PS=";"
FS="\\"
;;
+ CYGWIN_* )
+ NULL=/dev/null
+ PS=";"
+ FS="/"
+ ;;
* )
echo "Unrecognized system!"
exit 1;
--- a/hotspot/test/gc/6941923/test6941923.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/test/gc/6941923/test6941923.sh Fri Sep 14 10:14:02 2012 -0700
@@ -14,7 +14,7 @@
PS=":"
FS="/"
;;
- Windows_* )
+ Windows_* | CYGWIN_* )
echo "Test skipped for Windows"
exit 0
;;
--- a/hotspot/test/runtime/6626217/Test6626217.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/test/runtime/6626217/Test6626217.sh Fri Sep 14 10:14:02 2012 -0700
@@ -65,6 +65,14 @@
CP=cp
MV=mv
;;
+ CYGWIN_* )
+ NULL=/dev/null
+ PS=";"
+ FS="/"
+ RM=rm
+ CP=cp
+ MV=mv
+ ;;
* )
echo "Unrecognized system!"
exit 1;
--- a/hotspot/test/runtime/6878713/Test6878713.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/test/runtime/6878713/Test6878713.sh Fri Sep 14 10:14:02 2012 -0700
@@ -38,6 +38,11 @@
PS=";"
FS="\\"
;;
+ CYGWIN_* )
+ NULL=/dev/null
+ PS=";"
+ FS="/"
+ ;;
* )
echo "Unrecognized system!"
exit 1;
--- a/hotspot/test/runtime/7020373/Test7020373.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/test/runtime/7020373/Test7020373.sh Fri Sep 14 10:14:02 2012 -0700
@@ -40,6 +40,11 @@
PS=";"
FS="\\"
;;
+ CYGWIN_* )
+ NULL=/dev/null
+ PS=";"
+ FS="/"
+ ;;
* )
echo "Unrecognized system!"
exit 1;
--- a/hotspot/test/runtime/7051189/Xchecksig.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/test/runtime/7051189/Xchecksig.sh Fri Sep 14 10:14:02 2012 -0700
@@ -46,7 +46,7 @@
SunOS | Linux | Darwin )
FS="/"
;;
- Windows_* )
+ Windows_* | CYGWIN_* )
printf "Not testing libjsig.so on Windows. PASSED.\n "
exit 0
;;
--- a/hotspot/test/runtime/7110720/Test7110720.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/test/runtime/7110720/Test7110720.sh Fri Sep 14 10:14:02 2012 -0700
@@ -55,6 +55,12 @@
CP=cp
MV=mv
;;
+ CYGWIN_* )
+ FS="/"
+ RM=rm
+ CP=cp
+ MV=mv
+ ;;
* )
echo "Unrecognized system!"
exit 1;
--- a/hotspot/test/runtime/7158800/Test7158800.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/test/runtime/7158800/Test7158800.sh Fri Sep 14 10:14:02 2012 -0700
@@ -56,6 +56,11 @@
PS=";"
FS="\\"
;;
+ CYGWIN_* )
+ NULL=/dev/null
+ PS=";"
+ FS="/"
+ ;;
* )
echo "Unrecognized system!"
exit 1;
--- a/hotspot/test/runtime/7158988/TestFieldMonitor.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/hotspot/test/runtime/7158988/TestFieldMonitor.sh Fri Sep 14 10:14:02 2012 -0700
@@ -38,6 +38,18 @@
PS=";"
FS="\\"
;;
+ CYGWIN_NT* )
+ NULL=/dev/null
+ PS=";"
+ FS="/"
+ ;;
+ CYGWIN_* )
+ NULL=/dev/null
+ PS=";"
+ FS="/"
+ echo "Test skipped, only for WinNT"
+ exit 0
+ ;;
* )
echo "Unrecognized system!"
exit 1;
--- a/jaxp/.hgtags Fri Sep 14 09:47:14 2012 -0700
+++ b/jaxp/.hgtags Fri Sep 14 10:14:02 2012 -0700
@@ -175,3 +175,5 @@
dc1ea77ed9d9746e0f98bb1268987c3596c8b4b5 jdk8-b51
bd3c00d5761408954cc29ffb82016a76cbc90b43 jdk8-b52
2c566f25c39f0087464b73e3bcf1c1421d0f2a7e jdk8-b53
+7dd81ccb7c1134df70969b3068b1e98def701746 jdk8-b54
+7c2363666890c6675194948fbcd74d81ddb84298 jdk8-b55
--- a/jaxp/src/javax/xml/stream/XMLEventFactory.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jaxp/src/javax/xml/stream/XMLEventFactory.java Fri Sep 14 10:14:02 2012 -0700
@@ -49,6 +49,10 @@
public abstract class XMLEventFactory {
protected XMLEventFactory(){}
+ static final String JAXPFACTORYID = "javax.xml.stream.XMLEventFactory";
+ static final String DEFAULIMPL = "com.sun.xml.internal.stream.events.XMLEventFactoryImpl";
+
+
/**
* Create a new instance of the factory
* @throws FactoryConfigurationError if an instance of this factory cannot be loaded
@@ -57,8 +61,8 @@
throws FactoryConfigurationError
{
return (XMLEventFactory) FactoryFinder.find(
- "javax.xml.stream.XMLEventFactory",
- "com.sun.xml.internal.stream.events.XMLEventFactoryImpl");
+ JAXPFACTORYID,
+ DEFAULIMPL);
}
/**
@@ -90,8 +94,8 @@
throws FactoryConfigurationError
{
return (XMLEventFactory) FactoryFinder.find(
- "javax.xml.stream.XMLEventFactory",
- "com.sun.xml.internal.stream.events.XMLEventFactoryImpl");
+ JAXPFACTORYID,
+ DEFAULIMPL);
}
/**
@@ -114,7 +118,7 @@
throws FactoryConfigurationError {
try {
//do not fallback if given classloader can't find the class, throw exception
- return (XMLEventFactory) FactoryFinder.newInstance(factoryId, classLoader, false);
+ return (XMLEventFactory) FactoryFinder.find(factoryId, classLoader, null);
} catch (FactoryFinder.ConfigurationError e) {
throw new FactoryConfigurationError(e.getException(),
e.getMessage());
@@ -141,7 +145,7 @@
throws FactoryConfigurationError {
try {
//do not fallback if given classloader can't find the class, throw exception
- return (XMLEventFactory) FactoryFinder.newInstance(factoryId, classLoader, false);
+ return (XMLEventFactory) FactoryFinder.find(factoryId, classLoader, null);
} catch (FactoryFinder.ConfigurationError e) {
throw new FactoryConfigurationError(e.getException(),
e.getMessage());
--- a/jaxws/.hgtags Fri Sep 14 09:47:14 2012 -0700
+++ b/jaxws/.hgtags Fri Sep 14 10:14:02 2012 -0700
@@ -175,3 +175,5 @@
1a70b6333ebe12e1c6dbca30e58bc1ba894ab898 jdk8-b51
f62bc618122e87a8bea69865cc02074e9d850426 jdk8-b52
8a35fd644d3c0b75813ff0236adef8a1c6f895c6 jdk8-b53
+91970935926a20f19a5cbbf20931745ac1975e91 jdk8-b54
+109c9e1f2d8546e9954e1b7be9a37a4396434544 jdk8-b55
--- a/jdk/.hgtags Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/.hgtags Fri Sep 14 10:14:02 2012 -0700
@@ -176,3 +176,5 @@
e8569a473cee7f4955bd9e76a9bdf6c6a07ced27 jdk8-b52
2c6933c5106b81a8578b70996fe5b735fb3adb60 jdk8-b53
70ad0ed1d6cef0e7712690d1bab21e4769708aad jdk8-b54
+1f3f4b333341873f00da3dee85e4879f0e89c9bb jdk8-b55
+2e9eeef2909b33c9224a024afddb61ccb0b77f14 jdk8-b56
--- a/jdk/make/common/Defs.gmk Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/make/common/Defs.gmk Fri Sep 14 10:14:02 2012 -0700
@@ -542,6 +542,21 @@
CXXFLAGS_$(VARIANT)/BYFILE = $(CXXFLAGS_$(VARIANT)/$(@F)) \
$(CXXFLAGS_$(VARIANT)$(CXXFLAGS_$(VARIANT)/$(@F)))
+# Command line define to provide basename of file being compiled to source.
+# The C macro THIS_FILE can replace the use of __FILE__ in the source
+# files for the current filename being compiled.
+# The value of the __FILE__ macro is unpredictable and can be anything
+# from a relative path to a full path, THIS_FILE will be more consistent..
+# The THIS_FILE macro will always be just the basename of the file being
+# compiled.
+# Different string literals in the the object files makes it difficult to
+# compare shared libraries from different builds.
+#
+# NOTE: If the THIS_FILE macro is actually expanded while in an included
+# source file, it will not return the name of the included file.
+#
+CPP_THIS_FILE = -DTHIS_FILE='"$(<F)"'
+
#
# Tool flags
#
@@ -551,7 +566,7 @@
CFLAGS = $(CFLAGS_$(VARIANT)/BYFILE) $(CFLAGS_COMMON) $(OTHER_CFLAGS) $(EXTRA_CFLAGS)
CXXFLAGS = $(CXXFLAGS_$(VARIANT)/BYFILE) $(CXXFLAGS_COMMON) $(OTHER_CXXFLAGS) $(EXTRA_CFLAGS)
CPPFLAGS = $(CPPFLAGS_$(VARIANT)) $(CPPFLAGS_COMMON) $(OTHER_CPPFLAGS) \
- $(DEFINES) $(OPTIONS:%=-D%)
+ $(DEFINES) $(OPTIONS:%=-D%) $(CPP_THIS_FILE)
LDFLAGS = $(LDFLAGS_$(VARIANT)) $(LDFLAGS_COMMON) $(OTHER_LDFLAGS)
LDLIBS = $(OTHER_LDLIBS) $(LDLIBS_$(VARIANT)) $(LDLIBS_COMMON)
LINTFLAGS = $(LINTFLAGS_$(VARIANT)) $(LINTFLAGS_COMMON) \
--- a/jdk/make/common/Demo.gmk Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/make/common/Demo.gmk Fri Sep 14 10:14:02 2012 -0700
@@ -320,10 +320,10 @@
ifeq ($(PLATFORM),windows)
$(RC) $(RC_FLAGS) $(CC_OBJECT_OUTPUT_FLAG)$(DEMO_VERSION_INFO) $(VERSIONINFO_RESOURCE)
$(LINK.demo) $(SHARED_LIBRARY_FLAG) -Fe$@ \
- $(DEMO_FULL_OBJECTS) $(LDLIBS.demo)
+ $(sort $(DEMO_FULL_OBJECTS)) $(LDLIBS.demo)
else
$(LINK.demo) $(SHARED_LIBRARY_FLAG) -o $@ \
- $(DEMO_FULL_OBJECTS) $(LDLIBS.demo)
+ $(sort $(DEMO_FULL_OBJECTS)) $(LDLIBS.demo)
endif
@$(call binary_file_verification,$@)
--- a/jdk/make/common/Library.gmk Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/make/common/Library.gmk Fri Sep 14 10:14:02 2012 -0700
@@ -199,7 +199,7 @@
$(OBJDIR)/$(LIBRARY).lcf: $(OBJDIR)/$(LIBRARY).res $(COMPILE_FILES_o) $(FILES_m)
@$(prep-target)
@$(MKDIR) -p $(TEMPDIR)
- @$(ECHO) $(FILES_o) > $@
+ @$(ECHO) $(sort $(FILES_o)) > $@
ifndef LOCAL_RESOURCE_FILE
@$(ECHO) $(OBJDIR)/$(LIBRARY).res >> $@
endif
@@ -256,9 +256,9 @@
@$(ECHO) "STATS: LIBRARY=$(LIBRARY), PRODUCT=$(PRODUCT), OPTIMIZATION_LEVEL=$(OPTIMIZATION_LEVEL)"
@$(ECHO) "Rebuilding $@ because of $?"
ifeq ($(LIBRARY), fdlibm)
- $(AR) $(ARFLAGS) $@ $(FILES_o)
+ $(AR) $(ARFLAGS) $@ $(sort $(FILES_o))
else # LIBRARY
- $(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(FILES_o) $(LDLIBS)
+ $(LINKER) $(SHARED_LIBRARY_FLAG) -o $@ $(sort $(FILES_o)) $(LDLIBS)
@$(call binary_file_verification,$@)
ifeq ($(WRITE_LIBVERSION),true)
$(MCS) -d -a "$(FULL_VERSION)" $@
--- a/jdk/make/common/Program.gmk Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/make/common/Program.gmk Fri Sep 14 10:14:02 2012 -0700
@@ -262,7 +262,7 @@
$(ECHO) Rebuilding $@ because of $$1 $$2 $$3 $$4 $$5 $$6 $${7:+...};
@$(MKDIR) -p $(TEMPDIR)
$(LINK_PRE_CMD) $(CC) $(CC_OBJECT_OUTPUT_FLAG)$@ $(LDFLAGS) \
- $(FILES_o) $(THREADLIBS) $(LDLIBS)
+ $(sort $(FILES_o)) $(THREADLIBS) $(LDLIBS)
ifeq ($(findstring privileged, $(INFO_PLIST_FILE)), privileged)
-codesign -s openjdk_codesign $@
endif
@@ -392,8 +392,6 @@
VERSION_DEFINES += -DJDK_MAJOR_VERSION='"$(JDK_MAJOR_VERSION)"' \
-DJDK_MINOR_VERSION='"$(JDK_MINOR_VERSION)"'
-
-
$(OBJDIR)/main.$(OBJECT_SUFFIX): $(LAUNCHER_SHARE_SRC)/bin/main.c
@$(prep-target)
$(COMPILE.c) $(CC_OBJECT_OUTPUT_FLAG)$(OBJDIR)/main.$(OBJECT_SUFFIX) \
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -40,6 +40,7 @@
import java.awt.peer.ComponentPeer;
import java.awt.peer.ContainerPeer;
+import java.awt.peer.KeyboardFocusManagerPeer;
import java.util.concurrent.atomic.AtomicBoolean;
import java.lang.reflect.Field;
import java.security.AccessController;
@@ -894,15 +895,15 @@
", focusedWindowChangeAllowed=" + focusedWindowChangeAllowed +
", time= " + time + ", cause=" + cause);
}
- if (LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- processSynchronousLightweightTransfer(getTarget(), lightweightChild, temporary,
- focusedWindowChangeAllowed, time)) {
+ if (LWKeyboardFocusManagerPeer.processSynchronousLightweightTransfer(
+ getTarget(), lightweightChild, temporary,
+ focusedWindowChangeAllowed, time)) {
return true;
}
- int result = LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- shouldNativelyFocusHeavyweight(getTarget(), lightweightChild, temporary,
- focusedWindowChangeAllowed, time, cause);
+ int result = LWKeyboardFocusManagerPeer.shouldNativelyFocusHeavyweight(
+ getTarget(), lightweightChild, temporary,
+ focusedWindowChangeAllowed, time, cause);
switch (result) {
case LWKeyboardFocusManagerPeer.SNFH_FAILURE:
return false;
@@ -951,14 +952,13 @@
return false;
}
- LWComponentPeer focusOwnerPeer =
- LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- getFocusOwner();
- Component focusOwner = (focusOwnerPeer != null) ? focusOwnerPeer.getTarget() : null;
+ KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+ Component focusOwner = kfmPeer.getCurrentFocusOwner();
return LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
getTarget(), temporary,
focusedWindowChangeAllowed,
time, cause, focusOwner);
+
case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
return true;
}
@@ -1251,9 +1251,6 @@
if (!target.isFocusOwner() && LWKeyboardFocusManagerPeer.shouldFocusOnClick(target)) {
LWKeyboardFocusManagerPeer.requestFocusFor(target, CausedFocusEvent.Cause.MOUSE_EVENT);
- } else {
- // Anyway request focus to the toplevel.
- getWindowPeerOrSelf().requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
}
}
@@ -1263,8 +1260,8 @@
protected void handleJavaFocusEvent(FocusEvent e) {
// Note that the peer receives all the FocusEvents from
// its lightweight children as well
- LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- setFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? this : null);
+ KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+ kfmPeer.setCurrentFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? getTarget() : null);
}
/**
--- a/jdk/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -26,85 +26,47 @@
package sun.lwawt;
import java.awt.Component;
-import java.awt.KeyboardFocusManager;
import java.awt.Window;
-
-import java.util.Map;
-import java.util.HashMap;
-
-import sun.awt.AWTAccessor;
-import sun.awt.AppContext;
import sun.awt.KeyboardFocusManagerPeerImpl;
public class LWKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
-
- private Object lock = new Object();
- private LWWindowPeer focusedWindow;
- private LWComponentPeer focusOwner;
+ private static final LWKeyboardFocusManagerPeer inst = new LWKeyboardFocusManagerPeer();
- private static Map<KeyboardFocusManager, LWKeyboardFocusManagerPeer> instances =
- new HashMap<KeyboardFocusManager, LWKeyboardFocusManagerPeer>();
+ private Window focusedWindow;
+ private Component focusOwner;
- public static synchronized LWKeyboardFocusManagerPeer getInstance(AppContext ctx) {
- return getInstance(AWTAccessor.getKeyboardFocusManagerAccessor().
- getCurrentKeyboardFocusManager(ctx));
+ public static LWKeyboardFocusManagerPeer getInstance() {
+ return inst;
}
- public static synchronized LWKeyboardFocusManagerPeer getInstance(KeyboardFocusManager manager) {
- LWKeyboardFocusManagerPeer instance = instances.get(manager);
- if (instance == null) {
- instance = new LWKeyboardFocusManagerPeer(manager);
- instances.put(manager, instance);
- }
- return instance;
+ private LWKeyboardFocusManagerPeer() {
}
- public LWKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
- super(manager);
+ @Override
+ public void setCurrentFocusedWindow(Window win) {
+ synchronized (this) {
+ focusedWindow = win;
+ }
}
@Override
public Window getCurrentFocusedWindow() {
- synchronized (lock) {
- return (focusedWindow != null) ? (Window)focusedWindow.getTarget() : null;
+ synchronized (this) {
+ return focusedWindow;
}
}
@Override
public Component getCurrentFocusOwner() {
- synchronized (lock) {
- return (focusOwner != null) ? focusOwner.getTarget() : null;
+ synchronized (this) {
+ return focusOwner;
}
}
@Override
public void setCurrentFocusOwner(Component comp) {
- synchronized (lock) {
- focusOwner = (comp != null) ? (LWComponentPeer)comp.getPeer() : null;
- }
- }
-
- void setFocusedWindow(LWWindowPeer peer) {
- synchronized (lock) {
- focusedWindow = peer;
- }
- }
-
- LWWindowPeer getFocusedWindow() {
- synchronized (lock) {
- return focusedWindow;
- }
- }
-
- void setFocusOwner(LWComponentPeer peer) {
- synchronized (lock) {
- focusOwner = peer;
- }
- }
-
- LWComponentPeer getFocusOwner() {
- synchronized (lock) {
- return focusOwner;
+ synchronized (this) {
+ focusOwner = comp;
}
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Fri Sep 14 10:14:02 2012 -0700
@@ -415,8 +415,8 @@
}
@Override
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
- return LWKeyboardFocusManagerPeer.getInstance(manager);
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
+ return LWKeyboardFocusManagerPeer.getInstance();
}
@Override
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -88,10 +88,16 @@
private volatile int windowState = Frame.NORMAL;
+ // check that the mouse is over the window
+ private volatile boolean isMouseOver = false;
+
+ // A peer where the last mouse event came to. Used by cursor manager to
+ // find the component under cursor
+ private static volatile LWComponentPeer lastCommonMouseEventPeer = null;
+
// A peer where the last mouse event came to. Used to generate
- // MOUSE_ENTERED/EXITED notifications and by cursor manager to
- // find the component under cursor
- private static volatile LWComponentPeer lastMouseEventPeer = null;
+ // MOUSE_ENTERED/EXITED notifications
+ private volatile LWComponentPeer lastMouseEventPeer;
// Peers where all dragged/released events should come to,
// depending on what mouse button is being dragged according to Cocoa
@@ -232,8 +238,7 @@
// TODO: update graphicsConfig, see 4868278
platformWindow.setVisible(visible);
if (isSimpleWindow()) {
- LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
- getInstance(getAppContext());
+ KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
if (visible) {
if (!getTarget().isAutoRequestFocus()) {
@@ -242,7 +247,7 @@
requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
}
// Focus the owner in case this window is focused.
- } else if (manager.getCurrentFocusedWindow() == getTarget()) {
+ } else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
// Transfer focus to the owner.
LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
if (owner != null) {
@@ -707,66 +712,65 @@
Rectangle r = getBounds();
// findPeerAt() expects parent coordinates
LWComponentPeer targetPeer = findPeerAt(r.x + x, r.y + y);
- LWWindowPeer lastWindowPeer =
- (lastMouseEventPeer != null) ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
- LWWindowPeer curWindowPeer =
- (targetPeer != null) ? targetPeer.getWindowPeerOrSelf() : null;
if (id == MouseEvent.MOUSE_EXITED) {
- // Sometimes we may get MOUSE_EXITED after lastMouseEventPeer is switched
- // to a peer from another window. So we must first check if this peer is
- // the same as lastWindowPeer
- if (lastWindowPeer == this) {
- if (isEnabled()) {
+ isMouseOver = false;
+ if (lastMouseEventPeer != null) {
+ if (lastMouseEventPeer.isEnabled()) {
Point lp = lastMouseEventPeer.windowToLocal(x, y,
- lastWindowPeer);
+ this);
postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
- MouseEvent.MOUSE_EXITED, when,
- modifiers, lp.x, lp.y, screenX,
- screenY, clickCount, popupTrigger,
- button));
+ MouseEvent.MOUSE_EXITED, when,
+ modifiers, lp.x, lp.y, screenX,
+ screenY, clickCount, popupTrigger,
+ button));
+ }
+
+ // Sometimes we may get MOUSE_EXITED after lastCommonMouseEventPeer is switched
+ // to a peer from another window. So we must first check if this peer is
+ // the same as lastWindowPeer
+ if (lastCommonMouseEventPeer != null && lastCommonMouseEventPeer.getWindowPeerOrSelf() == this) {
+ lastCommonMouseEventPeer = null;
}
lastMouseEventPeer = null;
}
- } else {
- if (targetPeer != lastMouseEventPeer) {
-
- if (id != MouseEvent.MOUSE_DRAGGED || lastMouseEventPeer == null) {
- // lastMouseEventPeer may be null if mouse was out of Java windows
- if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
- // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
- // later), in which case lastWindowPeer is another window
- if (lastWindowPeer != this) {
- Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
- // Additionally translate from this to lastWindowPeer coordinates
- Rectangle lr = lastWindowPeer.getBounds();
- oldp.x += r.x - lr.x;
- oldp.y += r.y - lr.y;
- postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
- MouseEvent.MOUSE_EXITED,
- when, modifiers,
- oldp.x, oldp.y, screenX, screenY,
- clickCount, popupTrigger, button));
- } else {
- Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
- postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
- MouseEvent.MOUSE_EXITED,
- when, modifiers,
- oldp.x, oldp.y, screenX, screenY,
- clickCount, popupTrigger, button));
- }
- }
- if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
- Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
+ } else if(id == MouseEvent.MOUSE_ENTERED) {
+ isMouseOver = true;
+ if (targetPeer != null) {
+ if (targetPeer.isEnabled()) {
+ Point lp = targetPeer.windowToLocal(x, y, this);
postEvent(new MouseEvent(targetPeer.getTarget(),
- MouseEvent.MOUSE_ENTERED,
- when, modifiers,
- newp.x, newp.y, screenX, screenY,
- clickCount, popupTrigger, button));
- }
+ MouseEvent.MOUSE_ENTERED, when,
+ modifiers, lp.x, lp.y, screenX,
+ screenY, clickCount, popupTrigger,
+ button));
}
+ lastCommonMouseEventPeer = targetPeer;
lastMouseEventPeer = targetPeer;
}
+ } else {
+ PlatformWindow topmostPlatforWindow =
+ platformWindow.getTopmostPlatformWindowUnderMouse();
+
+ LWWindowPeer topmostWindowPeer =
+ topmostPlatforWindow != null ? topmostPlatforWindow.getPeer() : null;
+
+ // topmostWindowPeer == null condition is added for the backward
+ // compatibility with applets. It can be removed when the
+ // getTopmostPlatformWindowUnderMouse() method will be properly
+ // implemented in CPlatformEmbeddedFrame class
+ if (topmostWindowPeer == this || topmostWindowPeer == null) {
+ generateMouseEnterExitEventsForComponents(when, button, x, y,
+ screenX, screenY, modifiers, clickCount, popupTrigger,
+ targetPeer);
+ } else {
+ LWComponentPeer topmostTargetPeer =
+ topmostWindowPeer != null ? topmostWindowPeer.findPeerAt(r.x + x, r.y + y) : null;
+ topmostWindowPeer.generateMouseEnterExitEventsForComponents(when, button, x, y,
+ screenX, screenY, modifiers, clickCount, popupTrigger,
+ topmostTargetPeer);
+ }
+
// TODO: fill "bdata" member of AWTEvent
int eventButtonMask = (button > 0)? MouseEvent.getMaskForButton(button) : 0;
@@ -794,6 +798,14 @@
mouseClickButtons |= eventButtonMask;
}
+ // The window should be focused on mouse click. If it gets activated by the native platform,
+ // this request will be no op. It will take effect when:
+ // 1. A simple not focused window is clicked.
+ // 2. An active but not focused owner frame/dialog is clicked.
+ // The mouse event then will trigger a focus request "in window" to the component, so the window
+ // should gain focus before.
+ requestWindowFocus(CausedFocusEvent.Cause.MOUSE_EVENT);
+
mouseDownTarget[targetIdx] = targetPeer;
} else if (id == MouseEvent.MOUSE_DRAGGED) {
// Cocoa dragged event has the information about which mouse
@@ -816,19 +828,13 @@
// mouseClickButtons is updated below, after MOUSE_CLICK is sent
}
- // check if we receive mouseEvent from outside the window's bounds
- // it can be either mouseDragged or mouseReleased
- if (curWindowPeer == null) {
- //TODO This can happen if this window is invisible. this is correct behavior in this case?
- curWindowPeer = this;
- }
if (targetPeer == null) {
//TODO This can happen if this window is invisible. this is correct behavior in this case?
targetPeer = this;
}
- Point lp = targetPeer.windowToLocal(x, y, curWindowPeer);
+ Point lp = targetPeer.windowToLocal(x, y, this);
if (targetPeer.isEnabled()) {
MouseEvent event = new MouseEvent(targetPeer.getTarget(), id,
when, modifiers, lp.x, lp.y,
@@ -852,6 +858,38 @@
notifyUpdateCursor();
}
+ private void generateMouseEnterExitEventsForComponents(long when,
+ int button, int x, int y, int screenX, int screenY,
+ int modifiers, int clickCount, boolean popupTrigger,
+ LWComponentPeer targetPeer) {
+
+ if (!isMouseOver || targetPeer == lastMouseEventPeer) {
+ return;
+ }
+
+ // Generate Mouse Exit for components
+ if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
+ Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
+ postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
+ MouseEvent.MOUSE_EXITED,
+ when, modifiers,
+ oldp.x, oldp.y, screenX, screenY,
+ clickCount, popupTrigger, button));
+ }
+ lastCommonMouseEventPeer = targetPeer;
+ lastMouseEventPeer = targetPeer;
+
+ // Generate Mouse Enter for components
+ if (targetPeer != null && targetPeer.isEnabled()) {
+ Point newp = targetPeer.windowToLocal(x, y, this);
+ postEvent(new MouseEvent(targetPeer.getTarget(),
+ MouseEvent.MOUSE_ENTERED,
+ when, modifiers,
+ newp.x, newp.y, screenX, screenY,
+ clickCount, popupTrigger, button));
+ }
+ }
+
public void dispatchMouseWheelEvent(long when, int x, int y, int modifiers,
int scrollType, int scrollAmount,
int wheelRotation, double preciseWheelRotation,
@@ -884,20 +922,16 @@
public void dispatchKeyEvent(int id, long when, int modifiers,
int keyCode, char keyChar, int keyLocation)
{
- LWComponentPeer focusOwner =
- LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
- getFocusOwner();
+ LWKeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+ Component focusOwner = kfmPeer.getCurrentFocusOwner();
- // Null focus owner may receive key event when
- // application hides the focused window upon ESC press
- // (AWT transfers/clears the focus owner) and pending ESC release
- // may come to already hidden window. This check eliminates NPE.
- if (focusOwner != null) {
- KeyEvent event =
- new KeyEvent(focusOwner.getTarget(), id, when, modifiers,
- keyCode, keyChar, keyLocation);
- focusOwner.postEvent(event);
+ if (focusOwner == null) {
+ focusOwner = kfmPeer.getCurrentFocusedWindow();
+ if (focusOwner == null) {
+ focusOwner = this.getTarget();
+ }
}
+ postEvent(new KeyEvent(focusOwner, id, when, modifiers, keyCode, keyChar, keyLocation));
}
@@ -1096,11 +1130,11 @@
}
public static LWWindowPeer getWindowUnderCursor() {
- return lastMouseEventPeer != null ? lastMouseEventPeer.getWindowPeerOrSelf() : null;
+ return lastCommonMouseEventPeer != null ? lastCommonMouseEventPeer.getWindowPeerOrSelf() : null;
}
public static LWComponentPeer<?, ?> getPeerUnderCursor() {
- return lastMouseEventPeer;
+ return lastCommonMouseEventPeer;
}
/*
@@ -1213,10 +1247,8 @@
}
}
- LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
- getInstance(getAppContext());
-
- Window oppositeWindow = becomesFocused ? manager.getCurrentFocusedWindow() : null;
+ KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+ Window oppositeWindow = becomesFocused ? kfmPeer.getCurrentFocusedWindow() : null;
// Note, the method is not called:
// - when the opposite (gaining focus) window is an owned/owner window.
@@ -1229,10 +1261,10 @@
grabbingWindow.ungrab();
}
- manager.setFocusedWindow(becomesFocused ? LWWindowPeer.this : null);
+ kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
- WindowEvent windowEvent = new WindowEvent(getTarget(), eventID, oppositeWindow);
+ WindowEvent windowEvent = new TimedWindowEvent(getTarget(), eventID, oppositeWindow, System.currentTimeMillis());
// TODO: wrap in SequencedEvent
postEvent(windowEvent);
--- a/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java Fri Sep 14 10:14:02 2012 -0700
@@ -118,6 +118,8 @@
public void setAlwaysOnTop(boolean value);
+ public PlatformWindow getTopmostPlatformWindowUnderMouse();
+
public void updateFocusableWindowState();
public boolean rejectFocusRequest(CausedFocusEvent.Cause cause);
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Fri Sep 14 10:14:02 2012 -0700
@@ -151,6 +151,10 @@
@Override
public void setAlwaysOnTop(boolean value) {}
+ // This method should be properly implemented for applets.
+ // It returns null just as a stub.
+ public PlatformWindow getTopmostPlatformWindowUnderMouse() { return null; }
+
@Override
public void updateFocusableWindowState() {}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Sep 14 10:14:02 2012 -0700
@@ -61,8 +61,9 @@
private static native void nativeSetNSWindowRepresentedFilename(long nsWindowPtr, String representedFilename);
private static native void nativeSetNSWindowSecurityWarningPositioning(long nsWindowPtr, double x, double y, float biasX, float biasY);
private static native void nativeSetEnabled(long nsWindowPtr, boolean isEnabled);
- private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr);
+ private static native void nativeSynthesizeMouseEnteredExitedEvents();
private static native void nativeDispose(long nsWindowPtr);
+ private static native CPlatformWindow nativeGetTopmostPlatformWindowUnderMouse();
private static native int nativeGetNSWindowDisplayID_AppKitThread(long nsWindowPtr);
@@ -588,7 +589,7 @@
}
}
- nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
+ nativeSynthesizeMouseEnteredExitedEvents();
// Configure stuff #2
updateFocusabilityForAutoRequestFocus(true);
@@ -729,6 +730,10 @@
setStyleBits(ALWAYS_ON_TOP, isAlwaysOnTop);
}
+ public PlatformWindow getTopmostPlatformWindowUnderMouse(){
+ return CPlatformWindow.nativeGetTopmostPlatformWindowUnderMouse();
+ }
+
@Override
public void setOpacity(float opacity) {
CWrapper.NSWindow.setAlphaValue(getNSWindowPtr(), opacity);
@@ -803,7 +808,7 @@
throw new RuntimeException("Unknown window state: " + windowState);
}
- nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
+ nativeSynthesizeMouseEnteredExitedEvents();
// NOTE: the SWP.windowState field gets updated to the newWindowState
// value when the native notification comes to us
--- a/jdk/src/macosx/native/com/apple/laf/ScreenMenu.m Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/com/apple/laf/ScreenMenu.m Fri Sep 14 10:14:02 2012 -0700
@@ -37,7 +37,11 @@
#import "ThreadUtilities.h"
#import "CMenuBar.h"
-
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
static JNF_CLASS_CACHE(sjc_ScreenMenu, "com/apple/laf/ScreenMenu");
static jint ns2awtModifiers(NSUInteger keyMods) {
@@ -97,7 +101,7 @@
{
if (self.javaObjectWrapper == nil) {
#ifdef DEBUG
- NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__);
+ NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__);
#endif
return;
}
@@ -115,7 +119,7 @@
{
if (self.javaObjectWrapper == nil) {
#ifdef DEBUG
- NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__);
+ NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__);
#endif
return;
}
@@ -133,7 +137,7 @@
{
if (self.javaObjectWrapper == nil) {
#ifdef DEBUG
- NSLog(@"_javaObject is NULL: (%s - %s : %d)", __FILE__, __FUNCTION__, __LINE__);
+ NSLog(@"_javaObject is NULL: (%s - %s : %d)", THIS_FILE, __FUNCTION__, __LINE__);
#endif
return;
}
--- a/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiOut.c Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiOut.c Fri Sep 14 10:14:02 2012 -0700
@@ -26,6 +26,11 @@
//#define USE_ERROR
//#define USE_TRACE
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#if USE_PLATFORM_MIDI_OUT == TRUE
#include "PLATFORM_API_MacOSX_MidiUtils.h"
@@ -128,7 +133,7 @@
case 0xF7:
// System exclusive
fprintf(stderr, "%s: %d->internal error: sysex message status=0x%X while sending short message\n",
- __FILE__, __LINE__, data[0]);
+ THIS_FILE, __LINE__, data[0]);
byteIsInvalid = TRUE;
break;
@@ -154,7 +159,7 @@
default:
// Invalid message
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
- __FILE__, __LINE__, data[0]);
+ THIS_FILE, __LINE__, data[0]);
byteIsInvalid = TRUE;
break;
}
@@ -164,7 +169,7 @@
default:
// This can't happen, but handle it anyway.
fprintf(stderr, "%s: %d->Invalid message: message status=0x%X while sending short message\n",
- __FILE__, __LINE__, data[0]);
+ THIS_FILE, __LINE__, data[0]);
byteIsInvalid = TRUE;
break;
}
--- a/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiUtils.c Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/com/sun/media/sound/PLATFORM_API_MacOSX_MidiUtils.c Fri Sep 14 10:14:02 2012 -0700
@@ -42,6 +42,11 @@
//#define USE_ERROR
//#define USE_TRACE
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#if (USE_PLATFORM_MIDI_IN == TRUE) || (USE_PLATFORM_MIDI_OUT == TRUE)
#include "PLATFORM_API_MacOSX_MidiUtils.h"
@@ -317,7 +322,7 @@
packedMsg = pendingMessageStatus | pendingData[0] << 8;
} else {
fprintf(stderr, "%s: %d->internal error: pendingMessageStatus=0x%X, pendingDataLength=%d\n",
- __FILE__, __LINE__, pendingMessageStatus, pendingDataLength);
+ THIS_FILE, __LINE__, pendingMessageStatus, pendingDataLength);
byteIsInvalid = TRUE;
}
pendingDataLength = 0;
--- a/jdk/src/macosx/native/sun/awt/AWTView.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/AWTView.h Fri Sep 14 10:14:02 2012 -0700
@@ -33,8 +33,8 @@
@private
jobject m_cPlatformView;
- // Handler for the tracking rect needed for Enter/Exit events management.
- NSTrackingRectTag rolloverTrackingRectTag;
+ // Handler for the tracking area needed for Enter/Exit events management.
+ NSTrackingArea* rolloverTrackingArea;
// TODO: NSMenu *contextualMenu;
@@ -61,7 +61,7 @@
- (id) initWithRect:(NSRect) rect platformView:(jobject)cPlatformView windowLayer:(CALayer*)windowLayer;
- (void) deliverJavaMouseEvent: (NSEvent *) event;
-- (void) resetTrackingRect;
+- (void) resetTrackingArea;
- (void) deliverJavaKeyEventHelper: (NSEvent *) event;
- (jobject) awtComponent:(JNIEnv *)env;
--- a/jdk/src/macosx/native/sun/awt/AWTView.m Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/AWTView.m Fri Sep 14 10:14:02 2012 -0700
@@ -82,6 +82,7 @@
fPAHNeedsToSelect = NO;
mouseIsOver = NO;
+ [self resetTrackingArea];
if (windowLayer != nil) {
self.cglLayer = windowLayer;
@@ -146,7 +147,7 @@
[[self window] makeFirstResponder: self];
}];
if ([self window] != NULL) {
- [self resetTrackingRect];
+ [self resetTrackingArea];
}
}
@@ -368,30 +369,31 @@
JNFCallVoidMethod(env, m_cPlatformView, jm_deliverMouseEvent, jEvent);
}
-
-- (void) clearTrackingRect {
- if (rolloverTrackingRectTag > 0) {
- [self removeTrackingRect:rolloverTrackingRectTag];
- rolloverTrackingRectTag = 0;
+- (void) resetTrackingArea {
+ if (rolloverTrackingArea != nil) {
+ [self removeTrackingArea:rolloverTrackingArea];
+ [rolloverTrackingArea release];
}
-}
+
+ int options = (NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited |
+ NSTrackingMouseMoved | NSTrackingEnabledDuringMouseDrag);
-- (void) resetTrackingRect {
- [self clearTrackingRect];
- rolloverTrackingRectTag = [self addTrackingRect:[self visibleRect]
- owner:self
- userData:NULL
- assumeInside:NO];
+ rolloverTrackingArea = [[NSTrackingArea alloc] initWithRect:[self visibleRect]
+ options: options
+ owner:self
+ userInfo:nil
+ ];
+ [self addTrackingArea:rolloverTrackingArea];
}
- (void)updateTrackingAreas {
[super updateTrackingAreas];
- [self resetTrackingRect];
+ [self resetTrackingArea];
}
- (void) resetCursorRects {
[super resetCursorRects];
- [self resetTrackingRect];
+ [self resetTrackingArea];
}
-(void) deliverJavaKeyEventHelper: (NSEvent *) event {
@@ -402,7 +404,7 @@
}
[sLastKeyEvent release];
sLastKeyEvent = [event retain];
-
+
[AWTToolkit eventCountPlusPlus];
JNIEnv *env = [ThreadUtilities getJNIEnv];
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Fri Sep 14 10:14:02 2012 -0700
@@ -238,10 +238,12 @@
return self;
}
-// checks that this window is under the mouse cursor and this point is not overlapped by others windows
-- (BOOL) isTopmostWindowUnderMouse {
++ (BOOL) isAWTWindow:(NSWindow *)window {
+ return [window isKindOfClass: [AWTWindow_Panel class]] || [window isKindOfClass: [AWTWindow_Normal class]];
+}
- int currentWinID = [self.nsWindow windowNumber];
+// returns id for the topmost window under mouse
++ (NSInteger) getTopmostWindowUnderMouseID {
NSRect screenRect = [[NSScreen mainScreen] frame];
NSPoint nsMouseLocation = [NSEvent mouseLocation];
@@ -249,53 +251,77 @@
NSMutableArray *windows = (NSMutableArray *)CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID);
-
for (NSDictionary *window in windows) {
- int layer = [[window objectForKey:(id)kCGWindowLayer] intValue];
+ NSInteger layer = [[window objectForKey:(id)kCGWindowLayer] integerValue];
if (layer == 0) {
- int winID = [[window objectForKey:(id)kCGWindowNumber] intValue];
CGRect rect;
CGRectMakeWithDictionaryRepresentation((CFDictionaryRef)[window objectForKey:(id)kCGWindowBounds], &rect);
if (CGRectContainsPoint(rect, cgMouseLocation)) {
- return currentWinID == winID;
- } else if (currentWinID == winID) {
- return NO;
+ return [[window objectForKey:(id)kCGWindowNumber] integerValue];
}
}
}
- return NO;
+ return -1;
+}
+
+// checks that this window is under the mouse cursor and this point is not overlapped by others windows
+- (BOOL) isTopmostWindowUnderMouse {
+ return [self.nsWindow windowNumber] == [AWTWindow getTopmostWindowUnderMouseID];
}
-- (void) synthesizeMouseEnteredExitedEvents {
++ (AWTWindow *) getTopmostWindowUnderMouse {
+ NSEnumerator *windowEnumerator = [[NSApp windows] objectEnumerator];
+ NSWindow *window;
- int eventType = 0;
- BOOL isUnderMouse = [self isTopmostWindowUnderMouse];
- BOOL mouseIsOver = [[self.nsWindow contentView] mouseIsOver];
+ NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
- if (isUnderMouse && !mouseIsOver) {
- eventType = NSMouseEntered;
- } else if (!isUnderMouse && mouseIsOver) {
- eventType = NSMouseExited;
- } else {
- return;
+ while ((window = [windowEnumerator nextObject]) != nil) {
+ if ([window windowNumber] == topmostWindowUnderMouseID) {
+ BOOL isAWTWindow = [AWTWindow isAWTWindow: window];
+ return isAWTWindow ? (AWTWindow *) [window delegate] : nil;
+ }
}
+ return nil;
+}
+
++ (void) synthesizeMouseEnteredExitedEvents:(NSWindow*)window withType:(NSEventType)eventType {
NSPoint screenLocation = [NSEvent mouseLocation];
- NSPoint windowLocation = [self.nsWindow convertScreenToBase: screenLocation];
+ NSPoint windowLocation = [window convertScreenToBase: screenLocation];
int modifierFlags = (eventType == NSMouseEntered) ? NSMouseEnteredMask : NSMouseExitedMask;
NSEvent *mouseEvent = [NSEvent enterExitEventWithType: eventType
- location: windowLocation
- modifierFlags: modifierFlags
- timestamp: 0
- windowNumber: [self.nsWindow windowNumber]
- context: nil
- eventNumber: 0
- trackingNumber: 0
- userData: nil
- ];
+ location: windowLocation
+ modifierFlags: modifierFlags
+ timestamp: 0
+ windowNumber: [window windowNumber]
+ context: nil
+ eventNumber: 0
+ trackingNumber: 0
+ userData: nil
+ ];
+
+ [[window contentView] deliverJavaMouseEvent: mouseEvent];
+}
+
++ (void) synthesizeMouseEnteredExitedEventsForAllWindows {
- [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
+ NSInteger topmostWindowUnderMouseID = [AWTWindow getTopmostWindowUnderMouseID];
+ NSArray *windows = [NSApp windows];
+ NSWindow *window;
+
+ NSEnumerator *windowEnumerator = [windows objectEnumerator];
+ while ((window = [windowEnumerator nextObject]) != nil) {
+ if ([AWTWindow isAWTWindow: window]) {
+ BOOL isUnderMouse = ([window windowNumber] == topmostWindowUnderMouseID);
+ BOOL mouseIsOver = [[window contentView] mouseIsOver];
+ if (isUnderMouse && !mouseIsOver) {
+ [AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseEntered];
+ } else if (!isUnderMouse && mouseIsOver) {
+ [AWTWindow synthesizeMouseEnteredExitedEvents:window withType:NSMouseExited];
+ }
+ }
+ }
}
- (void) dealloc {
@@ -825,7 +851,7 @@
// (this will also re-enable screen updates, which were disabled above)
// TODO: send PaintEvent
- [window synthesizeMouseEnteredExitedEvents];
+ [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}];
JNF_COCOA_EXIT(env);
@@ -1040,22 +1066,42 @@
/*
* Class: sun_lwawt_macosx_CPlatformWindow
+ * Method: nativeGetTopmostPlatformWindowUnderMouse
+ * Signature: (J)V
+ */
+JNIEXPORT jobject
+JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeGetTopmostPlatformWindowUnderMouse
+(JNIEnv *env, jclass clazz)
+{
+ jobject topmostWindowUnderMouse = nil;
+
+ JNF_COCOA_ENTER(env);
+ AWT_ASSERT_APPKIT_THREAD;
+
+ AWTWindow *awtWindow = [AWTWindow getTopmostWindowUnderMouse];
+ if (awtWindow != nil) {
+ topmostWindowUnderMouse = [awtWindow.javaPlatformWindow jObject];
+ }
+
+ JNF_COCOA_EXIT(env);
+
+ return topmostWindowUnderMouse;
+}
+
+/*
+ * Class: sun_lwawt_macosx_CPlatformWindow
* Method: nativeSynthesizeMouseEnteredExitedEvents
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSynthesizeMouseEnteredExitedEvents
-(JNIEnv *env, jclass clazz, jlong windowPtr)
+(JNIEnv *env, jclass clazz)
{
JNF_COCOA_ENTER(env);
AWT_ASSERT_NOT_APPKIT_THREAD;
- NSWindow *nsWindow = OBJC(windowPtr);
[JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
AWT_ASSERT_APPKIT_THREAD;
-
- AWTWindow *window = (AWTWindow*)[nsWindow delegate];
-
- [window synthesizeMouseEnteredExitedEvents];
+ [AWTWindow synthesizeMouseEnteredExitedEventsForAllWindows];
}];
JNF_COCOA_EXIT(env);
--- a/jdk/src/macosx/native/sun/awt/CSystemColors.m Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/CSystemColors.m Fri Sep 14 10:14:02 2012 -0700
@@ -33,6 +33,11 @@
#import "ThreadUtilities.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
NSColor **sColors = nil;
NSColor **appleColors = nil;
@@ -130,7 +135,7 @@
result = (useAppleColor ? appleColors : sColors)[colorIndex];
}
else {
- NSLog(@"%s: %s %sColor: %ld not found, returning black.", __FILE__, __FUNCTION__, (useAppleColor) ? "Apple" : "System", colorIndex);
+ NSLog(@"%s: %s %sColor: %ld not found, returning black.", THIS_FILE, __FUNCTION__, (useAppleColor) ? "Apple" : "System", colorIndex);
result = [NSColor blackColor];
}
--- a/jdk/src/macosx/native/sun/awt/CTextPipe.m Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/CTextPipe.m Fri Sep 14 10:14:02 2012 -0700
@@ -36,6 +36,10 @@
#import "QuartzSurfaceData.h"
#include "AWTStrike.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
static const CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
@@ -488,7 +492,7 @@
if (glyphs == NULL || advances == NULL)
{
(*env)->DeleteLocalRef(env, glyphsArray);
- [NSException raise:NSMallocException format:@"%s-%s:%d", __FILE__, __FUNCTION__, __LINE__];
+ [NSException raise:NSMallocException format:@"%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__];
return;
}
--- a/jdk/src/macosx/native/sun/awt/ImageSurfaceData.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/ImageSurfaceData.h Fri Sep 14 10:14:02 2012 -0700
@@ -41,7 +41,7 @@
// If there is an image present, this is a no-op
void makeSureImageIsCreated(ImageSDOps* isdo);
-struct _ContextInfo
+typedef struct _ContextInfo
{
BOOL useWindowContextReference;
BOOL canUseJavaPixelsAsContext;
@@ -50,10 +50,9 @@
size_t bytesPerRow;
CGImageAlphaInfo alphaInfo;
CGColorSpaceRef colorSpace;
-}
-typedef ContextInfo;
+} ContextInfo;
-struct _ImageInfo
+typedef struct _ImageInfo
{
size_t bitsPerComponent;
size_t bitsPerPixel;
@@ -61,8 +60,7 @@
size_t bytesPerRow;
CGImageAlphaInfo alphaInfo;
CGColorSpaceRef colorSpace;
-}
-typedef ImageInfo;
+} ImageInfo;
struct _ImageSDOps
{
--- a/jdk/src/macosx/native/sun/awt/ImageSurfaceData.m Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/ImageSurfaceData.m Fri Sep 14 10:14:02 2012 -0700
@@ -53,10 +53,6 @@
// for vImage framework headers
#include <Accelerate/Accelerate.h>
-
-// private Quartz routines needed here
-CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx);
-
static ContextInfo sDefaultContextInfo[sun_java2d_OSXOffScreenSurfaceData_TYPE_3BYTE_RGB+1] =
{
{YES, YES, 8, 4, 0, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host, NULL}, // TYPE_CUSTOM // special case
@@ -942,7 +938,6 @@
// intitalize the context to match the Java coordinate system
// BG, since the context is created above, we can just concat
- //CGContextSetCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height));
CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, -1, 0, isdo->height));
CGContextSaveGState(qsdo->cgRef); // this will make sure we don't go pass device context settings
@@ -1114,7 +1109,10 @@
if (qsdo->cgRef != NULL)
{
CGContextSaveGState(qsdo->cgRef);
- CGContextSetCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, 1, 0, 0));
+ CGAffineTransform currCTM = CGContextGetCTM(qsdo->cgRef);
+ CGAffineTransform inverse = CGAffineTransformInvert(currCTM);
+ CGContextConcatCTM(qsdo->cgRef, inverse);
+ CGContextConcatCTM(qsdo->cgRef, CGAffineTransformMake(1, 0, 0, 1, 0, 0));
CGContextSetBlendMode(qsdo->cgRef, kCGBlendModeCopy);
CGContextSetAlpha(qsdo->cgRef, 1.0f);
CGContextDrawImage(qsdo->cgRef, CGRectMake(0, 0, width, height), javaImg);
--- a/jdk/src/macosx/native/sun/awt/QuartzRenderer.m Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/QuartzRenderer.m Fri Sep 14 10:14:02 2012 -0700
@@ -50,9 +50,6 @@
// same value as defined in Sun's own code
#define XOR_ALPHA_CUTOFF 128
-// private Quartz routines needed here
-CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx);
-
static CGFloat gRoundRectCtrlpts[10][12] =
{
@@ -536,7 +533,7 @@
makeSureImageIsCreated(isdo);
- CGAffineTransform ctm = CGContextGetCTM(cgRef);
+ CGContextSaveGState(cgRef);
CGContextConcatCTM(cgRef, CGAffineTransformMake(a, b, c, d, tx, ty));
jint alphaInfo = isdo->contextInfo.alphaInfo & kCGBitmapAlphaInfoMask;
@@ -551,7 +548,7 @@
CGImageRelease(subImg);
}
- CGContextSetCTM(cgRef, ctm);
+ CGContextRestoreGState(cgRef);
UnlockImage(env, isdo);
}
--- a/jdk/src/macosx/native/sun/awt/QuartzSurfaceData.m Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/QuartzSurfaceData.m Fri Sep 14 10:14:02 2012 -0700
@@ -40,9 +40,6 @@
#import <AppKit/AppKit.h>
#import "ThreadUtilities.h"
-// private Quartz routines needed here
-CG_EXTERN void CGContextSetCTM(CGContextRef ref, CGAffineTransform tx);
-
//#define DEBUG
#if defined DEBUG
#define PRINT(msg) {fprintf(stderr, "%s\n", msg);}
@@ -50,9 +47,6 @@
#define PRINT(msg) {}
#endif
-// from CGAffineTransformPrivate.h
-extern CGPoint CGPointApplyInverseAffineTransform(CGPoint point, CGAffineTransform t);
-
#define kOffset (0.5f)
BOOL gAdjustForJavaDrawing;
@@ -608,7 +602,8 @@
// We need to flip both y coefficeints to flip the offset point into the java coordinate system.
ctm.b = -ctm.b; ctm.d = -ctm.d; ctm.tx = 0.0f; ctm.ty = 0.0f;
CGPoint offsets = {kOffset, kOffset};
- offsets = CGPointApplyInverseAffineTransform(offsets, ctm);
+ CGAffineTransform inverse = CGAffineTransformInvert(ctm);
+ offsets = CGPointApplyAffineTransform(offsets, inverse);
qsdo->graphicsStateInfo.offsetX = offsets.x;
qsdo->graphicsStateInfo.offsetY = offsets.y;
}
--- a/jdk/src/macosx/native/sun/font/AWTStrike.m Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/macosx/native/sun/font/AWTStrike.m Fri Sep 14 10:14:02 2012 -0700
@@ -33,6 +33,11 @@
#import "CoreTextSupport.h"
//#import "jni_util.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
@implementation AWTStrike
static CGAffineTransform sInverseTX = { 1, 0, 0, -1, 0, 0 };
@@ -102,7 +107,7 @@
#define AWT_FONT_CLEANUP_FINISH \
if (_fontThrowJavaException == YES) { \
char s[512]; \
- sprintf(s, "%s-%s:%d", __FILE__, __FUNCTION__, __LINE__); \
+ sprintf(s, "%s-%s:%d", THIS_FILE, __FUNCTION__, __LINE__); \
[JNFException raise:env as:kRuntimeException reason:s]; \
}
--- a/jdk/src/share/back/error_messages.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/back/error_messages.h Fri Sep 14 10:14:02 2012 -0700
@@ -42,31 +42,36 @@
const char * eventText(int);
const char * jdwpErrorText(jdwpError);
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define EXIT_ERROR(error,msg) \
{ \
print_message(stderr, "JDWP exit error ", "\n", \
"%s(%d): %s [%s:%d]", \
jvmtiErrorText((jvmtiError)error), error, (msg==NULL?"":msg), \
- __FILE__, __LINE__); \
+ THIS_FILE, __LINE__); \
debugInit_exit((jvmtiError)error, msg); \
}
#define JDI_ASSERT(expression) \
do { \
if (gdata && gdata->assertOn && !(expression)) { \
- jdiAssertionFailed(__FILE__, __LINE__, #expression); \
+ jdiAssertionFailed(THIS_FILE, __LINE__, #expression); \
} \
} while (0)
#define JDI_ASSERT_MSG(expression, msg) \
do { \
if (gdata && gdata->assertOn && !(expression)) { \
- jdiAssertionFailed(__FILE__, __LINE__, msg); \
+ jdiAssertionFailed(THIS_FILE, __LINE__, msg); \
} \
} while (0)
#define JDI_ASSERT_FAILED(msg) \
- jdiAssertionFailed(__FILE__, __LINE__, msg)
+ jdiAssertionFailed(THIS_FILE, __LINE__, msg)
void do_pause(void);
--- a/jdk/src/share/back/log_messages.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/back/log_messages.h Fri Sep 14 10:14:02 2012 -0700
@@ -33,11 +33,15 @@
#define LOG_NULL ((void)0)
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#ifdef JDWP_LOGGING
-
#define _LOG(flavor,args) \
- (log_message_begin(flavor,__FILE__,__LINE__), \
+ (log_message_begin(flavor,THIS_FILE,__LINE__), \
log_message_end args)
#define LOG_TEST(flag) (gdata->log_flags & (flag))
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java Fri Sep 14 10:14:02 2012 -0700
@@ -30,6 +30,8 @@
import java.awt.Event;
import java.awt.KeyEventPostProcessor;
import java.awt.Window;
+import java.awt.Toolkit;
+import sun.awt.SunToolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
@@ -125,7 +127,19 @@
}
JMenu menu = mbar != null ? mbar.getMenu(0) : null;
- if (menu != null) {
+ // It might happen that the altRelease event is processed
+ // with a reasonable delay since it has been generated.
+ // Here we check the last deactivation time of the containing
+ // window. If this time appears to be greater than the altRelease
+ // event time the event is skipped to avoid unexpected menu
+ // activation. See 7121442.
+ boolean skip = false;
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ if (tk instanceof SunToolkit) {
+ skip = ev.getWhen() <= ((SunToolkit)tk).getWindowDeactivationTime(winAncestor);
+ }
+
+ if (menu != null && !skip) {
MenuElement[] path = new MenuElement[2];
path[0] = mbar;
path[1] = menu;
--- a/jdk/src/share/classes/java/awt/Component.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/awt/Component.java Fri Sep 14 10:14:02 2012 -0700
@@ -4710,7 +4710,10 @@
/*
* 0. Set timestamp and modifiers of current event.
*/
- EventQueue.setCurrentEventAndMostRecentTime(e);
+ if (!(e instanceof KeyEvent)) {
+ // Timestamp of a key event is set later in DKFM.preDispatchKeyEvent(KeyEvent).
+ EventQueue.setCurrentEventAndMostRecentTime(e);
+ }
/*
* 1. Pre-dispatchers. Do any necessary retargeting/reordering here
@@ -7606,13 +7609,33 @@
boolean focusedWindowChangeAllowed,
CausedFocusEvent.Cause cause)
{
+ // 1) Check if the event being dispatched is a system-generated mouse event.
+ AWTEvent currentEvent = EventQueue.getCurrentEvent();
+ if (currentEvent instanceof MouseEvent &&
+ SunToolkit.isSystemGenerated(currentEvent))
+ {
+ // 2) Sanity check: if the mouse event component source belongs to the same containing window.
+ Component source = ((MouseEvent)currentEvent).getComponent();
+ if (source == null || source.getContainingWindow() == getContainingWindow()) {
+ focusLog.finest("requesting focus by mouse event \"in window\"");
+
+ // If both the conditions are fulfilled the focus request should be strictly
+ // bounded by the toplevel window. It's assumed that the mouse event activates
+ // the window (if it wasn't active) and this makes it possible for a focus
+ // request with a strong in-window requirement to change focus in the bounds
+ // of the toplevel. If, by any means, due to asynchronous nature of the event
+ // dispatching mechanism, the window happens to be natively inactive by the time
+ // this focus request is eventually handled, it should not re-activate the
+ // toplevel. Otherwise the result may not meet user expectations. See 6981400.
+ focusedWindowChangeAllowed = false;
+ }
+ }
if (!isRequestFocusAccepted(temporary, focusedWindowChangeAllowed, cause)) {
if (focusLog.isLoggable(PlatformLogger.FINEST)) {
focusLog.finest("requestFocus is not accepted");
}
return false;
}
-
// Update most-recent map
KeyboardFocusManager.setMostRecentFocusOwner(this);
@@ -7645,7 +7668,15 @@
}
// Focus this Component
- long time = EventQueue.getMostRecentEventTime();
+ long time = 0;
+ if (EventQueue.isDispatchThread()) {
+ time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
+ } else {
+ // A focus request made from outside EDT should not be associated with any event
+ // and so its time stamp is simply set to the current time.
+ time = System.currentTimeMillis();
+ }
+
boolean success = peer.requestFocus
(this, temporary, focusedWindowChangeAllowed, time, cause);
if (!success) {
--- a/jdk/src/share/classes/java/awt/Container.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/awt/Container.java Fri Sep 14 10:14:02 2012 -0700
@@ -2863,7 +2863,7 @@
// keep the KeyEvents from being dispatched
// until the focus has been transfered
- long time = Toolkit.getEventQueue().getMostRecentEventTime();
+ long time = Toolkit.getEventQueue().getMostRecentKeyEventTime();
Component predictedFocusOwner = (Component.isInstanceOf(this, "javax.swing.JInternalFrame")) ? ((javax.swing.JInternalFrame)(this)).getMostRecentFocusOwner() : null;
if (predictedFocusOwner != null) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().
--- a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java Fri Sep 14 10:14:02 2012 -0700
@@ -41,6 +41,7 @@
import sun.awt.SunToolkit;
import sun.awt.AWTAccessor;
import sun.awt.CausedFocusEvent;
+import sun.awt.TimedWindowEvent;
/**
* The default KeyboardFocusManager for AWT applications. Focus traversal is
@@ -72,8 +73,8 @@
private WeakReference<Window> realOppositeWindowWR = NULL_WINDOW_WR;
private WeakReference<Component> realOppositeComponentWR = NULL_COMPONENT_WR;
private int inSendMessage;
- private LinkedList enqueuedKeyEvents = new LinkedList(),
- typeAheadMarkers = new LinkedList();
+ private LinkedList<KeyEvent> enqueuedKeyEvents = new LinkedList<KeyEvent>();
+ private LinkedList<TypeAheadMarker> typeAheadMarkers = new LinkedList<TypeAheadMarker>();
private boolean consumeNextKeyTyped;
static {
@@ -269,6 +270,31 @@
return se.dispatched;
}
+ /*
+ * Checks if the focus window event follows key events waiting in the type-ahead
+ * queue (if any). This may happen when a user types ahead in the window, the client
+ * listeners hang EDT for a while, and the user switches b/w toplevels. In that
+ * case the focus window events may be dispatched before the type-ahead events
+ * get handled. This may lead to wrong focus behavior and in order to avoid it,
+ * the focus window events are reposted to the end of the event queue. See 6981400.
+ */
+ private boolean repostIfFollowsKeyEvents(WindowEvent e) {
+ if (!(e instanceof TimedWindowEvent)) {
+ return false;
+ }
+ TimedWindowEvent we = (TimedWindowEvent)e;
+ long time = we.getWhen();
+ synchronized (this) {
+ for (KeyEvent ke: enqueuedKeyEvents) {
+ if (time >= ke.getWhen()) {
+ SunToolkit.postEvent(AppContext.getAppContext(), new SequencedEvent(e));
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* This method is called by the AWT event dispatcher requesting that the
* current KeyboardFocusManager dispatch the specified event on its behalf.
@@ -287,6 +313,10 @@
if (focusLog.isLoggable(PlatformLogger.FINE) && (e instanceof WindowEvent || e instanceof FocusEvent)) focusLog.fine("" + e);
switch (e.getID()) {
case WindowEvent.WINDOW_GAINED_FOCUS: {
+ if (repostIfFollowsKeyEvents((WindowEvent)e)) {
+ break;
+ }
+
WindowEvent we = (WindowEvent)e;
Window oldFocusedWindow = getGlobalFocusedWindow();
Window newFocusedWindow = we.getWindow();
@@ -646,6 +676,10 @@
}
case WindowEvent.WINDOW_LOST_FOCUS: {
+ if (repostIfFollowsKeyEvents((WindowEvent)e)) {
+ break;
+ }
+
WindowEvent we = (WindowEvent)e;
Window currentFocusedWindow = getGlobalFocusedWindow();
Window losingFocusWindow = we.getWindow();
@@ -825,10 +859,9 @@
ke = null;
synchronized (this) {
if (enqueuedKeyEvents.size() != 0) {
- ke = (KeyEvent)enqueuedKeyEvents.getFirst();
+ ke = enqueuedKeyEvents.getFirst();
if (typeAheadMarkers.size() != 0) {
- TypeAheadMarker marker = (TypeAheadMarker)
- typeAheadMarkers.getFirst();
+ TypeAheadMarker marker = typeAheadMarkers.getFirst();
// Fixed 5064013: may appears that the events have the same time
// if (ke.getWhen() >= marker.after) {
// The fix is rolled out.
@@ -857,9 +890,9 @@
focusLog.finest(">>> Markers dump, time: {0}", System.currentTimeMillis());
synchronized (this) {
if (typeAheadMarkers.size() != 0) {
- Iterator iter = typeAheadMarkers.iterator();
+ Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator();
while (iter.hasNext()) {
- TypeAheadMarker marker = (TypeAheadMarker)iter.next();
+ TypeAheadMarker marker = iter.next();
focusLog.finest(" {0}", marker);
}
}
@@ -881,8 +914,7 @@
KeyEvent ke = (KeyEvent)e;
synchronized (this) {
if (e.isPosted && typeAheadMarkers.size() != 0) {
- TypeAheadMarker marker = (TypeAheadMarker)
- typeAheadMarkers.getFirst();
+ TypeAheadMarker marker = typeAheadMarkers.getFirst();
// Fixed 5064013: may appears that the events have the same time
// if (ke.getWhen() >= marker.after) {
// The fix is rolled out.
@@ -915,12 +947,10 @@
synchronized (this) {
boolean found = false;
if (hasMarker(target)) {
- for (Iterator iter = typeAheadMarkers.iterator();
+ for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator();
iter.hasNext(); )
{
- if (((TypeAheadMarker)iter.next()).untilFocused ==
- target)
- {
+ if (iter.next().untilFocused == target) {
found = true;
} else if (found) {
break;
@@ -955,8 +985,8 @@
* @since 1.5
*/
private boolean hasMarker(Component comp) {
- for (Iterator iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
- if (((TypeAheadMarker)iter.next()).untilFocused == comp) {
+ for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
+ if (iter.next().untilFocused == comp) {
return true;
}
}
@@ -982,11 +1012,10 @@
return true;
}
- // Explicitly set the current event and most recent timestamp here in
- // addition to the call in Component.dispatchEventImpl. Because
- // KeyEvents can be delivered in response to a FOCUS_GAINED event, the
- // current timestamp may be incorrect. We need to set it here so that
- // KeyEventDispatchers will use the correct time.
+ // Explicitly set the key event timestamp here (not in Component.dispatchEventImpl):
+ // - A key event is anyway passed to this method which starts its actual dispatching.
+ // - If a key event is put to the type ahead queue, its time stamp should not be registered
+ // until its dispatching actually starts (by this method).
EventQueue.setCurrentEventAndMostRecentTime(ke);
/**
@@ -1174,10 +1203,10 @@
int insertionIndex = 0,
i = typeAheadMarkers.size();
- ListIterator iter = typeAheadMarkers.listIterator(i);
+ ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator(i);
for (; i > 0; i--) {
- TypeAheadMarker marker = (TypeAheadMarker)iter.previous();
+ TypeAheadMarker marker = iter.previous();
if (marker.after <= after) {
insertionIndex = i;
break;
@@ -1213,12 +1242,12 @@
after, untilFocused);
TypeAheadMarker marker;
- ListIterator iter = typeAheadMarkers.listIterator
+ ListIterator<TypeAheadMarker> iter = typeAheadMarkers.listIterator
((after >= 0) ? typeAheadMarkers.size() : 0);
if (after < 0) {
while (iter.hasNext()) {
- marker = (TypeAheadMarker)iter.next();
+ marker = iter.next();
if (marker.untilFocused == untilFocused)
{
iter.remove();
@@ -1227,7 +1256,7 @@
}
} else {
while (iter.hasPrevious()) {
- marker = (TypeAheadMarker)iter.previous();
+ marker = iter.previous();
if (marker.untilFocused == untilFocused &&
marker.after == after)
{
@@ -1255,8 +1284,8 @@
long start = -1;
- for (Iterator iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
- TypeAheadMarker marker = (TypeAheadMarker)iter.next();
+ for (Iterator<TypeAheadMarker> iter = typeAheadMarkers.iterator(); iter.hasNext(); ) {
+ TypeAheadMarker marker = iter.next();
Component toTest = marker.untilFocused;
boolean match = (toTest == comp);
while (!match && toTest != null && !(toTest instanceof Window)) {
@@ -1287,8 +1316,8 @@
return;
}
- for (Iterator iter = enqueuedKeyEvents.iterator(); iter.hasNext(); ) {
- KeyEvent ke = (KeyEvent)iter.next();
+ for (Iterator<KeyEvent> iter = enqueuedKeyEvents.iterator(); iter.hasNext(); ) {
+ KeyEvent ke = iter.next();
long time = ke.getWhen();
if (start < time && (end < 0 || time <= end)) {
--- a/jdk/src/share/classes/java/awt/Dialog.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/awt/Dialog.java Fri Sep 14 10:14:02 2012 -0700
@@ -924,7 +924,7 @@
isEnabled() && !isModalBlocked()) {
// keep the KeyEvents from being dispatched
// until the focus has been transfered
- time.set(Toolkit.getEventQueue().getMostRecentEventTimeEx());
+ time.set(Toolkit.getEventQueue().getMostRecentKeyEventTime());
KeyboardFocusManager.getCurrentKeyboardFocusManager().
enqueueKeyEvents(time.get(), toFocus);
}
--- a/jdk/src/share/classes/java/awt/EventQueue.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/awt/EventQueue.java Fri Sep 14 10:14:02 2012 -0700
@@ -162,6 +162,11 @@
*/
private long mostRecentEventTime = System.currentTimeMillis();
+ /*
+ * The time stamp of the last KeyEvent .
+ */
+ private long mostRecentKeyEventTime = System.currentTimeMillis();
+
/**
* The modifiers field of the current event, if the current event is an
* InputEvent or ActionEvent.
@@ -1142,6 +1147,15 @@
}
}
+ synchronized long getMostRecentKeyEventTime() {
+ pushPopLock.lock();
+ try {
+ return mostRecentKeyEventTime;
+ } finally {
+ pushPopLock.unlock();
+ }
+ }
+
static void setCurrentEventAndMostRecentTime(AWTEvent e) {
Toolkit.getEventQueue().setCurrentEventAndMostRecentTimeImpl(e);
}
@@ -1166,6 +1180,9 @@
if (e instanceof InputEvent) {
InputEvent ie = (InputEvent)e;
mostRecentEventTime2 = ie.getWhen();
+ if (e instanceof KeyEvent) {
+ mostRecentKeyEventTime = ie.getWhen();
+ }
} else if (e instanceof InputMethodEvent) {
InputMethodEvent ime = (InputMethodEvent)e;
mostRecentEventTime2 = ime.getWhen();
--- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java Fri Sep 14 10:14:02 2012 -0700
@@ -445,7 +445,7 @@
private void initPeer() {
Toolkit tk = Toolkit.getDefaultToolkit();
KeyboardFocusManagerPeerProvider peerProvider = (KeyboardFocusManagerPeerProvider)tk;
- peer = peerProvider.createKeyboardFocusManagerPeer(this);
+ peer = peerProvider.getKeyboardFocusManagerPeer();
}
/**
--- a/jdk/src/share/classes/java/awt/SequencedEvent.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/awt/SequencedEvent.java Fri Sep 14 10:14:02 2012 -0700
@@ -26,6 +26,7 @@
package java.awt;
import java.util.LinkedList;
+import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.SunToolkit;
@@ -54,6 +55,17 @@
private AppContext appContext;
private boolean disposed;
+ static {
+ AWTAccessor.setSequencedEventAccessor(new AWTAccessor.SequencedEventAccessor() {
+ public AWTEvent getNested(AWTEvent sequencedEvent) {
+ return ((SequencedEvent)sequencedEvent).nested;
+ }
+ public boolean isSequencedEvent(AWTEvent event) {
+ return event instanceof SequencedEvent;
+ }
+ });
+ }
+
/**
* Constructs a new SequencedEvent which will dispatch the specified
* nested event.
--- a/jdk/src/share/classes/java/awt/peer/KeyboardFocusManagerPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/awt/peer/KeyboardFocusManagerPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -34,6 +34,14 @@
public interface KeyboardFocusManagerPeer {
/**
+ * Sets the window that should become the focused window.
+ *
+ * @param win the window that should become the focused window
+ *
+ */
+ void setCurrentFocusedWindow(Window win);
+
+ /**
* Returns the currently focused window.
*
* @return the currently focused window
--- a/jdk/src/share/classes/java/beans/Introspector.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/beans/Introspector.java Fri Sep 14 10:14:02 2012 -0700
@@ -1460,7 +1460,7 @@
private PropertyDescriptor[] properties;
private int defaultProperty;
private MethodDescriptor[] methods;
- private final Reference<BeanInfo> targetBeanInfoRef;
+ private Reference<BeanInfo> targetBeanInfoRef;
public GenericBeanInfo(BeanDescriptor beanDescriptor,
EventSetDescriptor[] events, int defaultEvent,
@@ -1472,7 +1472,9 @@
this.properties = properties;
this.defaultProperty = defaultProperty;
this.methods = methods;
- this.targetBeanInfoRef = new SoftReference<>(targetBeanInfo);
+ this.targetBeanInfoRef = (targetBeanInfo != null)
+ ? new SoftReference<>(targetBeanInfo)
+ : null;
}
/**
@@ -1539,10 +1541,25 @@
}
public java.awt.Image getIcon(int iconKind) {
- BeanInfo targetBeanInfo = this.targetBeanInfoRef.get();
+ BeanInfo targetBeanInfo = getTargetBeanInfo();
if (targetBeanInfo != null) {
return targetBeanInfo.getIcon(iconKind);
}
return super.getIcon(iconKind);
}
+
+ private BeanInfo getTargetBeanInfo() {
+ if (this.targetBeanInfoRef == null) {
+ return null;
+ }
+ BeanInfo targetBeanInfo = this.targetBeanInfoRef.get();
+ if (targetBeanInfo == null) {
+ targetBeanInfo = ThreadGroupContext.getContext().getBeanInfoFinder()
+ .find(this.beanDescriptor.getBeanClass());
+ if (targetBeanInfo != null) {
+ this.targetBeanInfoRef = new SoftReference<>(targetBeanInfo);
+ }
+ }
+ return targetBeanInfo;
+ }
}
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java Fri Sep 14 10:14:02 2012 -0700
@@ -109,6 +109,10 @@
if (writeMethodName != null && getWriteMethod() == null) {
throw new IntrospectionException("Method not found: " + writeMethodName);
}
+ boundInitialization(beanClass);
+ }
+
+ private void boundInitialization(Class<?> beanClass) {
// If this class or one of its base classes allow PropertyChangeListener,
// then we assume that any properties we discover are "bound".
// See Introspector.getTargetPropertyInfo() method.
@@ -159,6 +163,7 @@
setReadMethod(read);
setWriteMethod(write);
this.baseName = base;
+ boundInitialization(bean);
}
/**
@@ -588,7 +593,7 @@
Method yw = y.getWriteMethod();
try {
- if (yw != null && yw.getDeclaringClass() == getClass0()) {
+ if (yw != null) {
setWriteMethod(yw);
} else {
setWriteMethod(xw);
--- a/jdk/src/share/classes/java/beans/XMLEncoder.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/beans/XMLEncoder.java Fri Sep 14 10:14:02 2012 -0700
@@ -631,7 +631,12 @@
}
if (d.name != null) {
- outputXML(isArgument ? "object" : "void", " idref=" + quote(d.name), value);
+ if (isArgument) {
+ writeln("<object idref=" + quote(d.name) + "/>");
+ }
+ else {
+ outputXML("void", " idref=" + quote(d.name), value);
+ }
}
else if (d.exp != null) {
outputStatement(d.exp, outer, isArgument);
@@ -710,12 +715,14 @@
}
else {
d.refs = 2;
- getValueData(target).refs++;
- List<Statement> statements = statementList(target);
- if (!statements.contains(exp)) {
- statements.add(exp);
+ if (d.name == null) {
+ getValueData(target).refs++;
+ List<Statement> statements = statementList(target);
+ if (!statements.contains(exp)) {
+ statements.add(exp);
+ }
+ outputValue(target, outer, false);
}
- outputValue(target, outer, false);
if (expression) {
outputValue(value, outer, isArgument);
}
--- a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Fri Sep 14 10:14:02 2012 -0700
@@ -143,6 +143,11 @@
protected abstract SpeciesData speciesData();
@Override
+ final Object internalProperties() {
+ return "/BMH="+internalValues();
+ }
+
+ @Override
final Object internalValues() {
Object[] boundValues = new Object[speciesData().fieldCount()];
for (int i = 0; i < boundValues.length; ++i) {
--- a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Fri Sep 14 10:14:02 2012 -0700
@@ -108,8 +108,8 @@
}
@Override
- String debugString() {
- return "DMH["+member.toString()+"]="+super.debugString();
+ String internalProperties() {
+ return "/DMH="+member.toString();
}
//// Implementation methods.
--- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Sep 14 10:14:02 2012 -0700
@@ -185,12 +185,17 @@
}
class CpPatch {
- int index;
- Object value;
- CpPatch(int index, Object value) {
+ final int index;
+ final String placeholder;
+ final Object value;
+ CpPatch(int index, String placeholder, Object value) {
this.index = index;
+ this.placeholder = placeholder;
this.value = value;
}
+ public String toString() {
+ return "CpPatch/index="+index+",placeholder="+placeholder+",value="+value;
+ }
}
Map<Object, CpPatch> cpPatches = new HashMap<>();
@@ -205,7 +210,7 @@
}
// insert placeholder in CP and remember the patch
int index = cw.newConst((Object) cpPlaceholder); // TODO check if aready in the constant pool
- cpPatches.put(cpPlaceholder, new CpPatch(index, arg));
+ cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, arg));
return cpPlaceholder;
}
@@ -213,7 +218,9 @@
int size = getConstantPoolSize(classFile);
Object[] res = new Object[size];
for (CpPatch p : cpPatches.values()) {
- res[p.index] = p.value;
+ if (p.index >= size)
+ throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
+ res[p.index] = p.value;
}
return res;
}
--- a/jdk/src/share/classes/java/lang/invoke/Invokers.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java Fri Sep 14 10:14:02 2012 -0700
@@ -74,8 +74,18 @@
MethodHandle invoker = exactInvoker;
if (invoker != null) return invoker;
MethodType mtype = targetType;
- LambdaForm lform = invokeForm(mtype, MethodTypeForm.LF_EX_INVOKER);
- invoker = BoundMethodHandle.bindSingle(mtype.invokerType(), lform, mtype);
+ MethodType invokerType = mtype.invokerType();
+ LambdaForm lform;
+ final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value
+ if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - MTYPE_ARG_APPENDED) {
+ lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_INVOKER);
+ invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
+ } else {
+ // At maximum arity, we cannot afford an extra mtype argument,
+ // so build a fully customized (non-cached) invoker form.
+ lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER);
+ invoker = SimpleMethodHandle.make(invokerType, lform);
+ }
assert(checkInvoker(invoker));
exactInvoker = invoker;
return invoker;
@@ -85,9 +95,20 @@
MethodHandle invoker = generalInvoker;
if (invoker != null) return invoker;
MethodType mtype = targetType;
- prepareForGenericCall(mtype);
- LambdaForm lform = invokeForm(mtype, MethodTypeForm.LF_GEN_INVOKER);
- invoker = BoundMethodHandle.bindSingle(mtype.invokerType(), lform, mtype);
+ MethodType invokerType = mtype.invokerType();
+ LambdaForm lform;
+ final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value
+ assert(GENERIC_INVOKER_SLOP >= MTYPE_ARG_APPENDED);
+ if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - GENERIC_INVOKER_SLOP) {
+ prepareForGenericCall(mtype);
+ lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_INVOKER);
+ invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
+ } else {
+ // At maximum arity, we cannot afford an extra mtype argument,
+ // so build a fully customized (non-cached) invoker form.
+ lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER);
+ invoker = SimpleMethodHandle.make(invokerType, lform);
+ }
assert(checkInvoker(invoker));
generalInvoker = invoker;
return invoker;
@@ -102,6 +123,7 @@
}
static MemberName invokeBasicMethod(MethodType type) {
+ type = type.basicType();
String name = "invokeBasic";
try {
//Lookup.findVirtual(MethodHandle.class, name, type);
@@ -135,9 +157,31 @@
/*non-public*/ MethodHandle spreadInvoker(int leadingArgCount) {
MethodHandle vaInvoker = spreadInvokers[leadingArgCount];
if (vaInvoker != null) return vaInvoker;
- MethodHandle gInvoker = generalInvoker();
int spreadArgCount = targetType.parameterCount() - leadingArgCount;
- vaInvoker = gInvoker.asSpreader(Object[].class, spreadArgCount);
+ MethodType spreadInvokerType = targetType
+ .replaceParameterTypes(leadingArgCount, targetType.parameterCount(), Object[].class);
+ if (targetType.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY) {
+ // Factor sinvoker.invoke(mh, a) into ginvoker.asSpreader().invoke(mh, a)
+ // where ginvoker.invoke(mh, a*) => mh.invoke(a*).
+ MethodHandle genInvoker = generalInvoker();
+ vaInvoker = genInvoker.asSpreader(Object[].class, spreadArgCount);
+ } else {
+ // Cannot build a general invoker here of type ginvoker.invoke(mh, a*[254]).
+ // Instead, factor sinvoker.invoke(mh, a) into ainvoker.invoke(filter(mh), a)
+ // where filter(mh) == mh.asSpreader(Object[], spreadArgCount)
+ MethodHandle arrayInvoker = MethodHandles.exactInvoker(spreadInvokerType);
+ MethodHandle makeSpreader;
+ try {
+ makeSpreader = IMPL_LOOKUP
+ .findVirtual(MethodHandle.class, "asSpreader",
+ MethodType.methodType(MethodHandle.class, Class.class, int.class));
+ } catch (ReflectiveOperationException ex) {
+ throw new InternalError(ex);
+ }
+ makeSpreader = MethodHandles.insertArguments(makeSpreader, 1, Object[].class, spreadArgCount);
+ vaInvoker = MethodHandles.filterArgument(arrayInvoker, 0, makeSpreader);
+ }
+ assert(vaInvoker.type().equals(spreadInvokerType.invokerType()));
spreadInvokers[leadingArgCount] = vaInvoker;
return vaInvoker;
}
@@ -171,7 +215,7 @@
.findStatic(CallSite.class, "uninitializedCallSite",
MethodType.methodType(Empty.class));
} catch (ReflectiveOperationException ex) {
- throw new RuntimeException(ex);
+ throw new InternalError(ex);
}
}
invoker = MethodHandles.explicitCastArguments(invoker, MethodType.methodType(targetType.returnType()));
@@ -185,30 +229,39 @@
return "Invokers"+targetType;
}
- private static MethodType fixMethodType(Class<?> callerClass, Object type) {
- if (type instanceof MethodType)
- return (MethodType) type;
- else
- return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
- }
-
- static MemberName exactInvokerMethod(Class<?> callerClass, Object type, Object[] appendixResult) {
- MethodType mtype = fixMethodType(callerClass, type);
- LambdaForm lform = invokeForm(mtype, MethodTypeForm.LF_EX_LINKER);
- appendixResult[0] = mtype;
+ static MemberName exactInvokerMethod(MethodType mtype, Object[] appendixResult) {
+ LambdaForm lform;
+ final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value
+ if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MTYPE_ARG_APPENDED) {
+ lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_LINKER);
+ appendixResult[0] = mtype;
+ } else {
+ lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_LINKER);
+ }
return lform.vmentry;
}
- static MemberName genericInvokerMethod(Class<?> callerClass, Object type, Object[] appendixResult) {
- MethodType mtype = fixMethodType(callerClass, type);
- LambdaForm lform = invokeForm(mtype, MethodTypeForm.LF_GEN_LINKER);
- prepareForGenericCall(mtype);
- appendixResult[0] = mtype;
+ static MemberName genericInvokerMethod(MethodType mtype, Object[] appendixResult) {
+ LambdaForm lform;
+ final int MTYPE_ARG_APPENDED = 1; // argument count for appended mtype value
+ if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - (MTYPE_ARG_APPENDED + GENERIC_INVOKER_SLOP)) {
+ lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_LINKER);
+ appendixResult[0] = mtype;
+ prepareForGenericCall(mtype);
+ } else {
+ lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_LINKER);
+ }
return lform.vmentry;
}
- private static LambdaForm invokeForm(MethodType mtype, int which) {
- mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
+ private static LambdaForm invokeForm(MethodType mtype, boolean customized, int which) {
+ boolean isCached;
+ if (!customized) {
+ mtype = mtype.basicType(); // normalize Z to I, String to Object, etc.
+ isCached = true;
+ } else {
+ isCached = false; // maybe cache if mtype == mtype.basicType()
+ }
boolean isLinker, isGeneric;
String debugName;
switch (which) {
@@ -218,27 +271,32 @@
case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true; debugName = "invoker"; break;
default: throw new InternalError();
}
- LambdaForm lform = mtype.form().cachedLambdaForm(which);
- if (lform != null) return lform;
+ LambdaForm lform;
+ if (isCached) {
+ lform = mtype.form().cachedLambdaForm(which);
+ if (lform != null) return lform;
+ }
// exactInvokerForm (Object,Object)Object
// link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
final int THIS_MH = 0;
final int CALL_MH = THIS_MH + (isLinker ? 0 : 1);
final int ARG_BASE = CALL_MH + 1;
final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
- final int INARG_LIMIT = OUTARG_LIMIT + (isLinker ? 1 : 0);
+ final int INARG_LIMIT = OUTARG_LIMIT + (isLinker && !customized ? 1 : 0);
int nameCursor = OUTARG_LIMIT;
- final int MTYPE_ARG = nameCursor++; // might be last in-argument
+ final int MTYPE_ARG = customized ? -1 : nameCursor++; // might be last in-argument
final int CHECK_TYPE = nameCursor++;
final int LINKER_CALL = nameCursor++;
MethodType invokerFormType = mtype.invokerType();
if (isLinker) {
- invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
+ if (!customized)
+ invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
} else {
invokerFormType = invokerFormType.invokerType();
}
Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
- assert(names.length == nameCursor);
+ assert(names.length == nameCursor)
+ : Arrays.asList(mtype, customized, which, nameCursor, names.length);
if (MTYPE_ARG >= INARG_LIMIT) {
assert(names[MTYPE_ARG] == null);
names[MTYPE_ARG] = BoundMethodHandle.getSpeciesData("L").getterName(names[THIS_MH], 0);
@@ -248,31 +306,42 @@
// Make the final call. If isGeneric, then prepend the result of type checking.
MethodType outCallType;
Object[] outArgs;
+ Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
if (!isGeneric) {
- names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], names[MTYPE_ARG]);
+ names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg);
// mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
outCallType = mtype;
+ } else if (customized) {
+ names[CHECK_TYPE] = new Name(NF_asType, names[CALL_MH], mtypeArg);
+ // mh.invokeGeneric(a*):R =>
+ // let mt=TYPEOF(a*:R), tmh=asType(mh, mt);
+ // tmh.invokeBasic(a*)
+ outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
+ outCallType = mtype;
} else {
- names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], names[MTYPE_ARG]);
+ names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg);
// mh.invokeGeneric(a*):R =>
// let mt=TYPEOF(a*:R), gamh=checkGenericType(mh, mt);
// gamh.invokeBasic(mt, mh, a*)
final int PREPEND_GAMH = 0, PREPEND_MT = 1, PREPEND_COUNT = 2;
+ assert(GENERIC_INVOKER_SLOP == PREPEND_COUNT);
outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
// prepend arguments:
System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
outArgs[PREPEND_GAMH] = names[CHECK_TYPE];
- outArgs[PREPEND_MT] = names[MTYPE_ARG];
+ outArgs[PREPEND_MT] = mtypeArg;
outCallType = mtype.insertParameterTypes(0, MethodType.class, MethodHandle.class);
}
names[LINKER_CALL] = new Name(invokeBasicMethod(outCallType), outArgs);
lform = new LambdaForm(debugName, INARG_LIMIT, names);
if (isLinker)
lform.compileToBytecode(); // JVM needs a real methodOop
- lform = mtype.form().setCachedLambdaForm(which, lform);
+ if (isCached)
+ lform = mtype.form().setCachedLambdaForm(which, lform);
return lform;
}
+ private static final int GENERIC_INVOKER_SLOP = 2; // used elsewhere to avoid arity problems
/*non-public*/ static
WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) {
@@ -370,6 +439,7 @@
// Local constant functions:
private static final NamedFunction NF_checkExactType;
private static final NamedFunction NF_checkGenericType;
+ private static final NamedFunction NF_asType;
private static final NamedFunction NF_getCallSiteTarget;
static {
try {
@@ -377,6 +447,8 @@
.getDeclaredMethod("checkExactType", Object.class, Object.class));
NF_checkGenericType = new NamedFunction(Invokers.class
.getDeclaredMethod("checkGenericType", Object.class, Object.class));
+ NF_asType = new NamedFunction(MethodHandle.class
+ .getDeclaredMethod("asType", MethodType.class));
NF_getCallSiteTarget = new NamedFunction(Invokers.class
.getDeclaredMethod("getCallSiteTarget", Object.class));
NF_checkExactType.resolve();
--- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java Fri Sep 14 10:14:02 2012 -0700
@@ -596,14 +596,7 @@
Object interpretWithArguments(Object... argumentValues) throws Throwable {
if (TRACE_INTERPRETER)
return interpretWithArgumentsTracing(argumentValues);
- if (COMPILE_THRESHOLD != 0 &&
- invocationCounter < COMPILE_THRESHOLD) {
- invocationCounter++; // benign race
- if (invocationCounter >= COMPILE_THRESHOLD) {
- // Replace vmentry with a bytecode version of this LF.
- compileToBytecode();
- }
- }
+ checkInvocationCounter();
assert(arityCheck(argumentValues));
Object[] values = Arrays.copyOf(argumentValues, names.length);
for (int i = argumentValues.length; i < values.length; i++) {
@@ -630,6 +623,16 @@
return name.function.invokeWithArguments(arguments);
}
+ private void checkInvocationCounter() {
+ if (COMPILE_THRESHOLD != 0 &&
+ invocationCounter < COMPILE_THRESHOLD) {
+ invocationCounter++; // benign race
+ if (invocationCounter >= COMPILE_THRESHOLD) {
+ // Replace vmentry with a bytecode version of this LF.
+ compileToBytecode();
+ }
+ }
+ }
Object interpretWithArgumentsTracing(Object... argumentValues) throws Throwable {
traceInterpreter("[ interpretWithArguments", this, argumentValues);
if (invocationCounter < COMPILE_THRESHOLD) {
@@ -703,7 +706,7 @@
}
public String toString() {
- StringBuilder buf = new StringBuilder("Lambda(");
+ StringBuilder buf = new StringBuilder(debugName+"=Lambda(");
for (int i = 0; i < names.length; i++) {
if (i == arity) buf.append(")=>{");
Name n = names[i];
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java Fri Sep 14 10:14:02 2012 -0700
@@ -306,12 +306,6 @@
return this;
}
- private void setFlags(int flags) {
- this.flags = flags;
- assert(testAnyFlags(ALL_KINDS));
- assert(referenceKindIsConsistent());
- }
-
private boolean testFlags(int mask, int value) {
return (flags & mask) == value;
}
@@ -452,8 +446,10 @@
this.clazz = defClass;
this.name = name;
this.type = type;
- setFlags(flags);
+ this.flags = flags;
+ assert(testAnyFlags(ALL_KINDS));
assert(this.resolution == null); // nobody should have touched this yet
+ //assert(referenceKindIsConsistent()); // do this after resolution
}
private void expandFromVM() {
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Fri Sep 14 10:14:02 2012 -0700
@@ -924,7 +924,7 @@
if (arrayType != type().parameterType(collectArgPos))
target = convertArguments(type().changeParameterType(collectArgPos, arrayType));
MethodHandle collector = ValueConversions.varargsArray(arrayType, arrayLength);
- return MethodHandleImpl.makeCollectArguments(target, collector, collectArgPos, false);
+ return MethodHandles.collectArguments(target, collectArgPos, collector);
}
// private API: return true if last param exactly matches arrayType
@@ -1226,7 +1226,7 @@
return "MethodHandle"+type;
}
String debugString() {
- return standardString()+"="+internalForm()+internalValues();
+ return standardString()+"/LF="+internalForm()+internalProperties();
}
//// Implementation methods.
@@ -1269,6 +1269,12 @@
/*non-public*/
Object internalValues() {
+ return null;
+ }
+
+ /*non-public*/
+ Object internalProperties() {
+ // Override to something like "/FOO=bar"
return "";
}
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Sep 14 10:14:02 2012 -0700
@@ -59,7 +59,7 @@
Name[] args = Arrays.copyOfRange(names, 1, 1 + srcType.parameterCount());
names[names.length - 1] = new Name(accessor.asType(srcType), (Object[]) args);
LambdaForm form = new LambdaForm("getElement", lambdaType.parameterCount(), names);
- MethodHandle mh = new SimpleMethodHandle(srcType, form);
+ MethodHandle mh = SimpleMethodHandle.make(srcType, form);
if (ArrayAccessor.needCast(arrayClass)) {
mh = mh.bindTo(arrayClass);
}
@@ -171,38 +171,46 @@
// Calculate extra arguments (temporaries) required in the names array.
// FIXME: Use an ArrayList<Name>. Some arguments require more than one conversion step.
- int extra = 0;
- for (int i = 0; i < srcType.parameterCount(); i++) {
- Class<?> src = srcType.parameterType(i);
- Class<?> dst = dstType.parameterType(i);
- if (!VerifyType.isNullConversion(src, dst)) {
- extra++;
+ final int INARG_COUNT = srcType.parameterCount();
+ int conversions = 0;
+ boolean[] needConv = new boolean[1+INARG_COUNT];
+ for (int i = 0; i <= INARG_COUNT; i++) {
+ Class<?> src = (i == INARG_COUNT) ? dstType.returnType() : srcType.parameterType(i);
+ Class<?> dst = (i == INARG_COUNT) ? srcType.returnType() : dstType.parameterType(i);
+ if (!VerifyType.isNullConversion(src, dst) ||
+ level <= 1 && dst.isInterface() && !dst.isAssignableFrom(src)) {
+ needConv[i] = true;
+ conversions++;
}
}
+ boolean retConv = needConv[INARG_COUNT];
- Class<?> needReturn = srcType.returnType();
- Class<?> haveReturn = dstType.returnType();
- boolean retConv = !VerifyType.isNullConversion(haveReturn, needReturn);
+ final int IN_MH = 0;
+ final int INARG_BASE = 1;
+ final int INARG_LIMIT = INARG_BASE + INARG_COUNT;
+ final int NAME_LIMIT = INARG_LIMIT + conversions + 1;
+ final int RETURN_CONV = (!retConv ? -1 : NAME_LIMIT - 1);
+ final int OUT_CALL = (!retConv ? NAME_LIMIT : RETURN_CONV) - 1;
// Now build a LambdaForm.
- MethodType lambdaType = srcType.invokerType();
- Name[] names = arguments(extra + 1, lambdaType);
- int[] indexes = new int[lambdaType.parameterCount()];
+ MethodType lambdaType = srcType.basicType().invokerType();
+ Name[] names = arguments(NAME_LIMIT - INARG_LIMIT, lambdaType);
+
+ // Collect the arguments to the outgoing call, maybe with conversions:
+ final int OUTARG_BASE = 0; // target MH is Name.function, name Name.arguments[0]
+ Object[] outArgs = new Object[OUTARG_BASE + INARG_COUNT];
- MethodType midType = dstType;
- for (int i = 0, argIndex = 1, tmpIndex = lambdaType.parameterCount(); i < srcType.parameterCount(); i++, argIndex++) {
+ int nameCursor = INARG_LIMIT;
+ for (int i = 0; i < INARG_COUNT; i++) {
Class<?> src = srcType.parameterType(i);
- Class<?> dst = midType.parameterType(i);
+ Class<?> dst = dstType.parameterType(i);
- if (VerifyType.isNullConversion(src, dst)) {
+ if (!needConv[i]) {
// do nothing: difference is trivial
- indexes[i] = argIndex;
+ outArgs[OUTARG_BASE + i] = names[INARG_BASE + i];
continue;
}
- // Work the current type backward toward the desired caller type:
- midType = midType.changeParameterType(i, src);
-
// Tricky case analysis follows.
MethodHandle fn = null;
if (src.isPrimitive()) {
@@ -246,33 +254,41 @@
fn = ValueConversions.cast(dst);
}
}
- names[tmpIndex] = new Name(fn, names[argIndex]);
- indexes[i] = tmpIndex;
- tmpIndex++;
+ Name conv = new Name(fn, names[INARG_BASE + i]);
+ assert(names[nameCursor] == null);
+ names[nameCursor++] = conv;
+ assert(outArgs[OUTARG_BASE + i] == null);
+ outArgs[OUTARG_BASE + i] = conv;
}
- if (retConv) {
- MethodHandle adjustReturn;
+
+ // Build argument array for the call.
+ assert(nameCursor == OUT_CALL);
+ names[OUT_CALL] = new Name(target, outArgs);
+
+ if (RETURN_CONV < 0) {
+ assert(OUT_CALL == names.length-1);
+ } else {
+ Class<?> needReturn = srcType.returnType();
+ Class<?> haveReturn = dstType.returnType();
+ MethodHandle fn;
+ Object[] arg = { names[OUT_CALL] };
if (haveReturn == void.class) {
// synthesize a zero value for the given void
Object zero = Wrapper.forBasicType(needReturn).zero();
- adjustReturn = MethodHandles.constant(needReturn, zero);
+ fn = MethodHandles.constant(needReturn, zero);
+ arg = new Object[0]; // don't pass names[OUT_CALL] to conversion
} else {
MethodHandle identity = MethodHandles.identity(needReturn);
MethodType needConversion = identity.type().changeParameterType(0, haveReturn);
- adjustReturn = makePairwiseConvert(identity, needConversion, level);
+ fn = makePairwiseConvert(identity, needConversion, level);
}
- target = makeCollectArguments(adjustReturn, target, 0, false);
+ assert(names[RETURN_CONV] == null);
+ names[RETURN_CONV] = new Name(fn, arg);
+ assert(RETURN_CONV == names.length-1);
}
- // Build argument array for the call.
- Name[] targetArgs = new Name[dstType.parameterCount()];
- for (int i = 0; i < dstType.parameterCount(); i++) {
- int idx = indexes[i];
- targetArgs[i] = names[idx];
- }
- names[names.length - 1] = new Name(target, (Object[]) targetArgs);
LambdaForm form = new LambdaForm("convert", lambdaType.parameterCount(), names);
- return new SimpleMethodHandle(srcType, form);
+ return SimpleMethodHandle.make(srcType, form);
}
static MethodHandle makeReferenceIdentity(Class<?> refType) {
@@ -280,7 +296,7 @@
Name[] names = arguments(1, lambdaType);
names[names.length - 1] = new Name(ValueConversions.identity(), names[1]);
LambdaForm form = new LambdaForm("identity", lambdaType.parameterCount(), names);
- return new SimpleMethodHandle(MethodType.methodType(refType, refType), form);
+ return SimpleMethodHandle.make(MethodType.methodType(refType, refType), form);
}
static MethodHandle makeVarargsCollector(MethodHandle target, Class<?> arrayType) {
@@ -334,8 +350,9 @@
MethodHandle collector;
try {
collector = asFixedArity().asCollector(arrayType, arrayLength);
+ assert(collector.type().parameterCount() == newArity) : "newArity="+newArity+" but collector="+collector;
} catch (IllegalArgumentException ex) {
- throw new WrongMethodTypeException("cannot build collector");
+ throw new WrongMethodTypeException("cannot build collector", ex);
}
cache = collector;
return collector.asType(newType);
@@ -429,12 +446,18 @@
names[names.length - 1] = new Name(target, (Object[]) targetArgs);
LambdaForm form = new LambdaForm("spread", lambdaType.parameterCount(), names);
- return new SimpleMethodHandle(srcType, form);
+ return SimpleMethodHandle.make(srcType, form);
}
static void checkSpreadArgument(Object av, int n) {
+ // FIXME: regression test for bug 7141637 erroneously expects an NPE, and other tests may expect IAE
+ // but the actual exception raised by an arity mismatch should be WMTE
+ final boolean RAISE_RANDOM_EXCEPTIONS = true; // FIXME: delete in JSR 292 M1
if (av == null) {
if (n == 0) return;
+ int len;
+ if (RAISE_RANDOM_EXCEPTIONS)
+ len = ((Object[])av).length; // throw NPE; but delete this after tests are fixed
} else if (av instanceof Object[]) {
int len = ((Object[])av).length;
if (len == n) return;
@@ -443,7 +466,9 @@
if (len == n) return;
}
// fall through to error:
- throw newIllegalArgumentException("Array is not of length "+n);
+ if (RAISE_RANDOM_EXCEPTIONS)
+ throw newIllegalArgumentException("Array is not of length "+n);
+ throw new WrongMethodTypeException("Array is not of length "+n);
}
private static final NamedFunction NF_checkSpreadArgument;
@@ -508,7 +533,7 @@
names[targetNamePos] = new Name(target, (Object[]) targetArgs);
LambdaForm form = new LambdaForm("collect", lambdaType.parameterCount(), names);
- return new SimpleMethodHandle(srcType, form);
+ return SimpleMethodHandle.make(srcType, form);
}
static
@@ -555,7 +580,7 @@
names[arity + 3] = new Name(new NamedFunction(invokeBasic), targetArgs);
LambdaForm form = new LambdaForm("guard", lambdaType.parameterCount(), names);
- return new SimpleMethodHandle(target.type(), form);
+ return SimpleMethodHandle.make(target.type(), form);
}
private static class GuardWithCatch {
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Fri Sep 14 10:14:02 2012 -0700
@@ -325,15 +325,28 @@
static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
Class<?> defc, String name, Object type,
Object[] appendixResult) {
- if (defc != MethodHandle.class || refKind != REF_invokeVirtual)
- throw new LinkageError("no such method "+defc.getName()+"."+name+type);
- switch (name) {
- case "invoke":
- return Invokers.genericInvokerMethod(callerClass, type, appendixResult);
- case "invokeExact":
- return Invokers.exactInvokerMethod(callerClass, type, appendixResult);
+ try {
+ if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
+ switch (name) {
+ case "invoke":
+ return Invokers.genericInvokerMethod(fixMethodType(callerClass, type), appendixResult);
+ case "invokeExact":
+ return Invokers.exactInvokerMethod(fixMethodType(callerClass, type), appendixResult);
+ }
+ }
+ } catch (Throwable ex) {
+ if (ex instanceof LinkageError)
+ throw (LinkageError) ex;
+ else
+ throw new LinkageError(ex.getMessage(), ex);
}
- throw new UnsupportedOperationException("linkMethod "+name);
+ throw new LinkageError("no such method "+defc.getName()+"."+name+type);
+ }
+ private static MethodType fixMethodType(Class<?> callerClass, Object type) {
+ if (type instanceof MethodType)
+ return (MethodType) type;
+ else
+ return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
}
// Tracing logic:
static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
@@ -351,6 +364,7 @@
}
}
+
/**
* The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
* It will make an up-call to this method. (Do not change the name or signature.)
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Fri Sep 14 10:14:02 2012 -0700
@@ -1876,6 +1876,17 @@
return MethodHandleImpl.makeCollectArguments(target, filter, pos, false);
}
+ // FIXME: Make this public in M1.
+ /*non-public*/ static
+ MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle collector) {
+ MethodType targetType = target.type();
+ MethodType filterType = collector.type();
+ if (filterType.returnType() != void.class &&
+ filterType.returnType() != targetType.parameterType(pos))
+ throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+ return MethodHandleImpl.makeCollectArguments(target, collector, pos, false);
+ }
+
/**
* Adapts a target method handle by post-processing
* its return value (if any) with a filter (another method handle).
--- a/jdk/src/share/classes/java/lang/invoke/MethodType.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java Fri Sep 14 10:14:02 2012 -0700
@@ -111,6 +111,36 @@
void setForm(MethodTypeForm f) { form = f; }
+ /** This number, mandated by the JVM spec as 255,
+ * is the maximum number of <em>slots</em>
+ * that any Java method can receive in its argument list.
+ * It limits both JVM signatures and method type objects.
+ * The longest possible invocation will look like
+ * {@code staticMethod(arg1, arg2, ..., arg255)} or
+ * {@code x.virtualMethod(arg1, arg2, ..., arg254)}.
+ */
+ /*non-public*/ static final int MAX_JVM_ARITY = 255; // this is mandated by the JVM spec.
+
+ /** This number is the maximum arity of a method handle, 254.
+ * It is derived from the absolute JVM-imposed arity by subtracting one,
+ * which is the slot occupied by the method handle itself at the
+ * beginning of the argument list used to invoke the method handle.
+ * The longest possible invocation will look like
+ * {@code mh.invoke(arg1, arg2, ..., arg254)}.
+ */
+ // Issue: Should we allow MH.invokeWithArguments to go to the full 255?
+ /*non-public*/ static final int MAX_MH_ARITY = MAX_JVM_ARITY-1; // deduct one for mh receiver
+
+ /** This number is the maximum arity of a method handle invoker, 253.
+ * It is derived from the absolute JVM-imposed arity by subtracting two,
+ * which are the slots occupied by invoke method handle, and the the
+ * target method handle, which are both at the beginning of the argument
+ * list used to invoke the target method handle.
+ * The longest possible invocation will look like
+ * {@code invokermh.invoke(targetmh, arg1, arg2, ..., arg253)}.
+ */
+ /*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1; // deduct one more for invoker
+
private static void checkRtype(Class<?> rtype) {
rtype.equals(rtype); // null check
}
@@ -131,7 +161,9 @@
return slots;
}
static void checkSlotCount(int count) {
- if ((count & 0xFF) != count)
+ assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0);
+ // MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
+ if ((count & MAX_JVM_ARITY) != count)
throw newIllegalArgumentException("bad parameter count "+count);
}
private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num) {
--- a/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java Fri Sep 14 10:14:02 2012 -0700
@@ -35,10 +35,14 @@
* @author jrose
*/
final class SimpleMethodHandle extends MethodHandle {
- SimpleMethodHandle(MethodType type, LambdaForm form) {
+ private SimpleMethodHandle(MethodType type, LambdaForm form) {
super(type, form);
}
+ /*non-public*/ static SimpleMethodHandle make(MethodType type, LambdaForm form) {
+ return new SimpleMethodHandle(type, form);
+ }
+
@Override
MethodHandle bindArgument(int pos, char basicType, Object value) {
MethodType type2 = type().dropParameterTypes(pos, pos+1);
--- a/jdk/src/share/classes/java/lang/invoke/WrongMethodTypeException.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/java/lang/invoke/WrongMethodTypeException.java Fri Sep 14 10:14:02 2012 -0700
@@ -59,4 +59,27 @@
public WrongMethodTypeException(String s) {
super(s);
}
+
+ /**
+ * Constructs a {@code WrongMethodTypeException} with the specified
+ * detail message and cause.
+ *
+ * @param s the detail message.
+ * @param cause the cause of the exception, or null.
+ */
+ //FIXME: make this public in MR1
+ /*non-public*/ WrongMethodTypeException(String s, Throwable cause) {
+ super(s, cause);
+ }
+
+ /**
+ * Constructs a {@code WrongMethodTypeException} with the specified
+ * cause.
+ *
+ * @param cause the cause of the exception, or null.
+ */
+ //FIXME: make this public in MR1
+ /*non-public*/ WrongMethodTypeException(Throwable cause) {
+ super(cause);
+ }
}
--- a/jdk/src/share/classes/sun/awt/AWTAccessor.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/sun/awt/AWTAccessor.java Fri Sep 14 10:14:02 2012 -0700
@@ -667,6 +667,21 @@
}
/*
+ * An accessor for the SequencedEventAccessor class
+ */
+ public interface SequencedEventAccessor {
+ /*
+ * Returns the nested event.
+ */
+ AWTEvent getNested(AWTEvent sequencedEvent);
+
+ /*
+ * Returns true if the event is an instances of SequencedEvent.
+ */
+ boolean isSequencedEvent(AWTEvent event);
+ }
+
+ /*
* Accessor instances are initialized in the static initializers of
* corresponding AWT classes by using setters defined below.
*/
@@ -692,6 +707,7 @@
private static SystemTrayAccessor systemTrayAccessor;
private static TrayIconAccessor trayIconAccessor;
private static DefaultKeyboardFocusManagerAccessor defaultKeyboardFocusManagerAccessor;
+ private static SequencedEventAccessor sequencedEventAccessor;
/*
* Set an accessor object for the java.awt.Component class.
@@ -1069,4 +1085,20 @@
}
return defaultKeyboardFocusManagerAccessor;
}
+ /*
+ * Set an accessor object for the java.awt.SequencedEvent class.
+ */
+ public static void setSequencedEventAccessor(SequencedEventAccessor sea) {
+ sequencedEventAccessor = sea;
+ }
+
+ /*
+ * Get the accessor object for the java.awt.SequencedEvent class.
+ */
+ public static SequencedEventAccessor getSequencedEventAccessor() {
+ // The class is not public. So we can't ensure it's initialized.
+ // Null returned value means it's not initialized
+ // (so not a single instance of the event has been created).
+ return sequencedEventAccessor;
+ }
}
--- a/jdk/src/share/classes/sun/awt/HToolkit.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/sun/awt/HToolkit.java Fri Sep 14 10:14:02 2012 -0700
@@ -44,6 +44,14 @@
public class HToolkit extends SunToolkit
implements ComponentFactory {
+ private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
+ public void setCurrentFocusedWindow(Window win) {}
+ public Window getCurrentFocusedWindow() { return null; }
+ public void setCurrentFocusOwner(Component comp) {}
+ public Component getCurrentFocusOwner() { return null; }
+ public void clearGlobalFocusOwner(Window activeWindow) {}
+ };
+
public HToolkit() {
}
@@ -152,15 +160,9 @@
throw new HeadlessException();
}
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
// See 6833019.
- return
- new KeyboardFocusManagerPeer() {
- public Window getCurrentFocusedWindow() { return null; }
- public void setCurrentFocusOwner(Component comp) {}
- public Component getCurrentFocusOwner() { return null; }
- public void clearGlobalFocusOwner(Window activeWindow) {}
- };
+ return kfmPeer;
}
public TrayIconPeer createTrayIcon(TrayIcon target)
--- a/jdk/src/share/classes/sun/awt/HeadlessToolkit.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/sun/awt/HeadlessToolkit.java Fri Sep 14 10:14:02 2012 -0700
@@ -30,22 +30,25 @@
import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.event.*;
import java.awt.im.InputMethodHighlight;
-import java.awt.im.spi.InputMethodDescriptor;
import java.awt.image.*;
import java.awt.datatransfer.Clipboard;
import java.awt.peer.*;
import java.beans.PropertyChangeListener;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.Map;
import java.util.Properties;
-import sun.awt.im.InputContext;
-import sun.awt.image.ImageRepresentation;
public class HeadlessToolkit extends Toolkit
implements ComponentFactory, KeyboardFocusManagerPeerProvider {
+ private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
+ public void setCurrentFocusedWindow(Window win) {}
+ public Window getCurrentFocusedWindow() { return null; }
+ public void setCurrentFocusOwner(Component comp) {}
+ public Component getCurrentFocusOwner() { return null; }
+ public void clearGlobalFocusOwner(Window activeWindow) {}
+ };
+
private Toolkit tk;
private ComponentFactory componentFactory;
@@ -179,15 +182,9 @@
throw new HeadlessException();
}
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
// See 6833019.
- return
- new KeyboardFocusManagerPeer() {
- public Window getCurrentFocusedWindow() { return null; }
- public void setCurrentFocusOwner(Component comp) {}
- public Component getCurrentFocusOwner() { return null; }
- public void clearGlobalFocusOwner(Window activeWindow) {}
- };
+ return kfmPeer;
}
public TrayIconPeer createTrayIcon(TrayIcon target)
--- a/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java Fri Sep 14 10:14:02 2012 -0700
@@ -53,12 +53,6 @@
public static final int SNFH_SUCCESS_HANDLED = 1;
public static final int SNFH_SUCCESS_PROCEED = 2;
- protected KeyboardFocusManager manager;
-
- public KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) {
- this.manager = manager;
- }
-
@Override
public void clearGlobalFocusOwner(Window activeWindow) {
if (activeWindow != null) {
@@ -134,7 +128,7 @@
if (focusLog.isLoggable(PlatformLogger.FINER))
focusLog.finer("Posting focus event: " + fl);
- SunToolkit.postPriorityEvent(fl);
+ SunToolkit.postEvent(SunToolkit.targetToAppContext(currentOwner), fl);
}
FocusEvent fg = new CausedFocusEvent(lightweightChild, FocusEvent.FOCUS_GAINED,
@@ -142,7 +136,7 @@
if (focusLog.isLoggable(PlatformLogger.FINER))
focusLog.finer("Posting focus event: " + fg);
- SunToolkit.postPriorityEvent(fg);
+ SunToolkit.postEvent(SunToolkit.targetToAppContext(lightweightChild), fg);
return true;
}
--- a/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerProvider.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerProvider.java Fri Sep 14 10:14:02 2012 -0700
@@ -25,20 +25,19 @@
package sun.awt;
-import java.awt.KeyboardFocusManager;
import java.awt.peer.KeyboardFocusManagerPeer;
/**
* {@link KeyboardFocusManagerPeerProvider} is required to be implemented by
* the currently used {@link java.awt.Toolkit} instance. In order to initialize
- * {@link java.awt.KeyboardFocusManager}, an instance of {@link KeyboardFocusManagerPeer}
- * is needed. To create that instance, the {@link #createKeyboardFocusManagerPeer}
+ * {@link java.awt.KeyboardFocusManager}, a singleton instance of {@link KeyboardFocusManagerPeer}
+ * is needed. To obtain that instance, the {@link #getKeyboardFocusManagerPeer}
* method of the current toolkit is called.
*/
public interface KeyboardFocusManagerPeerProvider {
/**
- * Creates a KeyboardFocusManagerPeer for the specified KeyboardFocusManager.
+ * Gets a singleton KeyboardFocusManagerPeer instance.
*/
- KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager);
+ KeyboardFocusManagerPeer getKeyboardFocusManagerPeer();
}
--- a/jdk/src/share/classes/sun/awt/SunToolkit.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/sun/awt/SunToolkit.java Fri Sep 14 10:14:02 2012 -0700
@@ -197,7 +197,7 @@
public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
throws AWTException;
- public abstract KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
+ public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
throws HeadlessException;
/**
@@ -463,6 +463,19 @@
if (event == null) {
throw new NullPointerException();
}
+
+ AWTAccessor.SequencedEventAccessor sea = AWTAccessor.getSequencedEventAccessor();
+ if (sea != null && sea.isSequencedEvent(event)) {
+ AWTEvent nested = sea.getNested(event);
+ if (nested.getID() == WindowEvent.WINDOW_LOST_FOCUS &&
+ nested instanceof TimedWindowEvent)
+ {
+ TimedWindowEvent twe = (TimedWindowEvent)nested;
+ ((SunToolkit)Toolkit.getDefaultToolkit()).
+ setWindowDeactivationTime((Window)twe.getSource(), twe.getWhen());
+ }
+ }
+
// All events posted via this method are system-generated.
// Placing the following call here reduces considerably the
// number of places throughout the toolkit that would
@@ -1863,6 +1876,28 @@
return false;
}
+ private static final Object DEACTIVATION_TIMES_MAP_KEY = new Object();
+
+ public synchronized void setWindowDeactivationTime(Window w, long time) {
+ AppContext ctx = getAppContext(w);
+ WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
+ if (map == null) {
+ map = new WeakHashMap<Window, Long>();
+ ctx.put(DEACTIVATION_TIMES_MAP_KEY, map);
+ }
+ map.put(w, time);
+ }
+
+ public synchronized long getWindowDeactivationTime(Window w) {
+ AppContext ctx = getAppContext(w);
+ WeakHashMap<Window, Long> map = (WeakHashMap<Window, Long>)ctx.get(DEACTIVATION_TIMES_MAP_KEY);
+ if (map == null) {
+ return -1;
+ }
+ Long time = map.get(w);
+ return time == null ? -1 : time;
+ }
+
// Cosntant alpha
public boolean isWindowOpacitySupported() {
return false;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/sun/awt/TimedWindowEvent.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,51 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.awt;
+
+import java.awt.event.WindowEvent;
+import java.awt.Window;
+
+public class TimedWindowEvent extends WindowEvent {
+
+ private long time;
+
+ public long getWhen() {
+ return time;
+ }
+
+ public TimedWindowEvent(Window source, int id, Window opposite, long time) {
+ super(source, id, opposite);
+ this.time = time;
+ }
+
+ public TimedWindowEvent(Window source, int id, Window opposite,
+ int oldState, int newState, long time)
+ {
+ super(source, id, opposite, oldState, newState);
+ this.time = time;
+ }
+}
+
--- a/jdk/src/share/classes/sun/invoke/util/ValueConversions.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java Fri Sep 14 10:14:02 2012 -0700
@@ -44,6 +44,7 @@
static {
final Object[] values = { 255 };
AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
public Void run() {
values[0] = Integer.getInteger(THIS_CLASS.getName()+".MAX_ARITY", 255);
return null;
@@ -182,7 +183,7 @@
*/
public static Number primitiveConversion(Wrapper wrap, Object x, boolean cast) {
// Maybe merge this code with Wrapper.convert/cast.
- Number res = null;
+ Number res;
if (x == null) {
if (!cast) return null;
return ZERO_INT;
@@ -322,11 +323,9 @@
static void ignore(Object x) {
// no value to return; this is an unbox of null
- return;
}
static void empty() {
- return;
}
static Object zeroObject() {
@@ -390,24 +389,6 @@
/// Converting references to references.
/**
- * Value-killing function.
- * @param x an arbitrary reference value
- * @return a null
- */
- static Object alwaysNull(Object x) {
- return null;
- }
-
- /**
- * Value-killing function.
- * @param x an arbitrary reference value
- * @return a zero
- */
- static int alwaysZero(Object x) {
- return 0;
- }
-
- /**
* Identity function.
* @param x an arbitrary reference value
* @return the same value x
@@ -416,6 +397,10 @@
return x;
}
+ static <T> T[] identity(T[] x) {
+ return x;
+ }
+
/**
* Identity function on ints.
* @param x an arbitrary int value
@@ -468,29 +453,33 @@
return t.cast(x);
}
- private static final MethodHandle IDENTITY, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY, NEW_ARRAY;
+ private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY,
+ ARRAY_IDENTITY, FILL_NEW_TYPED_ARRAY, FILL_NEW_ARRAY;
static {
try {
MethodType idType = MethodType.genericMethodType(1);
MethodType castType = idType.insertParameterTypes(0, Class.class);
- MethodType alwaysZeroType = idType.changeReturnType(int.class);
MethodType ignoreType = idType.changeReturnType(void.class);
MethodType zeroObjectType = MethodType.genericMethodType(0);
IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
//CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType);
- ALWAYS_NULL = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysNull", idType);
- ALWAYS_ZERO = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysZero", alwaysZeroType);
ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
- NEW_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "newArray", MethodType.methodType(Object[].class, int.class));
+ ARRAY_IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(Object[].class, Object[].class));
+ FILL_NEW_ARRAY = IMPL_LOOKUP
+ .findStatic(THIS_CLASS, "fillNewArray",
+ MethodType.methodType(Object[].class, Integer.class, Object[].class));
+ FILL_NEW_TYPED_ARRAY = IMPL_LOOKUP
+ .findStatic(THIS_CLASS, "fillNewTypedArray",
+ MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
} catch (NoSuchMethodException | IllegalAccessException ex) {
throw new InternalError("uncaught exception", ex);
}
}
- // Varargs methods need to be in a separately initialized class, to bootstrapping problems.
+ // Varargs methods need to be in a separately initialized class, to avoid bootstrapping problems.
static class LazyStatics {
private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST;
static {
@@ -505,34 +494,64 @@
}
}
+ static MethodHandle collectArguments(MethodHandle mh, int pos, MethodHandle collector) {
+ // FIXME: API needs public MHs.collectArguments.
+ // Should be:
+ // return MethodHandles.collectArguments(mh, 0, collector);
+ // The rest of this code is a workaround for not having that API.
+ if (COLLECT_ARGUMENTS != null) {
+ try {
+ return (MethodHandle)
+ COLLECT_ARGUMENTS.invokeExact(mh, pos, collector);
+ } catch (Throwable ex) {
+ if (ex instanceof RuntimeException)
+ throw (RuntimeException) ex;
+ if (ex instanceof Error)
+ throw (Error) ex;
+ throw new Error(ex.getMessage(), ex);
+ }
+ }
+ // Emulate MHs.collectArguments using fold + drop.
+ // This is slightly inefficient.
+ // More seriously, it can put a MH over the 255-argument limit.
+ mh = MethodHandles.dropArguments(mh, 1, collector.type().parameterList());
+ mh = MethodHandles.foldArguments(mh, collector);
+ return mh;
+ }
+ private static final MethodHandle COLLECT_ARGUMENTS;
+ static {
+ MethodHandle mh = null;
+ try {
+ java.lang.reflect.Method m = MethodHandles.class
+ .getDeclaredMethod("collectArguments",
+ MethodHandle.class, int.class, MethodHandle.class);
+ m.setAccessible(true);
+ mh = IMPL_LOOKUP.unreflect(m);
+
+ } catch (ReflectiveOperationException | SecurityException ex) {
+ throw new InternalError(ex);
+ }
+ COLLECT_ARGUMENTS = mh;
+ }
+
private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
- = newWrapperCaches(2);
+ = newWrapperCaches(1);
/** Return a method that casts its sole argument (an Object) to the given type
- * and returns it as the given type (if exact is true), or as plain Object (if erase is true).
+ * and returns it as the given type.
*/
public static MethodHandle cast(Class<?> type) {
- boolean exact = false;
if (type.isPrimitive()) throw new IllegalArgumentException("cannot cast primitive type "+type);
- MethodHandle mh = null;
+ MethodHandle mh;
Wrapper wrap = null;
EnumMap<Wrapper, MethodHandle> cache = null;
if (Wrapper.isWrapperType(type)) {
wrap = Wrapper.forWrapperType(type);
- cache = WRAPPER_CASTS[exact?1:0];
+ cache = WRAPPER_CASTS[0];
mh = cache.get(wrap);
if (mh != null) return mh;
}
- if (VerifyType.isNullReferenceConversion(Object.class, type))
- mh = IDENTITY;
- else if (VerifyType.isNullType(type))
- mh = ALWAYS_NULL;
- else
- mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
- if (exact) {
- MethodType xmt = MethodType.methodType(type, Object.class);
- mh = MethodHandles.explicitCastArguments(mh, xmt);
- }
+ mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
if (cache != null)
cache.put(wrap, mh);
return mh;
@@ -920,37 +939,47 @@
}
private static final MethodHandle[] ARRAYS = makeArrays();
- // mh-fill versions of the above:
- private static Object[] newArray(int len) { return new Object[len]; }
+ // filling versions of the above:
+ // using Integer len instead of int len and no varargs to avoid bootstrapping problems
+ private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
+ Object[] a = new Object[len];
+ fillWithArguments(a, 0, args);
+ return a;
+ }
+ private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
+ Object[] a = Arrays.copyOf(example, len);
+ fillWithArguments(a, 0, args);
+ return a;
+ }
private static void fillWithArguments(Object[] a, int pos, Object... args) {
System.arraycopy(args, 0, a, pos, args.length);
}
// using Integer pos instead of int pos to avoid bootstrapping problems
- private static Object[] fillArray(Object[] a, Integer pos, Object a0)
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0)
{ fillWithArguments(a, pos, a0); return a; }
- private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1)
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
{ fillWithArguments(a, pos, a0, a1); return a; }
- private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2)
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
{ fillWithArguments(a, pos, a0, a1, a2); return a; }
- private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3)
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
{ fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
- private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
- private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
- private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
- private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
- private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
- private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+ private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
Object a4, Object a5, Object a6, Object a7,
Object a8, Object a9)
{ fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
@@ -958,7 +987,7 @@
ArrayList<MethodHandle> mhs = new ArrayList<>();
mhs.add(null); // there is no empty fill; at least a0 is required
for (;;) {
- MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Object[].class, Integer.class);
+ MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
if (mh == null) break;
mhs.add(mh);
}
@@ -984,69 +1013,95 @@
if (mh != null) return mh;
mh = findCollector("array", nargs, Object[].class);
if (mh != null) return ARRAYS[nargs] = mh;
- MethodHandle producer = filler(0); // identity function produces result
- return ARRAYS[nargs] = buildVarargsArray(producer, nargs);
+ mh = buildVarargsArray(FILL_NEW_ARRAY, ARRAY_IDENTITY, nargs);
+ assert(assertCorrectArity(mh, nargs));
+ return ARRAYS[nargs] = mh;
+ }
+
+ private static boolean assertCorrectArity(MethodHandle mh, int arity) {
+ assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
+ return true;
}
- private static MethodHandle buildVarargsArray(MethodHandle producer, int nargs) {
+ private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
// Build up the result mh as a sequence of fills like this:
- // producer(fill(fill(fill(newArray(23),0,x1..x10),10,x11..x20),20,x21..x23))
+ // finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
// The various fill(_,10*I,___*[J]) are reusable.
- MethodHandle filler = filler(nargs);
- MethodHandle mh = producer;
- mh = MethodHandles.dropArguments(mh, 1, filler.type().parameterList());
- mh = MethodHandles.foldArguments(mh, filler);
- mh = MethodHandles.foldArguments(mh, buildNewArray(nargs));
+ int leftLen = Math.min(nargs, LEFT_ARGS); // absorb some arguments immediately
+ int rightLen = nargs - leftLen;
+ MethodHandle leftCollector = newArray.bindTo(nargs);
+ leftCollector = leftCollector.asCollector(Object[].class, leftLen);
+ MethodHandle mh = finisher;
+ if (rightLen > 0) {
+ MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
+ if (mh == ARRAY_IDENTITY)
+ mh = rightFiller;
+ else
+ mh = collectArguments(mh, 0, rightFiller);
+ }
+ if (mh == ARRAY_IDENTITY)
+ mh = leftCollector;
+ else
+ mh = collectArguments(mh, 0, leftCollector);
return mh;
}
- private static MethodHandle buildNewArray(int nargs) {
- return MethodHandles.insertArguments(NEW_ARRAY, 0, nargs);
- }
-
- private static final MethodHandle[] FILLERS = new MethodHandle[MAX_ARITY+1];
- // filler(N).invoke(a, arg0..arg[N-1]) fills a[0]..a[N-1]
- private static MethodHandle filler(int nargs) {
- MethodHandle filler = FILLERS[nargs];
+ private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1);
+ private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
+ /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
+ * fills a[L]..a[N-1] with corresponding arguments,
+ * and then returns a. The value L is a global constant (LEFT_ARGS).
+ */
+ private static MethodHandle fillToRight(int nargs) {
+ MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
if (filler != null) return filler;
- return FILLERS[nargs] = buildFiller(nargs);
+ filler = buildFiller(nargs);
+ assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
+ return FILL_ARRAY_TO_RIGHT[nargs] = filler;
}
private static MethodHandle buildFiller(int nargs) {
- if (nargs == 0)
- return MethodHandles.identity(Object[].class);
- final int CHUNK = (FILL_ARRAYS.length - 1);
+ if (nargs <= LEFT_ARGS)
+ return ARRAY_IDENTITY; // no args to fill; return the array unchanged
+ // we need room for both mh and a in mh.invoke(a, arg*[nargs])
+ final int CHUNK = LEFT_ARGS;
int rightLen = nargs % CHUNK;
- int leftLen = nargs - rightLen;
+ int midLen = nargs - rightLen;
if (rightLen == 0) {
- leftLen = nargs - (rightLen = CHUNK);
- if (FILLERS[leftLen] == null) {
+ midLen = nargs - (rightLen = CHUNK);
+ if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
// build some precursors from left to right
- for (int j = 0; j < leftLen; j += CHUNK) filler(j);
+ for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
+ if (j > LEFT_ARGS) fillToRight(j);
}
}
- MethodHandle leftFill = filler(leftLen); // recursive fill
- MethodHandle rightFill = FILL_ARRAYS[rightLen];
- rightFill = MethodHandles.insertArguments(rightFill, 1, leftLen); // [leftLen..nargs-1]
+ if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
+ assert(rightLen > 0);
+ MethodHandle midFill = fillToRight(midLen); // recursive fill
+ MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen); // [midLen..nargs-1]
+ assert(midFill.type().parameterCount() == 1 + midLen - LEFT_ARGS);
+ assert(rightFill.type().parameterCount() == 1 + rightLen);
- // Combine the two fills: right(left(newArray(nargs), x1..x20), x21..x23)
- MethodHandle mh = filler(0); // identity function produces result
- mh = MethodHandles.dropArguments(mh, 1, rightFill.type().parameterList());
- mh = MethodHandles.foldArguments(mh, rightFill);
- if (leftLen > 0) {
- mh = MethodHandles.dropArguments(mh, 1, leftFill.type().parameterList());
- mh = MethodHandles.foldArguments(mh, leftFill);
- }
- return mh;
+ // Combine the two fills:
+ // right(mid(a, x10..x19), x20..x23)
+ // The final product will look like this:
+ // right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
+ if (midLen == LEFT_ARGS)
+ return rightFill;
+ else
+ return collectArguments(rightFill, 0, midFill);
}
// Type-polymorphic version of varargs maker.
private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
= new ClassValue<MethodHandle[]>() {
+ @Override
protected MethodHandle[] computeValue(Class<?> type) {
return new MethodHandle[256];
}
};
+ static final int MAX_JVM_ARITY = 255; // limit imposed by the JVM
+
/** Return a method handle that takes the indicated number of
* typed arguments and returns an array of them.
* The type argument is the array type.
@@ -1055,16 +1110,36 @@
Class<?> elemType = arrayType.getComponentType();
if (elemType == null) throw new IllegalArgumentException("not an array: "+arrayType);
// FIXME: Need more special casing and caching here.
+ if (nargs >= MAX_JVM_ARITY/2 - 1) {
+ int slots = nargs;
+ final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1; // 1 for receiver MH
+ if (arrayType == double[].class || arrayType == long[].class)
+ slots *= 2;
+ if (slots > MAX_ARRAY_SLOTS)
+ throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
+ }
if (elemType == Object.class)
return varargsArray(nargs);
// other cases: primitive arrays, subtypes of Object[]
MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
if (mh != null) return mh;
- MethodHandle producer = buildArrayProducer(arrayType);
- mh = buildVarargsArray(producer, nargs);
+ if (elemType.isPrimitive()) {
+ MethodHandle builder = FILL_NEW_ARRAY;
+ MethodHandle producer = buildArrayProducer(arrayType);
+ mh = buildVarargsArray(builder, producer, nargs);
+ } else {
+ @SuppressWarnings("unchecked")
+ Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType;
+ Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
+ MethodHandle builder = FILL_NEW_TYPED_ARRAY.bindTo(example);
+ MethodHandle producer = ARRAY_IDENTITY;
+ mh = buildVarargsArray(builder, producer, nargs);
+ }
mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
- cache[nargs] = mh;
+ assert(assertCorrectArity(mh, nargs));
+ if (nargs < cache.length)
+ cache[nargs] = mh;
return mh;
}
--- a/jdk/src/share/demo/applets/CardTest/example1.html Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/demo/applets/CardTest/example1.html Fri Sep 14 10:14:02 2012 -0700
@@ -5,7 +5,7 @@
<body>
<h1>Card Test (1.1)</h1>
<hr>
- <applet code=CardTest.class width=400 height=300>
+ <applet code=CardTest.class width=455 height=300>
alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason."
Your browser is completely ignoring the <APPLET> tag!
</applet>
--- a/jdk/src/share/demo/applets/DitherTest/example1.html Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/demo/applets/DitherTest/example1.html Fri Sep 14 10:14:02 2012 -0700
@@ -5,7 +5,7 @@
<body>
<h1>Dither Test (1.1)</h1>
<hr>
- <applet code=DitherTest.class width=425 height=400>
+ <applet code=DitherTest.class width=455 height=400>
alt="Your browser understands the <APPLET> tag but isn't running the applet, for some reason."
Your browser is completely ignoring the <APPLET> tag!
</applet>
--- a/jdk/src/share/demo/jvmti/hprof/debug_malloc.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/demo/jvmti/hprof/debug_malloc.h Fri Sep 14 10:14:02 2012 -0700
@@ -59,6 +59,11 @@
#include <stdlib.h>
#include <string.h>
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* The real functions behind the macro curtains. */
void *debug_malloc(size_t, const char *, int);
@@ -71,10 +76,10 @@
void debug_malloc_verify(const char*, int);
#undef malloc_verify
-#define malloc_verify() debug_malloc_verify(__FILE__, __LINE__)
+#define malloc_verify() debug_malloc_verify(THIS_FILE, __LINE__)
void debug_malloc_police(const char*, int);
#undef malloc_police
-#define malloc_police() debug_malloc_police(__FILE__, __LINE__)
+#define malloc_police() debug_malloc_police(THIS_FILE, __LINE__)
#endif
--- a/jdk/src/share/demo/jvmti/hprof/hprof_error.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/demo/jvmti/hprof/hprof_error.h Fri Sep 14 10:14:02 2012 -0700
@@ -41,20 +41,25 @@
#ifndef HPROF_ERROR_H
#define HPROF_ERROR_H
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* Macros over assert and error functions so we can capture the source loc. */
#define HPROF_BOOL(x) ((jboolean)((x)==0?JNI_FALSE:JNI_TRUE))
#define HPROF_ERROR(fatal,msg) \
- error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, __FILE__, __LINE__)
+ error_handler(HPROF_BOOL(fatal), JVMTI_ERROR_NONE, msg, THIS_FILE, __LINE__)
#define HPROF_JVMTI_ERROR(error,msg) \
error_handler(HPROF_BOOL(error!=JVMTI_ERROR_NONE), \
- error, msg, __FILE__, __LINE__)
+ error, msg, THIS_FILE, __LINE__)
#if defined(DEBUG) || !defined(NDEBUG)
#define HPROF_ASSERT(cond) \
- (((int)(cond))?(void)0:error_assert(#cond, __FILE__, __LINE__))
+ (((int)(cond))?(void)0:error_assert(#cond, THIS_FILE, __LINE__))
#else
#define HPROF_ASSERT(cond)
#endif
@@ -77,11 +82,11 @@
#define LOG_FORMAT(format) "HPROF LOG: " format " [%s:%d]\n"
#define LOG1(str1) LOG_STDERR((stderr, LOG_FORMAT("%s"), \
- str1, __FILE__, __LINE__ ))
+ str1, THIS_FILE, __LINE__ ))
#define LOG2(str1,str2) LOG_STDERR((stderr, LOG_FORMAT("%s %s"), \
- str1, str2, __FILE__, __LINE__ ))
+ str1, str2, THIS_FILE, __LINE__ ))
#define LOG3(str1,str2,num) LOG_STDERR((stderr, LOG_FORMAT("%s %s 0x%x"), \
- str1, str2, num, __FILE__, __LINE__ ))
+ str1, str2, num, THIS_FILE, __LINE__ ))
#define LOG(str) LOG1(str)
--- a/jdk/src/share/demo/jvmti/hprof/hprof_util.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/demo/jvmti/hprof/hprof_util.h Fri Sep 14 10:14:02 2012 -0700
@@ -41,6 +41,11 @@
#ifndef HPROF_UTIL_H
#define HPROF_UTIL_H
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* Macros that protect code from accidently using a local ref improperly */
#define WITH_LOCAL_REFS(env, number) \
{ \
@@ -184,8 +189,8 @@
#ifdef DEBUG
void * hprof_debug_malloc(int size, char *file, int line);
void hprof_debug_free(void *ptr, char *file, int line);
- #define HPROF_MALLOC(size) hprof_debug_malloc(size, __FILE__, __LINE__)
- #define HPROF_FREE(ptr) hprof_debug_free(ptr, __FILE__, __LINE__)
+ #define HPROF_MALLOC(size) hprof_debug_malloc(size, THIS_FILE, __LINE__)
+ #define HPROF_FREE(ptr) hprof_debug_free(ptr, THIS_FILE, __LINE__)
#else
#define HPROF_MALLOC(size) hprof_malloc(size)
#define HPROF_FREE(ptr) hprof_free(ptr)
--- a/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/demo/jvmti/java_crw_demo/java_crw_demo.c Fri Sep 14 10:14:02 2012 -0700
@@ -70,12 +70,20 @@
/* Macros over error functions to capture line numbers */
-#define CRW_FATAL(ci, message) fatal_error(ci, message, __FILE__, __LINE__)
+/* Fatal error used in all builds. */
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE "java_crw.demo.c" /* Never use __FILE__ */
+#endif
+
+#define CRW_FATAL(ci, message) fatal_error(ci, message, THIS_FILE, __LINE__)
#if defined(DEBUG) || !defined(NDEBUG)
+ /* This assert macro is only used in the debug builds. */
#define CRW_ASSERT(ci, cond) \
- ((cond)?(void)0:assert_error(ci, #cond, __FILE__, __LINE__))
+ ((cond)?(void)0:assert_error(ci, #cond, THIS_FILE, __LINE__))
#else
--- a/jdk/src/share/instrument/JPLISAssert.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/instrument/JPLISAssert.h Fri Sep 14 10:14:02 2012 -0700
@@ -49,10 +49,14 @@
#define JPLISASSERT_ENABLEASSERTIONS (0)
#endif
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
#if JPLISASSERT_ENABLEASSERTIONS
-#define jplis_assert(x) JPLISAssertCondition((jboolean)(x), #x, __FILE__, __LINE__)
-#define jplis_assert_msg(x, msg) JPLISAssertConditionWithMessage((jboolean)(x), #x, msg, __FILE__, __LINE__)
+#define jplis_assert(x) JPLISAssertCondition((jboolean)(x), #x, THIS_FILE, __LINE__)
+#define jplis_assert_msg(x, msg) JPLISAssertConditionWithMessage((jboolean)(x), #x, msg, THIS_FILE, __LINE__)
#else
#define jplis_assert(x)
#define jplis_assert_msg(x, msg)
--- a/jdk/src/share/native/sun/awt/debug/debug_assert.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/native/sun/awt/debug/debug_assert.h Fri Sep 14 10:14:02 2012 -0700
@@ -32,17 +32,22 @@
#include "debug_util.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#if defined(DEBUG)
#define DASSERT(_expr) \
if ( !(_expr) ) { \
- DAssert_Impl( #_expr, __FILE__, __LINE__); \
+ DAssert_Impl( #_expr, THIS_FILE, __LINE__); \
} else { \
}
#define DASSERTMSG(_expr, _msg) \
if ( !(_expr) ) { \
- DAssert_Impl( (_msg), __FILE__, __LINE__); \
+ DAssert_Impl( (_msg), THIS_FILE, __LINE__); \
} else { \
}
--- a/jdk/src/share/native/sun/awt/debug/debug_mem.c Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/native/sun/awt/debug/debug_mem.c Fri Sep 14 10:14:02 2012 -0700
@@ -27,6 +27,11 @@
#include "debug_util.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define DMEM_MIN(a,b) (a) < (b) ? (a) : (b)
#define DMEM_MAX(a,b) (a) > (b) ? (a) : (b)
@@ -291,7 +296,7 @@
DMutex_Enter(DMemMutex);
/* Force memory leaks to be output regardless of trace settings */
- DTrace_EnableFile(__FILE__, TRUE);
+ DTrace_EnableFile(THIS_FILE, TRUE);
DTRACE_PRINTLN("--------------------------");
DTRACE_PRINTLN("Debug Memory Manager Leaks");
DTRACE_PRINTLN("--------------------------");
--- a/jdk/src/share/native/sun/awt/debug/debug_trace.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/native/sun/awt/debug/debug_trace.h Fri Sep 14 10:14:02 2012 -0700
@@ -34,6 +34,11 @@
#include "debug_util.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
typedef int dtrace_id;
enum {
UNDEFINED_TRACE_ID = -1 /* indicates trace point has not been registered yet */
@@ -69,7 +74,7 @@
#define _DTrace_Template(_func, _ac, _f, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) \
{ \
static dtrace_id _dt_lineid_ = UNDEFINED_TRACE_ID; \
- DTrace_PrintFunction((_func), &_Dt_FileTraceId, &_dt_lineid_, __FILE__, __LINE__, (_ac), (_f), (_a1), (_a2), (_a3), (_a4), (_a5), (_a6), (_a7), (_a8) ); \
+ DTrace_PrintFunction((_func), &_Dt_FileTraceId, &_dt_lineid_, THIS_FILE, __LINE__, (_ac), (_f), (_a1), (_a2), (_a3), (_a4), (_a5), (_a6), (_a7), (_a8) ); \
}
/* printf style trace macros */
--- a/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/native/sun/security/pkcs11/wrapper/pkcs11wrapper.h Fri Sep 14 10:14:02 2012 -0700
@@ -452,7 +452,12 @@
void *p11malloc(size_t c, char *file, int line);
void p11free(void *p, char *file, int line);
-#define malloc(c) (p11malloc((c), __FILE__, __LINE__))
-#define free(c) (p11free((c), __FILE__, __LINE__))
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
+#define malloc(c) (p11malloc((c), THIS_FILE, __LINE__))
+#define free(c) (p11free((c), THIS_FILE, __LINE__))
#endif
--- a/jdk/src/share/npt/utf.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/npt/utf.h Fri Sep 14 10:14:02 2012 -0700
@@ -33,8 +33,13 @@
#include "jni.h"
#include "utf_md.h"
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* Error and assert macros */
-#define UTF_ERROR(m) utfError(__FILE__, __LINE__, m)
+#define UTF_ERROR(m) utfError(THIS_FILE, __LINE__, m)
#define UTF_ASSERT(x) ( (x)==0 ? UTF_ERROR("ASSERT ERROR " #x) : (void)0 )
void utfError(char *file, int line, char *message);
--- a/jdk/src/share/transport/shmem/shmemBase.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/share/transport/shmem/shmemBase.h Fri Sep 14 10:14:02 2012 -0700
@@ -49,11 +49,16 @@
jint shmemBase_name(SharedMemoryTransport *, char **name);
jint shmemBase_getlasterror(char *msg, jint size);
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#ifdef DEBUG
#define SHMEM_ASSERT(expression) \
do { \
if (!(expression)) { \
- exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \
+ exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \
} \
} while (0)
#else
@@ -63,7 +68,7 @@
#define SHMEM_GUARANTEE(expression) \
do { \
if (!(expression)) { \
- exitTransportWithError("assertion failed", __FILE__, __DATE__, __LINE__); \
+ exitTransportWithError("assertion failed", THIS_FILE, __DATE__, __LINE__); \
} \
} while (0)
--- a/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XBaseWindow.java Fri Sep 14 10:14:02 2012 -0700
@@ -1001,6 +1001,13 @@
switch (xev.get_type()) {
case XConstants.ButtonPress:
if (buttonState == 0) {
+ XWindowPeer parent = getToplevelXWindow();
+ // See 6385277, 6981400.
+ if (parent != null && parent.isFocusableWindow()) {
+ // A click in a client area drops the actual focused window retaining.
+ parent.setActualFocusedWindow(null);
+ parent.requestWindowFocus(xbe.get_time(), true);
+ }
XAwtState.setAutoGrabWindow(this);
}
break;
--- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -588,33 +588,6 @@
}
- public void handleButtonPressRelease(XEvent xev) {
- /*
- * Fix for 6385277.
- * We request focus on simple Window by click in order
- * to make it behave like Frame/Dialog in this case and also to unify
- * the behaviour with what we have on MS Windows.
- * handleJavaMouseEvent() would be more suitable place to do this
- * but we want Swing to have this functionality also.
- */
- if (xev.get_type() == XConstants.ButtonPress) {
- final XWindowPeer parentXWindow = getParentTopLevel();
- Window parentWindow = (Window)parentXWindow.getTarget();
- if (parentXWindow.isFocusableWindow() && parentXWindow.isSimpleWindow() &&
- XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() != parentWindow)
- {
- postEvent(new InvocationEvent(parentWindow, new Runnable() {
- public void run() {
- // Request focus on the EDT of 'parentWindow' because
- // XDecoratedPeer.requestWindowFocus() calls client code.
- parentXWindow.requestXFocus();
- }
- }));
- }
- }
- super.handleButtonPressRelease(xev);
- }
-
public Dimension getMinimumSize() {
return target.getSize();
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -1108,7 +1108,7 @@
focusLog.fine("Request for decorated window focus");
// If this is Frame or Dialog we can't assure focus request success - but we still can try
// If this is Window and its owner Frame is active we can be sure request succedded.
- Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+ Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
focusLog.finer("Current window is: active={0}, focused={1}",
@@ -1201,7 +1201,7 @@
}
public void handleWindowFocusOut(Window oppositeWindow, long serial) {
- Window actualFocusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+ Window actualFocusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
// If the actual focused window is not this decorated window then retain it.
if (actualFocusedWindow != null && actualFocusedWindow != target) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -135,7 +135,7 @@
* Thus we don't have to perform any transitive (a blocker of a blocker) checks.
*/
boolean isFocusedWindowModalBlocker() {
- Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+ Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
XWindowPeer focusedWindowPeer = null;
if (focusedWindow != null) {
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -96,11 +96,11 @@
public void handleEvent(AWTEvent e) {
switch (e.getID()) {
case FocusEvent.FOCUS_GAINED:
- XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(proxy);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(proxy);
container.focusGained(handle);
break;
case FocusEvent.FOCUS_LOST:
- XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
container.focusLost(handle);
break;
case KeyEvent.KEY_PRESSED:
@@ -172,7 +172,7 @@
if (lightweightChild == null) {
lightweightChild = (Component)proxy;
}
- Component currentOwner = XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
+ Component currentOwner = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
if (currentOwner != null && currentOwner.getPeer() == null) {
currentOwner = null;
}
@@ -224,7 +224,8 @@
if (parent != null) {
Window parentWindow = (Window)parent;
// and check that it is focused
- if (!parentWindow.isFocused() && XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == parentWindow) {
+ if (!parentWindow.isFocused() &&
+ XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == parentWindow) {
// if it is not - skip requesting focus on Solaris
// but return true for compatibility.
return true;
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java Fri Sep 14 10:14:02 2012 -0700
@@ -204,7 +204,7 @@
// XEMBED_FOCUS_OUT client messages), so we first need to check if
// embedded is an active window before sending WINDOW_LOST_FOCUS
// to shared code
- if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == embedded.target) {
+ if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == embedded.target) {
embedded.handleWindowFocusOut(null, 0);
}
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -25,66 +25,48 @@
package sun.awt.X11;
import java.awt.Component;
-import java.awt.KeyboardFocusManager;
import java.awt.Window;
-
-import java.awt.event.FocusEvent;
-
-import java.awt.peer.KeyboardFocusManagerPeer;
-import java.awt.peer.ComponentPeer;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
import sun.util.logging.PlatformLogger;
-
import sun.awt.CausedFocusEvent;
-import sun.awt.SunToolkit;
import sun.awt.KeyboardFocusManagerPeerImpl;
public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XKeyboardFocusManagerPeer");
+ private static final XKeyboardFocusManagerPeer inst = new XKeyboardFocusManagerPeer();
- private static Object lock = new Object() {};
- private static Component currentFocusOwner;
- private static Window currentFocusedWindow;
+ private Component currentFocusOwner;
+ private Window currentFocusedWindow;
- XKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
- super(manager);
+ public static XKeyboardFocusManagerPeer getInstance() {
+ return inst;
+ }
+
+ private XKeyboardFocusManagerPeer() {
}
@Override
public void setCurrentFocusOwner(Component comp) {
- setCurrentNativeFocusOwner(comp);
+ synchronized (this) {
+ currentFocusOwner = comp;
+ }
}
@Override
public Component getCurrentFocusOwner() {
- return getCurrentNativeFocusOwner();
- }
-
- @Override
- public Window getCurrentFocusedWindow() {
- return getCurrentNativeFocusedWindow();
- }
-
- public static void setCurrentNativeFocusOwner(Component comp) {
- synchronized (lock) {
- currentFocusOwner = comp;
- }
- }
-
- public static Component getCurrentNativeFocusOwner() {
- synchronized(lock) {
+ synchronized(this) {
return currentFocusOwner;
}
}
- public static void setCurrentNativeFocusedWindow(Window win) {
- if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer("Setting current native focused window " + win);
+ @Override
+ public void setCurrentFocusedWindow(Window win) {
+ if (focusLog.isLoggable(PlatformLogger.FINER)) {
+ focusLog.finer("Setting current focused window " + win);
+ }
+
XWindowPeer from = null, to = null;
- synchronized(lock) {
+ synchronized(this) {
if (currentFocusedWindow != null) {
from = (XWindowPeer)currentFocusedWindow.getPeer();
}
@@ -104,8 +86,9 @@
}
}
- public static Window getCurrentNativeFocusedWindow() {
- synchronized(lock) {
+ @Override
+ public Window getCurrentFocusedWindow() {
+ synchronized(this) {
return currentFocusedWindow;
}
}
@@ -124,6 +107,6 @@
focusedWindowChangeAllowed,
time,
cause,
- getCurrentNativeFocusOwner());
+ getInstance().getCurrentFocusOwner());
}
}
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java Fri Sep 14 10:14:02 2012 -0700
@@ -663,7 +663,7 @@
long w = 0;
if (windowToXWindow(ev.get_xany().get_window()) != null) {
Component owner =
- XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
+ XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
if (owner != null) {
XWindow ownerWindow = (XWindow) AWTAccessor.getComponentAccessor().getPeer(owner);
if (ownerWindow != null) {
@@ -1155,9 +1155,8 @@
return peer;
}
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) throws HeadlessException {
- XKeyboardFocusManagerPeer peer = new XKeyboardFocusManagerPeer(manager);
- return peer;
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() throws HeadlessException {
+ return XKeyboardFocusManagerPeer.getInstance();
}
/**
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -617,7 +617,7 @@
public void handleWindowFocusIn_Dispatch() {
if (EventQueue.isDispatchThread()) {
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
SunToolkit.setSystemGenerated(we);
target.dispatchEvent(we);
@@ -626,7 +626,7 @@
public void handleWindowFocusInSync(long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
sendEvent(we);
}
// NOTE: This method may be called by privileged threads.
@@ -634,7 +634,7 @@
public void handleWindowFocusIn(long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
/* wrap in Sequenced, then post*/
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
postEvent(wrapInSequenced((AWTEvent) we));
}
@@ -642,15 +642,15 @@
// DO NOT INVOKE CLIENT CODE ON THIS THREAD!
public void handleWindowFocusOut(Window oppositeWindow, long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow(null);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
/* wrap in Sequenced, then post*/
postEvent(wrapInSequenced((AWTEvent) we));
}
public void handleWindowFocusOutSync(Window oppositeWindow, long serial) {
WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow(null);
- XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
+ XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
sendEvent(we);
}
@@ -1138,7 +1138,7 @@
// getWMState() always returns 0 (Withdrawn) for simple windows. Hence
// we ignore the state for such windows.
if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
- if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() ==
+ if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() ==
getTarget())
{
show = true;
@@ -1165,15 +1165,25 @@
}
public void dispose() {
+ if (isGrabbed()) {
+ if (grabLog.isLoggable(PlatformLogger.FINE)) {
+ grabLog.fine("Generating UngrabEvent on {0} because of the window disposal", this);
+ }
+ postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+ }
+
SunToolkit.awtLock();
+
try {
windows.remove(this);
} finally {
SunToolkit.awtUnlock();
}
+
if (warningWindow != null) {
warningWindow.destroy();
}
+
removeRootPropertyEventDispatcher();
mustControlStackPosition = false;
super.dispose();
@@ -1185,12 +1195,13 @@
* receive WM_TAKE_FOCUS.
*/
if (isSimpleWindow()) {
- if (target == XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow()) {
+ if (target == XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow()) {
Window owner = getDecoratedOwner((Window)target);
((XWindowPeer)AWTAccessor.getComponentAccessor().getPeer(owner)).requestWindowFocus();
}
}
}
+
boolean isResizable() {
return winAttr.isResizable;
}
@@ -1825,7 +1836,7 @@
// If this is Frame or Dialog we can't assure focus request success - but we still can try
// If this is Window and its owner Frame is active we can be sure request succedded.
Window ownerWindow = XWindowPeer.getDecoratedOwner((Window)target);
- Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+ Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
if (isWMStateNetHidden()) {
--- a/jdk/src/solaris/instrument/EncodingSupport_md.c Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/solaris/instrument/EncodingSupport_md.c Fri Sep 14 10:14:02 2012 -0700
@@ -33,8 +33,13 @@
/* Routines to convert back and forth between Platform Encoding and UTF-8 */
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/* Error and assert macros */
-#define UTF_ERROR(m) utfError(__FILE__, __LINE__, m)
+#define UTF_ERROR(m) utfError(THIS_FILE, __LINE__, m)
#define UTF_ASSERT(x) ( (x)==0 ? UTF_ERROR("ASSERT ERROR " #x) : (void)0 )
#define UTF_DEBUG(x)
--- a/jdk/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java Fri Sep 14 10:14:02 2012 -0700
@@ -25,7 +25,6 @@
package sun.awt.windows;
-import java.awt.KeyboardFocusManager;
import java.awt.Window;
import java.awt.Component;
import java.awt.peer.ComponentPeer;
@@ -37,8 +36,13 @@
static native Component getNativeFocusOwner();
static native Window getNativeFocusedWindow();
- WKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
- super(manager);
+ private static final WKeyboardFocusManagerPeer inst = new WKeyboardFocusManagerPeer();
+
+ public static WKeyboardFocusManagerPeer getInstance() {
+ return inst;
+ }
+
+ private WKeyboardFocusManagerPeer() {
}
@Override
@@ -52,6 +56,12 @@
}
@Override
+ public void setCurrentFocusedWindow(Window win) {
+ // Not used on Windows
+ throw new RuntimeException("not implemented");
+ }
+
+ @Override
public Window getCurrentFocusedWindow() {
return getNativeFocusedWindow();
}
--- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java Fri Sep 14 10:14:02 2012 -0700
@@ -506,10 +506,10 @@
return true;
}
- public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
+ public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
throws HeadlessException
{
- return new WKeyboardFocusManagerPeer(manager);
+ return WKeyboardFocusManagerPeer.getInstance();
}
protected native void setDynamicLayoutNative(boolean b);
--- a/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiIn.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiIn.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -35,9 +35,15 @@
#ifdef USE_ERROR
#include <stdio.h>
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define MIDIIN_CHECK_ERROR { \
if (err != MMSYSERR_NOERROR) \
- ERROR3("MIDI IN Error in %s:%d : %s\n", __FILE__, __LINE__, MIDI_IN_GetErrorStr((INT32) err)); \
+ ERROR3("MIDI IN Error in %s:%d : %s\n", THIS_FILE, __LINE__, MIDI_IN_GetErrorStr((INT32) err)); \
}
#else
#define MIDIIN_CHECK_ERROR
--- a/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiOut.c Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/native/com/sun/media/sound/PLATFORM_API_WinOS_MidiOut.c Fri Sep 14 10:14:02 2012 -0700
@@ -33,9 +33,15 @@
#ifdef USE_ERROR
#include <stdio.h>
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define MIDIOUT_CHECK_ERROR { \
if (err != MMSYSERR_NOERROR) \
- ERROR3("MIDI OUT Error in %s:%d : %s\n", __FILE__, __LINE__, MIDI_OUT_GetErrorStr((INT32) err)); \
+ ERROR3("MIDI OUT Error in %s:%d : %s\n", THIS_FILE, __LINE__, MIDI_OUT_GetErrorStr((INT32) err)); \
}
#else
#define MIDIOUT_CHECK_ERROR
--- a/jdk/src/windows/native/sun/java2d/d3d/D3DPipeline.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/native/sun/java2d/d3d/D3DPipeline.h Fri Sep 14 10:14:02 2012 -0700
@@ -28,6 +28,11 @@
#define D3D_DEBUG_INFO
#endif // DEBUG
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE THIS_FILE
+#endif
+
#ifdef D3D_PPL_DLL
@@ -104,7 +109,7 @@
#define ACT_IF_NULL(ACTION, value) \
if ((value) == NULL) { \
J2dTraceLn3(J2D_TRACE_ERROR, \
- "%s is null in %s:%d", #value, __FILE__, __LINE__); \
+ "%s is null in %s:%d", #value, THIS_FILE, __LINE__); \
ACTION; \
} else do { } while (0)
#define RETURN_IF_NULL(value) ACT_IF_NULL(return, value)
@@ -114,12 +119,12 @@
#define RETURN_STATUS_IF_EXP_FAILED(EXPR) \
if (FAILED(res = (EXPR))) { \
- DebugPrintD3DError(res, " " ## #EXPR ## " failed in " ## __FILE__); \
+ DebugPrintD3DError(res, " " ## #EXPR ## " failed in " ## THIS_FILE); \
return res; \
} else do { } while (0)
#define RETURN_STATUS_IF_FAILED(status) \
if (FAILED((status))) { \
- DebugPrintD3DError((status), " failed in " ## __FILE__ ## ", return;");\
+ DebugPrintD3DError((status), " failed in " ## THIS_FILE ## ", return;");\
return (status); \
} else do { } while (0)
--- a/jdk/src/windows/native/sun/windows/alloc.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/native/sun/windows/alloc.h Fri Sep 14 10:14:02 2012 -0700
@@ -26,6 +26,11 @@
#ifndef _ALLOC_H_
#define _ALLOC_H_
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#include "stdhdrs.h"
// By defining std::bad_alloc in a local header file instead of including
@@ -127,12 +132,12 @@
throw (std::bad_alloc);
#define safe_Malloc(size) \
- safe_Malloc_outofmem(size, __FILE__, __LINE__)
+ safe_Malloc_outofmem(size, THIS_FILE, __LINE__)
#define safe_Calloc(num, size) \
- safe_Calloc_outofmem(num, size, __FILE__, __LINE__)
+ safe_Calloc_outofmem(num, size, THIS_FILE, __LINE__)
#define safe_Realloc(memblock, size) \
- safe_Realloc_outofmem(memblock, size, __FILE__, __LINE__)
- #define new new(__FILE__, __LINE__)
+ safe_Realloc_outofmem(memblock, size, THIS_FILE, __LINE__)
+ #define new new(THIS_FILE, __LINE__)
#endif /* OUTOFMEM_TEST */
#define TRY \
--- a/jdk/src/windows/native/sun/windows/awt_Debug.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Debug.h Fri Sep 14 10:14:02 2012 -0700
@@ -65,7 +65,12 @@
#define AWT_DUMP_CLIP_RECTANGLE(_msg, _hwnd) \
_DTrace_Template(DumpClipRectangle, 2, "", (_msg), (_hwnd), 0, 0, 0, 0, 0, 0)
- #define new new(__FILE__, __LINE__)
+ /* Use THIS_FILE when it is available. */
+ #ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+ #endif
+
+ #define new new(THIS_FILE, __LINE__)
#define VERIFY(exp) DASSERT(exp)
#define UNIMPLEMENTED() DASSERT(FALSE)
--- a/jdk/src/windows/native/sun/windows/awt_Toolkit.h Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.h Fri Sep 14 10:14:02 2012 -0700
@@ -132,24 +132,30 @@
// Macros for using CriticalSection objects that help trace
// lock/unlock actions
+
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
#define CRITICAL_SECTION_ENTER(cs) { \
J2dTraceLn4(J2D_TRACE_VERBOSE2, \
"CS.Wait: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
- GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
+ GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \
(cs).Enter(); \
J2dTraceLn4(J2D_TRACE_VERBOSE2, \
"CS.Enter: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
- GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
+ GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \
}
#define CRITICAL_SECTION_LEAVE(cs) { \
J2dTraceLn4(J2D_TRACE_VERBOSE2, \
"CS.Leave: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
- GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
+ GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \
(cs).Leave(); \
J2dTraceLn4(J2D_TRACE_VERBOSE2, \
"CS.Left: tid, cs, file, line = 0x%x, 0x%x, %s, %d", \
- GetCurrentThreadId(), &(cs), __FILE__, __LINE__); \
+ GetCurrentThreadId(), &(cs), THIS_FILE, __LINE__); \
}
/************************************************************************
--- a/jdk/src/windows/native/sun/windows/awt_Window.cpp Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Fri Sep 14 10:14:02 2012 -0700
@@ -1477,7 +1477,7 @@
if (wClassEvent == NULL) {
if (env->PushLocalFrame(1) < 0)
return;
- wClassEvent = env->FindClass("java/awt/event/WindowEvent");
+ wClassEvent = env->FindClass("sun/awt/TimedWindowEvent");
if (wClassEvent != NULL) {
wClassEvent = (jclass)env->NewGlobalRef(wClassEvent);
}
@@ -1491,7 +1491,7 @@
if (wEventInitMID == NULL) {
wEventInitMID =
env->GetMethodID(wClassEvent, "<init>",
- "(Ljava/awt/Window;ILjava/awt/Window;II)V");
+ "(Ljava/awt/Window;ILjava/awt/Window;IIJ)V");
DASSERT(wEventInitMID);
if (wEventInitMID == NULL) {
return;
@@ -1532,7 +1532,7 @@
}
}
jobject event = env->NewObject(wClassEvent, wEventInitMID, target, id,
- jOpposite, oldState, newState);
+ jOpposite, oldState, newState, TimeHelper::getMessageTimeUTC());
DASSERT(!safe_ExceptionOccurred(env));
DASSERT(event != NULL);
if (jOpposite != NULL) {
--- a/jdk/src/windows/transport/shmem/shmem_md.c Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/src/windows/transport/shmem/shmem_md.c Fri Sep 14 10:14:02 2012 -0700
@@ -30,6 +30,11 @@
#include "sysShmem.h"
#include "shmemBase.h" /* for exitTransportWithError */
+/* Use THIS_FILE when it is available. */
+#ifndef THIS_FILE
+ #define THIS_FILE __FILE__
+#endif
+
/*
* These functions are not completely universal. For now, they are used
* exclusively for Jbug's shared memory transport mechanism. They have
@@ -44,7 +49,7 @@
if (!(expression)) { \
exitTransportWithError \
("\"%s\", line %d: assertion failure\n", \
- __FILE__, __DATE__, __LINE__); \
+ THIS_FILE, __DATE__, __LINE__); \
} \
}
#else
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/6981400/Test1.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,222 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6981400
+ * @summary Tabbing between textfiled do not work properly when ALT+TAB
+ * @author anton.tarasov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main Test1
+ */
+
+// This test shows a frame with four focusable components: b0, b1, b2, b3.
+// Then it presses Tab three times. EDT is freezed for a while on the first FOCUS_LOST event.
+// Meantime, the test clicks in a component of another frame and then clicks in the title
+// of the original frame. When EDT awakes and all the queued events get processed,
+// the other frame should ones gain focus and then pass it to the original frame.
+// The b3 component of the orinial frame should finally become a focus owner.
+// The FOCUS_LOST/FOCUS_GAINED events order in the original frame is tracked and should be:
+// b0 -> b1 -> b2 -> b3.
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.swing.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class Test1 {
+ static JFrame f0 = new JFrame("base_frame") { public String getName() {return "base_frame";} };
+ static JButton f0b0 = new JB("b0");
+ static JButton f0b1 = new JB("b1");
+ static JButton f0b2 = new JB("b2");
+ static JButton f0b3 = new JB("b3");
+
+ static JFrame f1 = new JFrame("swing_frame") { public String getName() {return "swing_frame";} };
+ static JButton f1b0 = new JButton("button");
+
+ static Frame f2 = new Frame("awt_frame") { public String getName() {return "awt_frame";} };
+ static Button f2b0 = new Button("button");
+
+ static Robot robot;
+
+ static List<Component> gainedList = new ArrayList<Component>();
+ static List<Component> lostList = new ArrayList<Component>();
+
+ static Component[] refGainedList = new Component[] {f0b1, f0b2, f0b3, f0b3};
+ static Component[] refLostList = new Component[] {f0b0, f0b1, f0b2, f0b3};
+
+ static boolean tracking;
+
+ public static void main(String[] args) {
+ Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+ public void eventDispatched(AWTEvent e) {
+ System.out.println(e);
+ }
+ }, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_EVENT_MASK);
+
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ throw new RuntimeException("Error: can't create Robot");
+ }
+
+ f0.add(f0b0);
+ f0.add(f0b1);
+ f0.add(f0b2);
+ f0.add(f0b3);
+ f0.setLayout(new FlowLayout());
+ f0.setBounds(0, 100, 400, 200);
+
+ f1.add(f1b0);
+ f1.setBounds(0, 400, 400, 200);
+
+ f2.add(f2b0);
+ f2.setBounds(0, 400, 400, 200);
+
+ f0b0.addFocusListener(new FocusAdapter() {
+ @Override
+ public void focusLost(FocusEvent e) {
+ try {
+ Thread.sleep(1000);
+ } catch (Exception ex) {}
+ }
+ });
+
+ //
+ // Case 1. Test against swing JFrame.
+ //
+
+ f1.setVisible(true);
+ f0.setVisible(true);
+
+ Util.waitForIdle(robot);
+
+ if (!f0b0.isFocusOwner()) {
+ Util.clickOnComp(f0b0, robot);
+ Util.waitForIdle(robot);
+ if (!f0b0.isFocusOwner()) {
+ throw new RuntimeException("Error: can't focus the component " + f0b0);
+ }
+ }
+
+ System.out.println("\nTest case 1: swing frame\n");
+ test(f1b0);
+
+ //
+ // Case 2. Test against awt Frame.
+ //
+
+ tracking = false;
+ gainedList.clear();
+ lostList.clear();
+
+ f1.dispose();
+ f2.setAutoRequestFocus(false);
+ f2.setVisible(true);
+ Util.waitForIdle(robot);
+
+ Util.clickOnComp(f0b0, robot);
+ Util.waitForIdle(robot);
+ if (!f0b0.isFocusOwner()) {
+ throw new RuntimeException("Error: can't focus the component " + f0b0);
+ }
+
+ System.out.println("\nTest case 2: awt frame\n");
+ test(f2b0);
+
+ System.out.println("\nTest passed.");
+ }
+
+ public static void test(Component compToClick) {
+ tracking = true;
+
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.delay(50);
+
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.delay(50);
+
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+
+ robot.delay(50);
+ Util.clickOnComp(compToClick, robot);
+
+ robot.delay(50);
+ Util.clickOnTitle(f0, robot);
+
+ Util.waitForIdle(robot);
+
+ if (!f0b3.isFocusOwner()) {
+ throw new RuntimeException("Test failed: f0b3 is not a focus owner");
+ }
+
+ if (!"sun.awt.X11.XToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) {
+
+ if (!Arrays.asList(refGainedList).equals(gainedList)) {
+ System.out.println("gained list: " + gainedList);
+ throw new RuntimeException("Test failed: wrong FOCUS_GAINED events order");
+ }
+ if (!Arrays.asList(refLostList).equals(lostList)) {
+ System.out.println("lost list: " + lostList);
+ throw new RuntimeException("Test failed: wrong FOCUS_LOST events order");
+ }
+ }
+ }
+}
+
+class JB extends JButton {
+ String name;
+
+ public JB(String name) {
+ super(name);
+ this.name = name;
+
+ addFocusListener(new FocusListener() {
+ public void focusGained(FocusEvent e) {
+ if (Test1.tracking)
+ Test1.gainedList.add(e.getComponent());
+ }
+
+ public void focusLost(FocusEvent e) {
+ if (Test1.tracking)
+ Test1.lostList.add(e.getComponent());
+ }
+ });
+ }
+
+ public String toString() {
+ return "[" + name + "]";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/6981400/Test2.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,118 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6981400
+ * @summary Tabbing between textfiled do not work properly when ALT+TAB
+ * @author anton.tarasov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main Test2
+ */
+
+// A focus request made after a char is typed ahead shouldn't affect the char's target component.
+
+import java.awt.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class Test2 {
+ static Frame f = new Frame("frame");
+ static TextArea t0 = new TextArea(1, 10) { public String toString() { return "[TA-0]";} };
+ static TextArea t1 = new TextArea(1, 10) { public String toString() { return "[TA-1]";} };
+ static TextArea t2 = new TextArea(1, 10) { public String toString() { return "[TA-2]";} };
+
+ static volatile boolean passed = true;
+
+ static Robot robot;
+
+ public static void main(String[] args) {
+ Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+ public void eventDispatched(AWTEvent e) {
+ System.out.println(e);
+ if (e.getID() == KeyEvent.KEY_TYPED) {
+ if (e.getSource() != t1) {
+ passed = false;
+ throw new RuntimeException("Test failed: the key event has wrong source: " + e);
+ }
+ }
+ }
+ }, FocusEvent.FOCUS_EVENT_MASK | KeyEvent.KEY_EVENT_MASK);
+
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ throw new RuntimeException("Error: can't create Robot");
+ }
+
+ f.add(t0);
+ f.add(t1);
+ f.add(t2);
+
+ f.setLayout(new FlowLayout());
+ f.pack();
+
+ t0.addFocusListener(new FocusAdapter() {
+ public void focusLost(FocusEvent e) {
+ try {
+ Thread.sleep(3000);
+ } catch (Exception ex) {}
+ }
+ });
+
+ // The request shouldn't affect the key event delivery.
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(2000);
+ } catch (Exception ex) {}
+ System.out.println("requesting focus to " + t2);
+ t2.requestFocus();
+ }
+ }).start();
+
+
+ f.setVisible(true);
+ Util.waitForIdle(robot);
+
+ test();
+
+ if (passed) System.out.println("\nTest passed.");
+ }
+
+ static void test() {
+ Util.clickOnComp(t1, robot);
+
+ // The key event should be eventually delivered to t1.
+ robot.delay(50);
+ robot.keyPress(KeyEvent.VK_A);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_A);
+
+ Util.waitForIdle(robot);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Focus/6981400/Test3.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,141 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6981400
+ * @summary Tabbing between textfiled do not work properly when ALT+TAB
+ * @author anton.tarasov
+ * @library ../../regtesthelpers
+ * @build Util
+ * @run main Test3
+ */
+
+// A menu item in a frame should not be auto-selected when switching by Alt+TAB back and forth.
+
+import java.awt.*;
+import javax.swing.*;
+import java.awt.event.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class Test3 {
+ static JFrame f = new JFrame("Frame");
+ static JMenuBar bar = new JMenuBar();
+ static JMenu menu = new JMenu("File");
+ static JMenuItem item = new JMenuItem("Save");
+
+ static JButton b0 = new JButton("b0");
+ static JButton b1 = new JButton("b1");
+
+ static Robot robot;
+
+ public static void main(String[] args) {
+ Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+ public void eventDispatched(AWTEvent e) {
+ System.err.println(e);
+ }
+ }, KeyEvent.KEY_EVENT_MASK);
+
+ try {
+ robot = new Robot();
+ } catch (AWTException ex) {
+ throw new RuntimeException("Error: can't create Robot");
+ }
+
+ try {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+ } catch (Exception e) {}
+
+ b0.addFocusListener(new FocusAdapter() {
+ public void focusLost(FocusEvent f) {
+ try {
+ Thread.sleep(2000);
+ } catch (Exception e) {}
+ }
+ });
+
+ menu.add(item);
+ bar.add(menu);
+ f.setJMenuBar(bar);
+
+ f.add(b0);
+ f.add(b1);
+
+ f.setLayout(new FlowLayout());
+ f.setSize(400, 100);
+ f.setVisible(true);
+ Util.waitForIdle(robot);
+
+ if (!b0.hasFocus()) {
+ Util.clickOnComp(b0, robot);
+ Util.waitForIdle(robot);
+ if (!b0.hasFocus()) {
+ throw new RuntimeException("Error: can't focus " + b0);
+ }
+ }
+
+ test();
+
+ System.out.println("Test passed.");
+ }
+
+ public static void test() {
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+ robot.delay(50);
+
+ robot.keyPress(KeyEvent.VK_ALT);
+ robot.delay(50);
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_ALT);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+
+ robot.delay(500);
+
+ robot.keyPress(KeyEvent.VK_ALT);
+ robot.delay(50);
+ robot.keyPress(KeyEvent.VK_TAB);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_ALT);
+ robot.delay(50);
+ robot.keyRelease(KeyEvent.VK_TAB);
+
+ // Control shot.
+ Util.clickOnTitle(f, robot);
+ Util.waitForIdle(robot);
+
+ if (menu.isSelected()) {
+ throw new RuntimeException("Test failed: the menu gets selected");
+ }
+ if (!b1.hasFocus()) {
+ throw new RuntimeException("Test failed: the button is not a focus owner " + b1);
+ }
+ }
+}
+
+
--- a/jdk/test/java/beans/Introspector/6380849/TestBeanInfo.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/test/java/beans/Introspector/6380849/TestBeanInfo.java Fri Sep 14 10:14:02 2012 -0700
@@ -38,8 +38,7 @@
import java.beans.BeanInfo;
import java.beans.Introspector;
-import java.lang.ref.Reference;
-import java.lang.reflect.Field;
+import java.lang.reflect.Method;
public class TestBeanInfo implements Runnable {
@@ -60,10 +59,9 @@
try {
actual = Introspector.getBeanInfo(type);
type = actual.getClass();
- Field field = type.getDeclaredField("targetBeanInfoRef"); // NON-NLS: field name
- field.setAccessible(true);
- Reference ref = (Reference) field.get(actual);
- actual = (BeanInfo) ref.get();
+ Method method = type.getDeclaredMethod("getTargetBeanInfo"); // NON-NLS: method name
+ method.setAccessible(true);
+ actual = (BeanInfo) method.invoke(actual);
}
catch (Exception exception) {
throw new Error("unexpected error", exception);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/Test7186794.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,55 @@
+/*
+ * 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 7186794
+ * @summary Tests setter in the super class
+ * @author Sergey Malenkov
+ */
+
+import java.util.List;
+
+public class Test7186794 {
+
+ public static void main(String[] args) {
+ if (null == BeanUtils.findPropertyDescriptor(MyBean.class, "value").getWriteMethod()) {
+ throw new Error("The property setter is not found");
+ }
+ }
+
+ public static class BaseBean {
+
+ protected List<String> value;
+
+ public void setValue(List<String> value) {
+ this.value = value;
+ }
+ }
+
+ public static class MyBean extends BaseBean {
+ public List<String> getValue() {
+ return super.value;
+ }
+ }
+}
--- a/jdk/test/java/beans/Introspector/Test7189112.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/test/java/beans/Introspector/Test7189112.java Fri Sep 14 10:14:02 2012 -0700
@@ -28,17 +28,11 @@
* @author Sergey Malenkov
*/
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-
public class Test7189112 {
- public static void main(String[] args) throws IntrospectionException {
- for (PropertyDescriptor pd : Introspector.getBeanInfo(MyBean.class).getPropertyDescriptors()) {
- if (pd.getName().equals("value") && (null == pd.getWriteMethod())) {
- throw new Error("The property setter is not found");
- }
+ public static void main(String[] args) {
+ if (null == BeanUtils.findPropertyDescriptor(MyBean.class, "value").getWriteMethod()) {
+ throw new Error("The property setter is not found");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/Test7192955.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,83 @@
+/*
+ * 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 7192955
+ * @summary Tests that all properties are bound
+ * @author Sergey Malenkov
+ */
+
+import java.beans.PropertyChangeListener;
+import java.util.List;
+
+public class Test7192955 {
+
+ public static void main(String[] args) {
+ if (!BeanUtils.findPropertyDescriptor(MyBean.class, "test").isBound()) {
+ throw new Error("a simple property is not bound");
+ }
+ if (!BeanUtils.findPropertyDescriptor(MyBean.class, "list").isBound()) {
+ throw new Error("a generic property is not bound");
+ }
+ if (!BeanUtils.findPropertyDescriptor(MyBean.class, "readOnly").isBound()) {
+ throw new Error("a read-only property is not bound");
+ }
+ }
+
+ public static class BaseBean {
+
+ private List<String> list;
+
+ public List<String> getList() {
+ return this.list;
+ }
+
+ public void setList(List<String> list) {
+ this.list = list;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ }
+
+ public List<String> getReadOnly() {
+ return this.list;
+ }
+ }
+
+ public static class MyBean extends BaseBean {
+
+ private String test;
+
+ public String getTest() {
+ return this.test;
+ }
+
+ public void setTest(String test) {
+ this.test = test;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/Introspector/Test7195106.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,67 @@
+/*
+ * 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 7195106
+ * @summary Tests that explicit BeanInfo is not collected
+ * @author Sergey Malenkov
+ */
+
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.SimpleBeanInfo;
+
+public class Test7195106 {
+
+ public static void main(String[] arg) throws Exception {
+ BeanInfo info = Introspector.getBeanInfo(My.class);
+ if (null == info.getIcon(BeanInfo.ICON_COLOR_16x16)) {
+ throw new Error("Unexpected behavior");
+ }
+ try {
+ int[] array = new int[1024];
+ while (true) {
+ array = new int[array.length << 1];
+ }
+ }
+ catch (OutOfMemoryError error) {
+ System.gc();
+ }
+ if (null == info.getIcon(BeanInfo.ICON_COLOR_16x16)) {
+ throw new Error("Explicit BeanInfo is collected");
+ }
+ }
+
+ public static class My {
+ }
+
+ public static class MyBeanInfo extends SimpleBeanInfo {
+ @Override
+ public Image getIcon(int type) {
+ return new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/beans/XMLEncoder/Test7169395.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,101 @@
+/*
+ * 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 7169395
+ * @summary Tests that array list initialized correctly
+ * @author Sergey Malenkov
+ */
+
+import java.beans.ConstructorProperties;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class Test7169395 extends AbstractTest {
+
+ public static void main(String[] args) {
+ new Test7169395().test(true);
+ }
+
+ protected Object getObject() {
+ Container container = new Container();
+ container.add("test-null", null);
+ container.add("test-value", "value");
+ container.add("test-other", "other");
+ return container;
+ }
+
+ public static class Component {
+
+ private final Container container;
+ private final String name;
+ private String value;
+
+ @ConstructorProperties({ "container", "name" })
+ public Component(Container container, String name) {
+ this.container = container;
+ this.name = name;
+ }
+
+ public Container getContainer() {
+ return this.container;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public String getValue() {
+ return this.value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+ }
+
+ public static class Container {
+
+ private final Map<String, Component> map = new TreeMap<String, Component>();
+
+ public Collection<Component> getComponents() {
+ return new ArrayList<Component>(this.map.values());
+ }
+
+ public void setComponents(Collection<Component> components) {
+ this.map.clear();
+ for (Component component : components){
+ this.map.put(component.getName(), component);
+ }
+ }
+
+ public void add(String name, String value) {
+ Component list = new Component(this, name);
+ list.setValue(value);
+ this.map.put(name, list);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/BigArityTest.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,1044 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @summary High arity invocations, up to the maximum of 255 arguments
+ * @compile BigArityTest.java
+ * @run junit/othervm -DBigArityTest.ITERATION_COUNT=1 test.java.lang.invoke.BigArityTest
+ */
+
+package test.java.lang.invoke;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.WrongMethodTypeException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Objects;
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class BigArityTest {
+
+ static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+ static final int MAX_JVM_ARITY = 255;
+ static final int ITERATION_COUNT = getProperty("ITERATION_COUNT", 40000);
+ static final int MIN_ARITY = getProperty("MIN_ARITY", 250);
+ static final int SLOW_ARITY = getProperty("SLOW_ARITY", MAX_JVM_ARITY-3);
+ static final int MAX_ARITY = getProperty("MAX_ARITY", MAX_JVM_ARITY-1); // always -1 for the MH reciever itself
+ private static int getProperty(String name, int dflt) {
+ return Integer.parseInt(getProperty(name, ""+dflt));
+ }
+ private static String getProperty(String name, String dflt) {
+ String x = System.getProperty(BigArityTest.class.getSimpleName() + "." + name);
+ if (x == null) x = System.getProperty(BigArityTest.class.getName() + "." + name);
+ return x == null ? dflt : x;
+ }
+
+ static Object hashArguments(Object... args) {
+ return Objects.hash(args);
+ }
+ static final MethodHandle MH_hashArguments_VA;
+ static {
+ try {
+ MH_hashArguments_VA =
+ MethodHandles.lookup().unreflect(
+ BigArityTest.class.getDeclaredMethod("hashArguments", Object[].class));
+ } catch (ReflectiveOperationException ex) {
+ throw new InternalError(ex);
+ }
+ }
+ static MethodHandle MH_hashArguments(int arity) {
+ MethodType mt = MethodType.genericMethodType(arity);
+ return MH_hashArguments_VA.asType(mt);
+ }
+ static MethodHandle MH_hashArguments(Class<? extends Object[]> arrayClass, int arity) {
+ if (arrayClass == Object[].class)
+ return MH_hashArguments(arity);
+ ArrayList<Class<?>> ptypes = new ArrayList<>(Collections.<Class<?>>nCopies(arity, arrayClass.getComponentType()));
+ MethodType mt = MethodType.methodType(Object.class, ptypes);
+ return MH_hashArguments_VA.asType(mt);
+ }
+
+ static Object[] testArgs(int arity) {
+ Object args[] = new Object[arity];
+ for (int i = 0; i < arity; i++)
+ args[i] = i * (i + 1) / 2;
+ return args;
+ }
+
+ @Test
+ public void testBoundaryValues() throws Throwable {
+ for (int badArity : new int[]{ -1, MAX_JVM_ARITY+1, MAX_JVM_ARITY }) {
+ try {
+ MethodHandle badmh = MH_hashArguments(badArity);
+ throw new AssertionError("should not be able to build a 255-arity MH: "+badmh);
+ } catch (IllegalArgumentException | WrongMethodTypeException ex) {
+ System.out.println("OK: "+ex);
+ }
+ }
+ }
+
+ // Make sure the basic argument spreading and varargs mechanisms are working.
+ // Exercise arity 3 thoroughly.
+ @Test
+ public void testSpreads() throws Throwable {
+ System.out.println("testing asSpreader on arity=3");
+ Object[] args = testArgs(3);
+ int r0 = Objects.hash(args);
+ MethodHandle mh = MH_hashArguments(3);
+ Object r;
+ r = mh.invokeExact(args[0], args[1], args[2]);
+ assertEquals(r0, r);
+ r = mh.invoke(args[0], args[1], args[2]);
+ assertEquals(r0, r);
+ r = mh.invoke((Comparable) args[0], (Integer) args[1], (Number) args[2]);
+ assertEquals(r0, r);
+ r = mh.invokeWithArguments(args);
+ assertEquals(r0, r);
+ for (Class<?> cls0 : new Class<?>[] {
+ Object[].class, Number[].class, Integer[].class, Comparable[].class
+ }) {
+ @SuppressWarnings("unchecked")
+ Class<? extends Object[]> cls = (Class<? extends Object[]>) cls0;
+ //Class<? extends Object[]> cls = Object[].class.asSubclass(cls0);
+ int nargs = args.length, skip;
+ MethodHandle smh = mh.asSpreader(cls, nargs - (skip = 0));
+ Object[] tail = Arrays.copyOfRange(args, skip, nargs, cls);
+ if (cls == Object[].class)
+ r = smh.invokeExact(tail);
+ else if (cls == Integer[].class)
+ r = smh.invokeExact((Integer[]) tail);
+ else
+ r = smh.invoke(tail);
+ assertEquals(r0, r);
+ smh = mh.asSpreader(cls, nargs - (skip = 1));
+ tail = Arrays.copyOfRange(args, skip, nargs, cls);
+ if (cls == Object[].class)
+ r = smh.invokeExact(args[0], tail);
+ else if (cls == Integer[].class)
+ r = smh.invokeExact(args[0], (Integer[]) tail);
+ else
+ r = smh.invoke(args[0], tail);
+ assertEquals(r0, r);
+ smh = mh.asSpreader(cls, nargs - (skip = 2));
+ tail = Arrays.copyOfRange(args, skip, nargs, cls);
+ if (cls == Object[].class)
+ r = smh.invokeExact(args[0], args[1], tail);
+ else if (cls == Integer[].class)
+ r = smh.invokeExact(args[0], args[1], (Integer[]) tail);
+ else
+ r = smh.invoke(args[0], args[1], tail);
+ assertEquals(r0, r);
+ smh = mh.asSpreader(cls, nargs - (skip = 3));
+ tail = Arrays.copyOfRange(args, skip, nargs, cls);
+ if (cls == Object[].class)
+ r = smh.invokeExact(args[0], args[1], args[2], tail);
+ else if (cls == Integer[].class)
+ r = smh.invokeExact(args[0], args[1], args[2], (Integer[]) tail);
+ else
+ r = smh.invoke(args[0], args[1], args[2], tail);
+ assertEquals(r0, r);
+ // Try null array in addition to zero-length array:
+ tail = null;
+ if (cls == Object[].class)
+ r = smh.invokeExact(args[0], args[1], args[2], tail);
+ else if (cls == Integer[].class)
+ r = smh.invokeExact(args[0], args[1], args[2], (Integer[]) tail);
+ else
+ r = smh.invoke(args[0], args[1], args[2], tail);
+ assertEquals(r0, r);
+ }
+ }
+
+ @Test
+ public void testInvokeWithArguments() throws Throwable {
+ System.out.println("testing invokeWithArguments on all arities");
+ for (int arity = 0; arity < MAX_ARITY; arity++) {
+ Object[] args = testArgs(arity);
+ Object r0 = Objects.hash(args);
+ Object r = MH_hashArguments(arity).invokeWithArguments(args);
+ assertEquals("arity="+arity, r0, r);
+ }
+ // The next one is the most likely to fail:
+ int arity = MAX_ARITY;
+ Object[] args = testArgs(arity);
+ Object r0 = Objects.hash(args);
+ Object r = MH_hashArguments(arity).invokeWithArguments(args);
+ assertEquals("arity=MAX_ARITY", r0, r);
+ }
+
+ static Object[] cat(Object a, Object[] b) {
+ int alen = 1, blen = b.length;
+ Object[] c = new Object[alen + blen];
+ c[0] = a;
+ System.arraycopy(b, 0, c, alen, blen);
+ return c;
+ }
+
+ @Test
+ public void testArities() throws Throwable {
+ System.out.println("testing spreaders and collectors on high arities...");
+ int iterations = ITERATION_COUNT;
+ testArities(Object[].class, MIN_ARITY-10, MIN_ARITY-1, iterations / 1000);
+ testArities(Object[].class, MIN_ARITY, SLOW_ARITY-1, iterations);
+ testArities(Object[].class, SLOW_ARITY, MAX_ARITY, iterations / 1000);
+ }
+
+ @Test
+ public void testAritiesOnTypedArrays() throws Throwable {
+ for (Class<?> cls0 : new Class<?>[] {
+ Number[].class, Integer[].class, Comparable[].class
+ }) {
+ @SuppressWarnings("unchecked")
+ Class<? extends Object[]> cls = (Class<? extends Object[]>) cls0;
+ System.out.println("array class: "+cls.getSimpleName());
+ int iterations = ITERATION_COUNT / 1000;
+ testArities(cls, MIN_ARITY, SLOW_ARITY-1, iterations);
+ testArities(cls, SLOW_ARITY, MAX_ARITY, iterations / 100);
+ }
+ }
+
+ private void testArities(Class<? extends Object[]> cls,
+ int minArity,
+ int maxArity,
+ int iterations) throws Throwable {
+ boolean verbose = (cls == Object[].class);
+ for (int arity = minArity; arity <= maxArity; arity++) {
+ if (verbose) System.out.println("arity="+arity);
+ MethodHandle mh = MH_hashArguments(cls, arity);
+ MethodHandle mh_VA = mh.asSpreader(cls, arity);
+ assert(mh_VA.type().parameterType(0) == cls);
+ testArities(cls, arity, iterations, verbose, mh, mh_VA);
+ if (cls != Object[].class) {
+ // mh_CA will collect arguments of a particular type and pass them to mh_VA
+ MethodHandle mh_CA = mh_VA.asCollector(cls, arity);
+ MethodHandle mh_VA2 = mh_CA.asSpreader(cls, arity);
+ try {
+ mh_VA2.invokeWithArguments(new Object[arity]);
+ throw new AssertionError("should not reach");
+ } catch (ClassCastException | WrongMethodTypeException ex) {
+ }
+ assert(mh_CA.type().equals(mh.type()));
+ assert(mh_VA2.type().equals(mh_VA.type()));
+ testArities(cls, arity, iterations, false, mh_CA, mh_VA2);
+ }
+ }
+ }
+ private void testArities(Class<? extends Object[]> cls,
+ int arity,
+ int iterations,
+ boolean verbose,
+ MethodHandle mh,
+ MethodHandle mh_VA
+ ) throws Throwable {
+ if (iterations < 4) iterations = 4;
+ final int MAX_MH_ARITY = MAX_JVM_ARITY - 1; // mh.invoke(arg*[N])
+ final int MAX_INVOKER_ARITY = MAX_MH_ARITY - 1; // inv.invoke(mh, arg*[N])
+ Object[] args = testArgs(arity);
+ if (cls != Object[].class)
+ args = Arrays.copyOf(args, arity, cls);
+ Object r0 = Objects.hash(args);
+ Object r;
+ MethodHandle ximh = null;
+ MethodHandle gimh = null;
+ if (arity <= MAX_INVOKER_ARITY) {
+ ximh = MethodHandles.exactInvoker(mh.type());
+ gimh = MethodHandles.invoker(mh.type());
+ } else {
+ try {
+ ximh = MethodHandles.exactInvoker(mh.type());
+ throw new AssertionError("should fail to create ximh of arity "+arity);
+ } catch (IllegalArgumentException ex) {
+ if (verbose)
+ System.out.println("OK: xmih["+arity+"] => "+ex);
+ }
+ try {
+ gimh = MethodHandles.invoker(mh.type());
+ throw new AssertionError("should fail to create gimh of arity "+arity);
+ } catch (IllegalArgumentException ex) {
+ if (verbose)
+ System.out.println("OK: gmih["+arity+"] => "+ex);
+ }
+ }
+ Object[] mh_args = cat(mh, args);
+ assert(arity <= MAX_MH_ARITY);
+ for (int i = 0; i < iterations; ++i) {
+ if (cls == Object[].class)
+ r = mh_VA.invokeExact(args);
+ else if (cls == Integer[].class)
+ r = mh_VA.invokeExact((Integer[])args);
+ else
+ r = mh_VA.invoke(args);
+ assertEquals(r0, r);
+ r = mh.invokeWithArguments(args);
+ assertEquals(r0, r);
+ if (ximh != null) {
+ r = ximh.invokeWithArguments(mh_args);
+ assertEquals(r0, r);
+ }
+ if (gimh != null) {
+ r = gimh.invokeWithArguments(mh_args);
+ assertEquals(r0, r);
+ }
+ }
+ }
+
+ static Object hashArguments_252(
+ // <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
+ Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
+ Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
+ Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
+ Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
+ Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
+ Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
+ Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
+ Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
+ Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
+ Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
+ Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
+ Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
+ Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
+ Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
+ Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
+ Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
+ Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
+ Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
+ Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
+ Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
+ Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
+ Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
+ Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
+ Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
+ Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
+ Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
+ Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
+ Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
+ Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
+ Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
+ Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
+ // </editor-fold>
+ Object xF8, Object xF9, Object xFA, Object xFB) {
+ return Objects.hash(
+ // <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
+ x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+ x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+ x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+ x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+ x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+ x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+ x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+ x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+ x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+ x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+ xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+ xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+ xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+ xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+ xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+ xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
+ // </editor-fold>
+ xF8, xF9, xFA, xFB);
+ }
+
+ @Test
+ public void test252() throws Throwable {
+ final int ARITY = 252;
+ System.out.println("test"+ARITY);
+ Object[] a = testArgs(ARITY);
+ Object r0 = hashArguments(a);
+ Object r;
+ r = hashArguments_252(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+ assertEquals(r0, r);
+ MethodType mt = MethodType.genericMethodType(ARITY);
+ MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+ r = mh.invokeExact(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+ assertEquals(r0, r);
+ r = mh.invokeWithArguments(a);
+ assertEquals(r0, r);
+ MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
+ r = ximh.invokeExact(mh,
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+ assertEquals(r0, r);
+ r = ximh.invokeWithArguments(cat(mh,a));
+ assertEquals(r0, r);
+ MethodHandle gimh = MethodHandles.invoker(mh.type());
+ r = gimh.invoke(mh,
+ // <editor-fold defaultstate="collapsed" desc="(Number) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ (Number)
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+ assertEquals(r0, r);
+ r = gimh.invokeWithArguments(cat(mh,a));
+ assertEquals(r0, r);
+ mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
+ //System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
+ r = mh.invokeExact(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ (Integer)
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+ assertEquals(r0, r);
+ r = mh.invoke(
+ // <editor-fold defaultstate="collapsed" desc="(Comparable) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ (Comparable<?>)
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+ assertEquals(r0, r);
+ }
+
+ static Object hashArguments_253(
+ // <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
+ Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
+ Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
+ Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
+ Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
+ Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
+ Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
+ Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
+ Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
+ Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
+ Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
+ Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
+ Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
+ Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
+ Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
+ Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
+ Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
+ Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
+ Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
+ Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
+ Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
+ Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
+ Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
+ Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
+ Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
+ Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
+ Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
+ Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
+ Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
+ Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
+ Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
+ Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
+ // </editor-fold>
+ Object xF8, Object xF9, Object xFA, Object xFB, Object xFC) {
+ return Objects.hash(
+ // <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
+ x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+ x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+ x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+ x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+ x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+ x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+ x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+ x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+ x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+ x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+ xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+ xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+ xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+ xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+ xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+ xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
+ // </editor-fold>
+ xF8, xF9, xFA, xFB, xFC);
+ }
+
+ @Test
+ public void test253() throws Throwable {
+ final int ARITY = 253;
+ System.out.println("test"+ARITY);
+ Object[] a = testArgs(ARITY);
+ Object r0 = hashArguments(a);
+ Object r;
+ r = hashArguments_253(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+ assertEquals(r0, r);
+ MethodType mt = MethodType.genericMethodType(ARITY);
+ MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+ r = mh.invokeExact(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+ assertEquals(r0, r);
+ r = mh.invokeWithArguments(a);
+ assertEquals(r0, r);
+ MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
+ r = ximh.invokeExact(mh,
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+ assertEquals(r0, r);
+ // FIXME: This next one fails, because it uses an internal invoker of arity 255.
+ r = ximh.invokeWithArguments(cat(mh,a));
+ assertEquals(r0, r);
+ MethodHandle gimh = MethodHandles.invoker(mh.type());
+ r = gimh.invoke(mh,
+ // <editor-fold defaultstate="collapsed" desc="(Number) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ (Number)
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+ assertEquals(r0, r);
+ // FIXME: This next one fails, because it uses an internal invoker of arity 255.
+ r = gimh.invokeWithArguments(cat(mh,a));
+ assertEquals(r0, r);
+ mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
+ //System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
+ r = mh.invokeExact(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ (Integer)
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+ assertEquals(r0, r);
+ r = mh.invoke(
+ // <editor-fold defaultstate="collapsed" desc="(Comparable) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ (Comparable<?>)
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+ assertEquals(r0, r);
+ }
+
+ static Object hashArguments_254(
+ // <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
+ Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
+ Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
+ Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
+ Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
+ Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
+ Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
+ Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
+ Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
+ Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
+ Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
+ Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
+ Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
+ Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
+ Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
+ Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
+ Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
+ Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
+ Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
+ Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
+ Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
+ Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
+ Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
+ Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
+ Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
+ Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
+ Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
+ Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
+ Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
+ Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
+ Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
+ Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
+ // </editor-fold>
+ Object xF8, Object xF9, Object xFA, Object xFB, Object xFC, Object xFD) {
+ return Objects.hash(
+ // <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
+ x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+ x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+ x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+ x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+ x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+ x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+ x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+ x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+ x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+ x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+ xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+ xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+ xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+ xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+ xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+ xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
+ // </editor-fold>
+ xF8, xF9, xFA, xFB, xFC, xFD);
+ }
+
+ @Test
+ public void test254() throws Throwable {
+ final int ARITY = 254;
+ System.out.println("test"+ARITY);
+ Object[] a = testArgs(ARITY);
+ Object r0 = hashArguments(a);
+ Object r;
+ r = hashArguments_254(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+ assertEquals(r0, r);
+ MethodType mt = MethodType.genericMethodType(ARITY);
+ MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+ r = mh.invokeExact(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+ assertEquals(r0, r);
+ // FIXME: This next one fails, because it uses an internal invoker of arity 255.
+ r = mh.invokeWithArguments(a);
+ assertEquals(r0, r);
+ try {
+ MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
+ throw new AssertionError("should have thrown IAE; cannot have 1+1+254 arguments");
+ } catch (IllegalArgumentException ex) {
+ System.out.println("OK: "+ex);
+ }
+ mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
+ //System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
+ r = mh.invokeExact(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ (Integer)
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+ assertEquals(r0, r);
+ mh = mh.asType(mh.type().changeParameterType(0xE0, Number.class));
+ //System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
+ r = mh.invokeExact(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ... (Number) a[0xE0], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ (Integer)
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ (Number)
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+ assertEquals(r0, r);
+ r = mh.invoke(
+ // <editor-fold defaultstate="collapsed" desc="(Comparable) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ (Comparable<?>)
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+ assertEquals(r0, r);
+ }
+
+ static Object hashArguments_255(
+ // <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
+ Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
+ Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
+ Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
+ Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
+ Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
+ Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
+ Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
+ Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
+ Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
+ Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
+ Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
+ Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
+ Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
+ Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
+ Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
+ Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
+ Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
+ Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
+ Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
+ Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
+ Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
+ Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
+ Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
+ Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
+ Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
+ Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
+ Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
+ Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
+ Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
+ Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
+ Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
+ // </editor-fold>
+ Object xF8, Object xF9, Object xFA, Object xFB, Object xFC, Object xFD, Object xFE) {
+ return Objects.hash(
+ // <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
+ x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+ x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+ x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+ x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+ x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+ x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+ x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+ x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+ x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+ x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+ xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+ xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+ xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+ xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+ xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+ xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
+ // </editor-fold>
+ xF8, xF9, xFA, xFB, xFC, xFD, xFE);
+ }
+
+ @Test
+ public void test255() throws Throwable {
+ final int ARITY = 255;
+ System.out.println("test"+ARITY);
+ Object[] a = testArgs(ARITY);
+ Object r0 = hashArguments(a);
+ Object r;
+ r = hashArguments_255(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]);
+ assertEquals(r0, r);
+ MethodType mt = MethodType.genericMethodType(ARITY);
+ MethodHandle mh;
+ try {
+ mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+ throw new AssertionError("should not create an arity 255 method handle");
+ } catch (IllegalArgumentException ex) {
+ System.out.println("OK: "+ex);
+ mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+(ARITY-1), mt.dropParameterTypes(ARITY-1, ARITY));
+ }
+ try {
+ r = mh.invokeExact(
+ // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+ a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+ a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+ a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+ a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+ a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+ a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+ a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+ a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+ a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+ a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+ a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+ a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+ a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+ a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+ a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+ a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+ // </editor-fold>
+ a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]);
+ throw new AssertionError("should not call an arity 255 method handle");
+ } catch (LinkageError ex) {
+ System.out.println("OK: "+ex);
+ }
+ try {
+ MethodHandle ximh = MethodHandles.exactInvoker(mt);
+ throw new AssertionError("should have thrown IAE; cannot have 1+1+255 arguments");
+ } catch (IllegalArgumentException ex) {
+ System.out.println("OK: "+ex);
+ }
+ }
+}
--- a/jdk/test/java/lang/invoke/MaxTest.java Fri Sep 14 09:47:14 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/*
- * 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. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @summary BoundMethodHandle tests with primitive types
- * @compile MaxTest.java
- * @run junit/othervm test.java.lang.invoke.MaxTest
- */
-
-package test.java.lang.invoke;
-
-import static org.junit.Assert.assertEquals;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-
-import org.junit.Test;
-
-public class MaxTest {
-
- static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
-
- private MethodHandle getMax(Class<?> t) throws Throwable {
- return LOOKUP.findStatic(Math.class, "max", MethodType.methodType(t, t, t));
- }
-
- static int ITERATION_COUNT = 40000;
- static {
- String iterations = System.getProperty(MaxTest.class.getSimpleName() + ".ITERATION_COUNT");
- if (iterations == null) {
- iterations = System.getProperty(MaxTest.class.getName() + ".ITERATION_COUNT");
- }
- if (iterations != null) {
- ITERATION_COUNT = Integer.parseInt(iterations);
- }
- }
-
- @Test
- public void testMaxLong() throws Throwable {
- final Class<?> C = long.class;
- final long P = 23L;
- final long Q = 42L;
- final long R = Math.max(P, Q);
- for (int i = 0; i < ITERATION_COUNT; ++i) {
- MethodHandle h = getMax(C);
- assertEquals((long) h.invokeExact(P, Q), R);
- MethodHandle bh = MethodHandles.insertArguments(h, 0, P);
- assertEquals((long) bh.invokeExact(Q), R);
- MethodHandle bbh = MethodHandles.insertArguments(bh, 0, Q);
- assertEquals((long) bbh.invokeExact(), R);
- MethodHandle b2h = MethodHandles.insertArguments(h, 1, Q);
- assertEquals((long) b2h.invokeExact(P), R);
- MethodHandle bb2h = MethodHandles.insertArguments(b2h, 0, P);
- assertEquals((long) bb2h.invokeExact(), R);
- }
- }
-
- @Test
- public void testMaxInt() throws Throwable {
- final Class<?> C = int.class;
- final int P = 23;
- final int Q = 42;
- final int R = Math.max(P, Q);
- for (int i = 0; i < ITERATION_COUNT; ++i) {
- MethodHandle h = getMax(C);
- assertEquals((int) h.invokeExact(P, Q), R);
- MethodHandle bh = MethodHandles.insertArguments(h, 0, P);
- assertEquals((int) bh.invokeExact(Q), R);
- MethodHandle bbh = MethodHandles.insertArguments(bh, 0, Q);
- assertEquals((int) bbh.invokeExact(), R);
- MethodHandle b2h = MethodHandles.insertArguments(h, 1, Q);
- assertEquals((int) b2h.invokeExact(P), R);
- MethodHandle bb2h = MethodHandles.insertArguments(b2h, 0, P);
- assertEquals((int) bb2h.invokeExact(), R);
- }
- }
-
- @Test
- public void testMaxFloat() throws Throwable {
- final Class<?> C = float.class;
- final float P = 23F;
- final float Q = 42F;
- final float R = Math.max(P, Q);
- final float D = 0.1F;
- for (int i = 0; i < ITERATION_COUNT; ++i) {
- MethodHandle h = getMax(C);
- assertEquals((float) h.invokeExact(P, Q), R, D);
- MethodHandle bh = MethodHandles.insertArguments(h, 0, P);
- assertEquals((float) bh.invokeExact(Q), R, D);
- MethodHandle bbh = MethodHandles.insertArguments(bh, 0, Q);
- assertEquals((float) bbh.invokeExact(), R, D);
- MethodHandle b2h = MethodHandles.insertArguments(h, 1, Q);
- assertEquals((float) b2h.invokeExact(P), R, D);
- MethodHandle bb2h = MethodHandles.insertArguments(b2h, 0, P);
- assertEquals((float) bb2h.invokeExact(), R, D);
- }
- }
-
- @Test
- public void testMaxDouble() throws Throwable {
- final Class<?> C = double.class;
- final double P = 23F;
- final double Q = 42F;
- final double R = Math.max(P, Q);
- final double D = 0.1;
- for (int i = 0; i < ITERATION_COUNT; ++i) {
- MethodHandle h = getMax(C);
- assertEquals((double) h.invokeExact(P, Q), R, D);
- MethodHandle bh = MethodHandles.insertArguments(h, 0, P);
- assertEquals((double) bh.invokeExact(Q), R, D);
- MethodHandle bbh = MethodHandles.insertArguments(bh, 0, Q);
- assertEquals((double) bbh.invokeExact(), R, D);
- MethodHandle b2h = MethodHandles.insertArguments(h, 1, Q);
- assertEquals((double) b2h.invokeExact(P), R, D);
- MethodHandle bb2h = MethodHandles.insertArguments(b2h, 0, P);
- assertEquals((double) bb2h.invokeExact(), R, D);
- }
- }
-
-}
--- a/jdk/test/java/lang/invoke/MethodHandlesTest.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java Fri Sep 14 10:14:02 2012 -0700
@@ -1485,7 +1485,7 @@
RuntimeException error = null;
try {
target = id.asType(newType);
- } catch (RuntimeException ex) {
+ } catch (WrongMethodTypeException ex) {
error = ex;
}
if (verbosity >= 3)
@@ -2381,47 +2381,100 @@
assertSame(thrown, caught);
}
- //@Test
+ @Test
public void testInterfaceCast() throws Throwable {
//if (CAN_SKIP_WORKING) return;
startTest("interfaceCast");
- for (Class<?> ctype : new Class<?>[]{ Object.class, String.class, CharSequence.class, Number.class, Iterable.class}) {
- testInterfaceCast(ctype, false, false);
- testInterfaceCast(ctype, true, false);
- testInterfaceCast(ctype, false, true);
- testInterfaceCast(ctype, true, true);
+ assert( (((Object)"foo") instanceof CharSequence));
+ assert(!(((Object)"foo") instanceof Iterable));
+ for (MethodHandle mh : new MethodHandle[]{
+ MethodHandles.identity(String.class),
+ MethodHandles.identity(CharSequence.class),
+ MethodHandles.identity(Iterable.class)
+ }) {
+ if (verbosity > 0) System.out.println("-- mh = "+mh);
+ for (Class<?> ctype : new Class<?>[]{
+ Object.class, String.class, CharSequence.class,
+ Number.class, Iterable.class
+ }) {
+ if (verbosity > 0) System.out.println("---- ctype = "+ctype.getName());
+ // doret docast
+ testInterfaceCast(mh, ctype, false, false);
+ testInterfaceCast(mh, ctype, true, false);
+ testInterfaceCast(mh, ctype, false, true);
+ testInterfaceCast(mh, ctype, true, true);
+ }
}
}
- public void testInterfaceCast(Class<?> ctype, boolean doret, boolean docast) throws Throwable {
- String str = "normal return value";
- MethodHandle mh = MethodHandles.identity(String.class);
+ private static Class<?> i2o(Class<?> c) {
+ return (c.isInterface() ? Object.class : c);
+ }
+ public void testInterfaceCast(MethodHandle mh, Class<?> ctype,
+ boolean doret, boolean docast) throws Throwable {
+ MethodHandle mh0 = mh;
+ if (verbosity > 1)
+ System.out.println("mh="+mh+", ctype="+ctype.getName()+", doret="+doret+", docast="+docast);
+ String normalRetVal = "normal return value";
MethodType mt = mh.type();
+ MethodType mt0 = mt;
if (doret) mt = mt.changeReturnType(ctype);
else mt = mt.changeParameterType(0, ctype);
if (docast) mh = MethodHandles.explicitCastArguments(mh, mt);
else mh = mh.asType(mt);
+ assertEquals(mt, mh.type());
+ MethodType mt1 = mt;
// this bit is needed to make the interface types disappear for invokeWithArguments:
mh = MethodHandles.explicitCastArguments(mh, mt.generic());
- boolean expectFail = !ctype.isInstance(str);
- if (ctype.isInterface()) {
- // special rules: interfaces slide by more frequently
- if (docast || !doret) expectFail = false;
+ Class<?>[] step = {
+ mt1.parameterType(0), // param as passed to mh at first
+ mt0.parameterType(0), // param after incoming cast
+ mt0.returnType(), // return value before cast
+ mt1.returnType(), // return value after outgoing cast
+ };
+ // where might a checkCast occur?
+ boolean[] checkCast = new boolean[step.length];
+ // the string value must pass each step without causing an exception
+ if (!docast) {
+ if (!doret) {
+ if (step[0] != step[1])
+ checkCast[1] = true; // incoming value is cast
+ } else {
+ if (step[2] != step[3])
+ checkCast[3] = true; // outgoing value is cast
+ }
}
+ boolean expectFail = false;
+ for (int i = 0; i < step.length; i++) {
+ Class<?> c = step[i];
+ if (!checkCast[i]) c = i2o(c);
+ if (!c.isInstance(normalRetVal)) {
+ if (verbosity > 3)
+ System.out.println("expect failure at step "+i+" in "+Arrays.toString(step)+Arrays.toString(checkCast));
+ expectFail = true;
+ break;
+ }
+ }
+ countTest(!expectFail);
+ if (verbosity > 2)
+ System.out.println("expectFail="+expectFail+", mt="+mt);
Object res;
try {
- res = mh.invokeWithArguments(str);
+ res = mh.invokeWithArguments(normalRetVal);
} catch (Exception ex) {
res = ex;
}
boolean sawFail = !(res instanceof String);
if (sawFail != expectFail) {
- System.out.println("*** testInterfaceCast: "+mh+" was "+mt+" => "+res+(docast ? " (explicitCastArguments)" : ""));
+ System.out.println("*** testInterfaceCast: mh0 = "+mh0);
+ System.out.println(" retype using "+(docast ? "explicitCastArguments" : "asType")+" to "+mt+" => "+mh);
+ System.out.println(" call returned "+res);
+ System.out.println(" expected "+(expectFail ? "an exception" : normalRetVal));
}
- if (!sawFail) {
- assertFalse(res.toString(), expectFail);
- assertEquals(str, res);
+ if (!expectFail) {
+ assertFalse(res.toString(), sawFail);
+ assertEquals(normalRetVal, res);
} else {
- assertTrue(res.toString(), expectFail);
+ assertTrue(res.toString(), sawFail);
}
}
--- a/jdk/test/java/lang/invoke/PermuteArgsTest.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/test/java/lang/invoke/PermuteArgsTest.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
/* @test
* @summary unit tests for method handles which permute their arguments
- * @run junit/othervm -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest
+ * @run junit/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest
*/
/* Examples of manual runs:
* java -DPermuteArgsTest.{DRY_RUN=true,MAX_ARITY=253} test.java.lang.invoke.PermuteArgsTest
@@ -191,7 +191,11 @@
pt = mt1.parameterType(mt1.parameterCount() - posArgs);
mt1 = mt1.appendParameterTypes(pt);
}
- return mh.asType(mt1);
+ try {
+ return mh.asType(mt1);
+ } catch (WrongMethodTypeException | IllegalArgumentException ex) {
+ throw new IllegalArgumentException("cannot convert to type "+mt1+" from "+mh, ex);
+ }
}
static MethodHandle findTestMH(String name, int[] perm) throws ReflectiveOperationException {
int arity = perm.length;
--- a/jdk/test/java/lang/invoke/RicochetTest.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/test/java/lang/invoke/RicochetTest.java Fri Sep 14 10:14:02 2012 -0700
@@ -256,7 +256,7 @@
//System.out.println(" expect="+expect);
// now use the combined MH, and test the output:
- MethodHandle mh = collectArguments(lister, pos, INT_COLLECTORS[collects]);
+ MethodHandle mh = collectArguments(lister, pos, int[].class, INT_COLLECTORS[collects]);
if (mh == null) continue; // no infix collection, yet
assert(mh.type().parameterCount() == inputs);
Object observe = mh.asSpreader(int[].class, args.length).invokeExact(args);
@@ -266,13 +266,53 @@
}
}
- private static MethodHandle collectArguments(MethodHandle lister, int pos, MethodHandle collector) {
+ @Test
+ public void testByteCollects() throws Throwable {
+ if (!startTest("testByteCollects")) return;
+ for (MethodHandle lister : BYTE_LISTERS) {
+ int outputs = lister.type().parameterCount();
+ for (int collects = 0; collects <= Math.min(outputs, BYTE_COLLECTORS.length-1); collects++) {
+ int inputs = outputs - 1 + collects;
+ if (inputs < 0) continue;
+ for (int pos = 0; pos + collects <= inputs; pos++) {
+ MethodHandle collector = BYTE_COLLECTORS[collects];
+ byte[] args = new byte[inputs];
+ int ap = 0, arg = 31;
+ for (int i = 0; i < pos; i++)
+ args[ap++] = (byte)(arg++ + 0);
+ for (int i = 0; i < collects; i++)
+ args[ap++] = (byte)(arg++ + 10);
+ while (ap < args.length)
+ args[ap++] = (byte)(arg++ + 20);
+ // calculate piecemeal:
+ //System.out.println("testIntCollects "+Arrays.asList(lister, pos, collector)+" on "+Arrays.toString(args));
+ byte[] collargs = Arrays.copyOfRange(args, pos, pos+collects);
+ byte coll = (byte) collector.asSpreader(byte[].class, collargs.length).invokeExact(collargs);
+ byte[] listargs = Arrays.copyOfRange(args, 0, outputs);
+ System.arraycopy(args, pos+collects, listargs, pos+1, outputs - (pos+1));
+ listargs[pos] = coll;
+ //System.out.println(" coll="+coll+" listargs="+Arrays.toString(listargs));
+ Object expect = lister.asSpreader(byte[].class, listargs.length).invokeExact(listargs);
+ //System.out.println(" expect="+expect);
+
+ // now use the combined MH, and test the output:
+ MethodHandle mh = collectArguments(lister, pos, byte[].class, BYTE_COLLECTORS[collects]);
+ if (mh == null) continue; // no infix collection, yet
+ assert(mh.type().parameterCount() == inputs);
+ Object observe = mh.asSpreader(byte[].class, args.length).invokeExact(args);
+ assertEquals(expect, observe);
+ }
+ }
+ }
+ }
+
+ private static MethodHandle collectArguments(MethodHandle lister, int pos, Class<?> array, MethodHandle collector) {
int collects = collector.type().parameterCount();
int outputs = lister.type().parameterCount();
if (pos == outputs - 1)
return MethodHandles.filterArguments(lister, pos,
- collector.asSpreader(int[].class, collects))
- .asCollector(int[].class, collects);
+ collector.asSpreader(array, collects))
+ .asCollector(array, collects);
//return MethodHandles.collectArguments(lister, pos, collector); //no such animal
return null;
}
@@ -537,6 +577,9 @@
private static final MethodHandle[] INT_COLLECTORS = {
constant(int.class, 42), opI, opI2, opI3, opI4
};
+ private static final MethodHandle[] BYTE_COLLECTORS = {
+ constant(byte.class, (byte)42), i2b(opI), i2b(opI2), i2b(opI3), i2b(opI4)
+ };
private static final MethodHandle[] LONG_COLLECTORS = {
constant(long.class, 42), opJ, opJ2, opJ3
};
@@ -559,21 +602,36 @@
Collections.nCopies(8, int.class));
private static final MethodHandle list8longs = findStatic("list8longs", Object.class,
Collections.nCopies(8, long.class));
- private static final MethodHandle[] INT_LISTERS, LONG_LISTERS;
+ private static final MethodHandle[] INT_LISTERS, LONG_LISTERS, BYTE_LISTERS;
static {
int listerCount = list8ints.type().parameterCount() + 1;
INT_LISTERS = new MethodHandle[listerCount];
LONG_LISTERS = new MethodHandle[listerCount];
+ BYTE_LISTERS = new MethodHandle[listerCount];
MethodHandle lister = list8ints;
MethodHandle llister = list8longs;
for (int i = listerCount - 1; ; i--) {
INT_LISTERS[i] = lister;
LONG_LISTERS[i] = llister;
+ BYTE_LISTERS[i] = i2b(lister);
if (i == 0) break;
lister = insertArguments(lister, i-1, 0);
llister = insertArguments(llister, i-1, 0L);
}
}
+ private static MethodHandle i2b(MethodHandle mh) {
+ return MethodHandles.explicitCastArguments(mh, subst(mh.type(), int.class, byte.class));
+ }
+ private static MethodType subst(MethodType mt, Class<?> from, Class<?> to) {
+ for (int i = 0; i < mt.parameterCount(); i++) {
+ if (mt.parameterType(i) == from)
+ mt = mt.changeParameterType(i, to);
+ }
+ if (mt.returnType() == from)
+ mt = mt.changeReturnType(to);
+ return mt;
+ }
+
private static Object convI_L(int x) { stress(); return (Object) x; }
private static int convL_I(Object x) { stress(); return (int) x; }
--- a/jdk/test/sun/invoke/util/ValueConversionsTest.java Fri Sep 14 09:47:14 2012 -0700
+++ b/jdk/test/sun/invoke/util/ValueConversionsTest.java Fri Sep 14 10:14:02 2012 -0700
@@ -159,14 +159,8 @@
assertEquals(caster.type(), ValueConversions.identity().type());
for (Object obj : objects) {
Class<?> src = obj.getClass();
- boolean canCast;
- if (dst.isInterface()) {
- canCast = true;
- } else {
- canCast = dst.isAssignableFrom(src);
- assertEquals(canCast, dst.isInstance(obj));
- }
- //System.out.println("obj="+obj+" <: dst="+dst);
+ boolean canCast = dst.isAssignableFrom(src);
+ //System.out.println("obj="+obj+" <: dst="+dst+(canCast ? " (OK)" : " (will fail)"));
try {
Object result = caster.invokeExact(obj);
if (canCast)
--- a/langtools/.hgtags Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/.hgtags Fri Sep 14 10:14:02 2012 -0700
@@ -175,3 +175,5 @@
c4cd4cab2220817c88c8c139c9bfc91c36b48826 jdk8-b51
1d2db0e5eabc2eaf865986f7b7ffbf7b14b00232 jdk8-b52
d3d0b9cd76e04bf9e381b402630ac3cfe464bb38 jdk8-b53
+9cf72631baf5cb1ebd8736c5efeab7746977ea68 jdk8-b54
+e48e7e1f026b82d921433150180799898c088890 jdk8-b55
--- a/langtools/make/jprt.properties Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/make/jprt.properties Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/langtools/make/tools/anttasks/CompilePropertiesTask.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/make/tools/anttasks/CompilePropertiesTask.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/make/tools/anttasks/GenStubsTask.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/make/tools/anttasks/GenStubsTask.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/make/tools/anttasks/SelectToolTask.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/make/tools/anttasks/SelectToolTask.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/make/tools/compileproperties/CompileProperties.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/make/tools/compileproperties/CompileProperties.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/make/tools/genstubs/GenStubs.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/make/tools/genstubs/GenStubs.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Annotations.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,294 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.tools.javac.code;
+
+import java.util.Map;
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.comp.Annotate;
+import com.sun.tools.javac.comp.AttrContext;
+import com.sun.tools.javac.comp.Env;
+import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.Log;
+import com.sun.tools.javac.util.Pair;
+
+import static com.sun.tools.javac.code.Kinds.PCK;
+import com.sun.tools.javac.util.*;
+
+/**
+ * Container for all annotations (attributes in javac) on a Symbol.
+ *
+ * This class is explicitly mutable. Its contents will change when attributes
+ * are annotated onto the Symbol. However this class depends on the facts that
+ * List (in javac) is immutable.
+ *
+ * An instance of this class can be in one of three states:
+ *
+ * NOT_STARTED indicates that the Symbol this instance belongs to have not been
+ * annotated (yet). Specifically if the declaration is not annotated this
+ * instance will never move past NOT_STARTED. You can never go back to
+ * NOT_STARTED.
+ *
+ * IN_PROGRESS annotations have been found on the declaration. Will be processed
+ * later. You can reset to IN_PROGRESS. While IN_PROGRESS you can set the list
+ * of attributes (and this moves out of the IN_PROGRESS state).
+ *
+ * "unnamed" this Annotations contains some attributes, possibly the final set.
+ * While in this state you can only prepend or append to the attributes not set
+ * it directly. You can also move back to the IN_PROGRESS sate using reset().
+ *
+ * <p><b>This is NOT part of any supported API. If you write code that depends
+ * on this, you do so at your own risk. This code and its internal interfaces
+ * are subject to change or deletion without notice.</b>
+ */
+public class Annotations {
+
+ private static final List<Attribute.Compound> NOT_STARTED = List.of(null);
+ private static final List<Attribute.Compound> IN_PROGRESS = List.of(null);
+ /*
+ * This field should never be null
+ */
+ private List<Attribute.Compound> attributes = NOT_STARTED;
+ /*
+ * The Symbol this Annotatios belong to
+ */
+ private final Symbol s;
+
+ public Annotations(Symbol s) {
+ this.s = s;
+ }
+
+ public List<Attribute.Compound> getAttributes() {
+ return filterSentinels(attributes);
+ }
+
+ public void setAttributes(List<Attribute.Compound> a) {
+ Assert.check(pendingCompletion() || !isStarted());
+ if (a == null) {
+ throw new NullPointerException();
+ }
+ attributes = a;
+ }
+
+ public void setAttributes(Annotations other) {
+ if (other == null) {
+ throw new NullPointerException();
+ }
+ setAttributes(other.getAttributes());
+ }
+
+ public void setAttributesWithCompletion(final Annotate.AnnotateRepeatedContext ctx) {
+ Assert.check(pendingCompletion() || (!isStarted() && s.kind == PCK));
+
+ Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated = ctx.annotated;
+ boolean atLeastOneRepeated = false;
+ List<Attribute.Compound> buf = List.<Attribute.Compound>nil();
+ for (ListBuffer<Attribute.Compound> lb : annotated.values()) {
+ if (lb.size() == 1) {
+ buf = buf.prepend(lb.first());
+ } else { // repeated
+ buf = buf.prepend(new Placeholder(lb.toList(), s));
+ atLeastOneRepeated = true;
+ }
+ }
+
+ // Add non-repeating attributes
+ setAttributes(buf.reverse());
+
+ if (atLeastOneRepeated) {
+ // The Symbol s is now annotated with a combination of
+ // finished non-repeating annotations and placeholders for
+ // repeating annotations.
+ //
+ // We need to do this in two passes because when creating
+ // a container for a repeating annotation we must
+ // guarantee that the @ContainedBy on the
+ // contained annotation is fully annotated
+ //
+ // The way we force this order is to do all repeating
+ // annotations in a pass after all non-repeating are
+ // finished. This will work because @ContainedBy
+ // is non-repeating and therefore will be annotated in the
+ // fist pass.
+
+ // Queue a pass that will replace Attribute.Placeholders
+ // with Attribute.Compound (made from synthesized containers).
+ ctx.annotateRepeated(new Annotate.Annotator() {
+
+ @Override
+ public String toString() {
+ return "repeated annotation pass of: " + s + " in: " + s.owner;
+ }
+
+ @Override
+ public void enterAnnotation() {
+ complete(ctx);
+ }
+ });
+ }
+ }
+
+ public Annotations reset() {
+ attributes = IN_PROGRESS;
+ return this;
+ }
+
+ public boolean isEmpty() {
+ return !isStarted()
+ || pendingCompletion()
+ || attributes.isEmpty();
+ }
+
+ public boolean pendingCompletion() {
+ return attributes == IN_PROGRESS;
+ }
+
+ public Annotations append(List<Attribute.Compound> l) {
+ attributes = filterSentinels(attributes);
+
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (attributes.isEmpty()) {
+ attributes = l;
+ } else {
+ attributes = attributes.appendList(l);
+ }
+ return this;
+ }
+
+ public Annotations prepend(List<Attribute.Compound> l) {
+ attributes = filterSentinels(attributes);
+
+ if (l.isEmpty()) {
+ ; // no-op
+ } else if (attributes.isEmpty()) {
+ attributes = l;
+ } else {
+ attributes = attributes.prependList(l);
+ }
+ return this;
+ }
+
+ private List<Attribute.Compound> filterSentinels(List<Attribute.Compound> a) {
+ return (a == IN_PROGRESS || a == NOT_STARTED)
+ ? List.<Attribute.Compound>nil()
+ : a;
+ }
+
+ private boolean isStarted() {
+ return attributes != NOT_STARTED;
+ }
+
+ private List<Attribute.Compound> getPlaceholders() {
+ List<Attribute.Compound> res = List.<Attribute.Compound>nil();
+ for (Attribute.Compound a : filterSentinels(attributes)) {
+ if (a instanceof Placeholder) {
+ res = res.prepend(a);
+ }
+ }
+ return res.reverse();
+ }
+
+ /*
+ * Replace Placeholders for repeating annotations with their containers
+ */
+ private void complete(Annotate.AnnotateRepeatedContext ctx) {
+ Assert.check(!pendingCompletion());
+ Log log = ctx.log;
+ Env<AttrContext> env = ctx.env;
+ JavaFileObject oldSource = log.useSource(env.toplevel.sourcefile);
+ try {
+
+ if (isEmpty()) {
+ return;
+ }
+
+ List<Attribute.Compound> result = List.nil();
+ for (Attribute.Compound a : getAttributes()) {
+ if (a instanceof Placeholder) {
+ Attribute.Compound replacement = replaceOne((Placeholder) a, ctx);
+
+ if (null != replacement) {
+ result = result.prepend(replacement);
+ }
+ } else {
+ result = result.prepend(a);
+ }
+ }
+
+ attributes = result.reverse();
+
+ Assert.check(Annotations.this.getPlaceholders().isEmpty());
+ } finally {
+ log.useSource(oldSource);
+ }
+ }
+
+ private Attribute.Compound replaceOne(Placeholder placeholder, Annotate.AnnotateRepeatedContext ctx) {
+ Log log = ctx.log;
+
+ // Process repeated annotations
+ Attribute.Compound validRepeated =
+ ctx.processRepeatedAnnotations(placeholder.getPlaceholderFor());
+
+ if (validRepeated != null) {
+ // Check that the container isn't manually
+ // present along with repeated instances of
+ // its contained annotation.
+ ListBuffer<Attribute.Compound> manualContainer = ctx.annotated.get(validRepeated.type.tsym);
+ if (manualContainer != null) {
+ log.error(ctx.pos.get(manualContainer.first()), "invalid.containedby.annotation.repeated.and.container.present",
+ manualContainer.first().type.tsym);
+ }
+ }
+
+ // A null return will delete the Placeholder
+ return validRepeated;
+
+ }
+
+ private static class Placeholder extends Attribute.Compound {
+
+ private List<Attribute.Compound> placeholderFor;
+ private Symbol on;
+
+ public Placeholder(List<Attribute.Compound> placeholderFor, Symbol on) {
+ super(Type.noType, List.<Pair<Symbol.MethodSymbol, Attribute>>nil());
+ this.placeholderFor = placeholderFor;
+ this.on = on;
+ }
+
+ @Override
+ public String toString() {
+ return "<placeholder: " + placeholderFor + " on: " + on + ">";
+ }
+
+ public List<Attribute.Compound> getPlaceholderFor() {
+ return placeholderFor;
+ }
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Attribute.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -103,11 +103,11 @@
* represented as a ClassSymbol.
*/
public static class Class extends Attribute {
- public final Type type;
+ public final Type classType;
public void accept(Visitor v) { v.visitClass(this); }
public Class(Types types, Type type) {
super(makeClassType(types, type));
- this.type = type;
+ this.classType = type;
}
static Type makeClassType(Types types, Type type) {
Type arg = type.isPrimitive()
@@ -118,13 +118,13 @@
types.syms.classType.tsym);
}
public String toString() {
- return type + ".class";
+ return classType + ".class";
}
public Type getValue() {
- return type;
+ return classType;
}
public <R, P> R accept(AnnotationValueVisitor<R, P> v, P p) {
- return v.visitType(type, p);
+ return v.visitType(classType, p);
}
}
@@ -212,6 +212,12 @@
super(type);
this.values = values;
}
+
+ public Array(Type type, List<Attribute> values) {
+ super(type);
+ this.values = values.toArray(new Attribute[values.size()]);
+ }
+
public void accept(Visitor v) { v.visitArray(this); }
public String toString() {
StringBuilder buf = new StringBuilder();
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Lint.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -70,16 +70,16 @@
* Returns the result of combining the values in this object with
* the given annotations.
*/
- public Lint augment(List<Attribute.Compound> attrs) {
- return augmentor.augment(this, attrs);
+ public Lint augment(Annotations annots) {
+ return augmentor.augment(this, annots.getAttributes());
}
/**
* Returns the result of combining the values in this object with
* the given annotations and flags.
*/
- public Lint augment(List<Attribute.Compound> attrs, long flags) {
- Lint l = augmentor.augment(this, attrs);
+ public Lint augment(Annotations annots, long flags) {
+ Lint l = augmentor.augment(this, annots.getAttributes());
if ((flags & DEPRECATED) != 0) {
if (l == this)
l = new Lint(this);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -203,6 +203,9 @@
public boolean allowEffectivelyFinalInInnerClasses() {
return compareTo(JDK1_8) >= 0;
}
+ public boolean allowRepeatedAnnotations() {
+ return compareTo(JDK1_8) >= 0;
+ }
public static SourceVersion toSourceVersion(Source source) {
switch(source) {
case JDK1_2:
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Sep 14 10:14:02 2012 -0700
@@ -72,22 +72,24 @@
*/
public long flags() { return flags_field; }
- /** The attributes of this symbol.
+ /** The attributes of this symbol are contained in this
+ * Annotations. The Annotations instance is NOT immutable.
*/
- public List<Attribute.Compound> attributes_field;
+ public final Annotations annotations = new Annotations(this);
/** An accessor method for the attributes of this symbol.
* Attributes of class symbols should be accessed through the accessor
* method to make sure that the class symbol is loaded.
*/
public List<Attribute.Compound> getAnnotationMirrors() {
- return Assert.checkNonNull(attributes_field);
+ return Assert.checkNonNull(annotations.getAttributes());
}
/** Fetch a particular annotation from a symbol. */
public Attribute.Compound attribute(Symbol anno) {
- for (Attribute.Compound a : getAnnotationMirrors())
+ for (Attribute.Compound a : getAnnotationMirrors()) {
if (a.type.tsym == anno) return a;
+ }
return null;
}
@@ -120,7 +122,6 @@
this.owner = owner;
this.completer = null;
this.erasure_field = null;
- this.attributes_field = List.nil();
this.name = name;
}
@@ -657,10 +658,11 @@
if (completer != null) complete();
if (package_info != null && package_info.completer != null) {
package_info.complete();
- if (attributes_field.isEmpty())
- attributes_field = package_info.attributes_field;
+ if (annotations.isEmpty()) {
+ annotations.setAttributes(package_info.annotations);
}
- return Assert.checkNonNull(attributes_field);
+ }
+ return Assert.checkNonNull(annotations.getAttributes());
}
/** A package "exists" if a type or package that exists has
@@ -762,7 +764,7 @@
public List<Attribute.Compound> getAnnotationMirrors() {
if (completer != null) complete();
- return Assert.checkNonNull(attributes_field);
+ return Assert.checkNonNull(annotations.getAttributes());
}
public Type erasure(Types types) {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Fri Sep 14 10:14:02 2012 -0700
@@ -156,6 +156,10 @@
public final Type systemType;
public final Type autoCloseableType;
public final Type trustMeType;
+ public final Type containedByType;
+ public final Type containerForType;
+ public final Type documentedType;
+ public final Type elementTypeType;
/** The symbol representing the length field of an array.
*/
@@ -468,6 +472,10 @@
deprecatedType = enterClass("java.lang.Deprecated");
suppressWarningsType = enterClass("java.lang.SuppressWarnings");
inheritedType = enterClass("java.lang.annotation.Inherited");
+ containedByType = enterClass("java.lang.annotation.ContainedBy");
+ containerForType = enterClass("java.lang.annotation.ContainerFor");
+ documentedType = enterClass("java.lang.annotation.Documented");
+ elementTypeType = enterClass("java.lang.annotation.ElementType");
systemType = enterClass("java.lang.System");
autoCloseableType = enterClass("java.lang.AutoCloseable");
autoCloseableClose = new MethodSymbol(PUBLIC,
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Sep 14 10:14:02 2012 -0700
@@ -1358,6 +1358,20 @@
}
return result;
}
+
+ /**
+ * Returns an ArrayType with the component type t
+ *
+ * @param t The component type of the ArrayType
+ * @return the ArrayType for the given component
+ */
+ public ArrayType makeArrayType(Type t) {
+ if (t.tag == VOID ||
+ t.tag >= PACKAGE) {
+ Assert.error("Type t must not be a a VOID or PACKAGE type, " + t.toString());
+ }
+ return new ArrayType(t, syms.arrayClass);
+ }
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="asSuper">
@@ -1589,9 +1603,16 @@
* type parameters in t are deleted.
*/
public Type erasure(Type t) {
- return erasure(t, false);
+ return eraseNotNeeded(t)? t : erasure(t, false);
}
//where
+ private boolean eraseNotNeeded(Type t) {
+ // We don't want to erase primitive types and String type as that
+ // operation is idempotent. Also, erasing these could result in loss
+ // of information such as constant values attached to such types.
+ return (t.tag <= lastBaseTag) || (syms.stringType.tsym == t.tsym);
+ }
+
private Type erasure(Type t, boolean recurse) {
if (t.tag <= lastBaseTag)
return t; /* fast special case */
@@ -3804,8 +3825,12 @@
// <editor-fold defaultstate="collapsed" desc="Annotation support">
public RetentionPolicy getRetention(Attribute.Compound a) {
+ return getRetention(a.type.tsym);
+ }
+
+ public RetentionPolicy getRetention(Symbol sym) {
RetentionPolicy vis = RetentionPolicy.CLASS; // the default
- Attribute.Compound c = a.type.tsym.attribute(syms.retentionType.tsym);
+ Attribute.Compound c = sym.attribute(syms.retentionType.tsym);
if (c != null) {
Attribute value = c.member(names.value);
if (value != null && value instanceof Attribute.Enum) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,11 @@
package com.sun.tools.javac.comp;
+import java.util.Map;
+import java.util.Objects;
+
import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.tree.*;
@@ -83,8 +87,9 @@
private int enterCount = 0;
ListBuffer<Annotator> q = new ListBuffer<Annotator>();
+ ListBuffer<Annotator> repeatedQ = new ListBuffer<Annotator>();
- public void later(Annotator a) {
+ public void normal(Annotator a) {
q.append(a);
}
@@ -92,6 +97,10 @@
q.prepend(a);
}
+ public void repeated(Annotator a) {
+ repeatedQ.append(a);
+ }
+
/** Called when the Enter phase starts. */
public void enterStart() {
enterCount++;
@@ -109,6 +118,10 @@
try {
while (q.nonEmpty())
q.next().enterAnnotation();
+
+ while (repeatedQ.nonEmpty()) {
+ repeatedQ.next().enterAnnotation();
+ }
} finally {
enterCount--;
}
@@ -124,6 +137,53 @@
String toString();
}
+ /**
+ * This context contains all the information needed to synthesize new
+ * annotations trees by the completer for repeating annotations.
+ */
+ public class AnnotateRepeatedContext {
+ public final Env<AttrContext> env;
+ public final Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated;
+ public final Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos;
+ public final Log log;
+
+ public AnnotateRepeatedContext(Env<AttrContext> env,
+ Map<Symbol.TypeSymbol, ListBuffer<Attribute.Compound>> annotated,
+ Map<Attribute.Compound, JCDiagnostic.DiagnosticPosition> pos,
+ Log log) {
+ Objects.requireNonNull(env);
+ Objects.requireNonNull(annotated);
+ Objects.requireNonNull(pos);
+ Objects.requireNonNull(log);
+
+ this.env = env;
+ this.annotated = annotated;
+ this.pos = pos;
+ this.log = log;
+ }
+
+ /**
+ * Process a list of repeating annotations returning a new
+ * Attribute.Compound that is the attribute for the synthesized tree
+ * for the container.
+ *
+ * @param repeatingAnnotations a List of repeating annotations
+ * @return a new Attribute.Compound that is the container for the repeatingAnnotations
+ */
+ public Attribute.Compound processRepeatedAnnotations(List<Attribute.Compound> repeatingAnnotations) {
+ return Annotate.this.processRepeatedAnnotations(repeatingAnnotations, this);
+ }
+
+ /**
+ * Queue the Annotator a on the repeating annotations queue of the
+ * Annotate instance this context belongs to.
+ *
+ * @param a the Annotator to enqueue for repeating annotation annotating
+ */
+ public void annotateRepeated(Annotator a) {
+ Annotate.this.repeated(a);
+ }
+ }
/* ********************************************************************
* Compute an attribute from its annotation.
@@ -268,4 +328,219 @@
log.error(tree.pos(), "annotation.value.not.allowable.type");
return new Attribute.Error(attr.attribExpr(tree, env, expected));
}
+
+ /* *********************************
+ * Support for repeating annotations
+ ***********************************/
+
+ /* Process repeated annotations. This method returns the
+ * synthesized container annotation or null IFF all repeating
+ * annotation are invalid. This method reports errors/warnings.
+ */
+ private Attribute.Compound processRepeatedAnnotations(List<Attribute.Compound> annotations,
+ AnnotateRepeatedContext ctx) {
+ Attribute.Compound firstOccurrence = annotations.head;
+ List<Attribute> repeated = List.nil();
+ Type origAnnoType;
+ Type arrayOfOrigAnnoType = null;
+ Type targetContainerType = null;
+ MethodSymbol containerValueSymbol = null;
+
+ Assert.check(!annotations.isEmpty() &&
+ !annotations.tail.isEmpty()); // i.e. size() > 1
+
+ for (List<Attribute.Compound> al = annotations;
+ !al.isEmpty();
+ al = al.tail)
+ {
+ Attribute.Compound currentAnno = al.head;
+
+ origAnnoType = currentAnno.type;
+ if (arrayOfOrigAnnoType == null) {
+ arrayOfOrigAnnoType = types.makeArrayType(origAnnoType);
}
+
+ Type currentContainerType = getContainingType(currentAnno, ctx.pos.get(currentAnno));
+ if (currentContainerType == null) {
+ continue;
+ }
+ // Assert that the target Container is == for all repeated
+ // annos of the same annotation type, the types should
+ // come from the same Symbol, i.e. be '=='
+ Assert.check(targetContainerType == null || currentContainerType == targetContainerType);
+ targetContainerType = currentContainerType;
+
+ containerValueSymbol = validateContainer(targetContainerType, origAnnoType, ctx.pos.get(currentAnno));
+
+ if (containerValueSymbol == null) { // Check of CA type failed
+ // errors are already reported
+ continue;
+ }
+
+ repeated = repeated.prepend(currentAnno);
+ }
+
+ if (!repeated.isEmpty()) {
+ repeated = repeated.reverse();
+ JCAnnotation annoTree;
+ TreeMaker m = make.at(ctx.pos.get(firstOccurrence));
+ Pair<MethodSymbol, Attribute> p =
+ new Pair<MethodSymbol, Attribute>(containerValueSymbol,
+ new Attribute.Array(arrayOfOrigAnnoType, repeated));
+ annoTree = m.Annotation(new Attribute.Compound(targetContainerType,
+ List.of(p)));
+ Attribute.Compound c = enterAnnotation(annoTree,
+ targetContainerType,
+ ctx.env);
+ return c;
+ } else {
+ return null; // errors should have been reported elsewhere
+ }
+ }
+
+ /** Fetches the actual Type that should be the containing annotation. */
+ private Type getContainingType(Attribute.Compound currentAnno,
+ DiagnosticPosition pos)
+ {
+ Type origAnnoType = currentAnno.type;
+ TypeSymbol origAnnoDecl = origAnnoType.tsym;
+
+ // Fetch the ContainedBy annotation from the current
+ // annotation's declaration, or null if it has none
+ Attribute.Compound ca = origAnnoDecl.attribute(syms.containedByType.tsym);
+ if (ca == null) { // has no ContainedBy annotation
+ log.error(pos, "duplicate.annotation.missing.container", origAnnoType);
+ return null;
+ }
+
+ return filterSame(extractContainingType(ca, pos, origAnnoDecl),
+ origAnnoType);
+ }
+
+ // returns null if t is same as 's', returns 't' otherwise
+ private Type filterSame(Type t, Type s) {
+ if (t == null || s == null) {
+ return t;
+ }
+
+ return types.isSameType(t, s) ? null : t;
+ }
+
+ /** Extract the actual Type to be used for a containing annotation. */
+ private Type extractContainingType(Attribute.Compound ca,
+ DiagnosticPosition pos,
+ TypeSymbol annoDecl)
+ {
+ // The next three checks check that the ContainedBy annotation
+ // on the declaration of the annotation type that is repeating is
+ // valid.
+
+ // ContainedBy must have at least one element
+ if (ca.values.isEmpty()) {
+ log.error(pos, "invalid.containedby.annotation", annoDecl);
+ return null;
+ }
+ Pair<MethodSymbol,Attribute> p = ca.values.head;
+ Name name = p.fst.name;
+ if (name != names.value) { // should contain only one element, named "value"
+ log.error(pos, "invalid.containedby.annotation", annoDecl);
+ return null;
+ }
+ if (!(p.snd instanceof Attribute.Class)) { // check that the value of "value" is an Attribute.Class
+ log.error(pos, "invalid.containedby.annotation", annoDecl);
+ return null;
+ }
+
+ return ((Attribute.Class)p.snd).getValue();
+ }
+
+ /* Validate that the suggested targetContainerType Type is a valid
+ * container type for repeated instances of originalAnnoType
+ * annotations. Return null and report errors if this is not the
+ * case, return the MethodSymbol of the value element in
+ * targetContainerType if it is suitable (this is needed to
+ * synthesize the container). */
+ private MethodSymbol validateContainer(Type targetContainerType,
+ Type originalAnnoType,
+ DiagnosticPosition pos) {
+ MethodSymbol containerValueSymbol = null;
+ boolean fatalError = false;
+
+ // Validate that there is a (and only 1) value method
+ Scope scope = targetContainerType.tsym.members();
+ int nr_value_elems = 0;
+ boolean error = false;
+ for(Symbol elm : scope.getElementsByName(names.value)) {
+ nr_value_elems++;
+
+ if (nr_value_elems == 1 &&
+ elm.kind == Kinds.MTH) {
+ containerValueSymbol = (MethodSymbol)elm;
+ } else {
+ error = true;
+ }
+ }
+ if (error) {
+ log.error(pos,
+ "invalid.containedby.annotation.multiple.values",
+ targetContainerType,
+ nr_value_elems);
+ return null;
+ } else if (nr_value_elems == 0) {
+ log.error(pos,
+ "invalid.containedby.annotation.no.value",
+ targetContainerType);
+ return null;
+ }
+
+ // validate that the 'value' element is a method
+ // probably "impossible" to fail this
+ if (containerValueSymbol.kind != Kinds.MTH) {
+ log.error(pos,
+ "invalid.containedby.annotation.invalid.value",
+ targetContainerType);
+ fatalError = true;
+ }
+
+ // validate that the 'value' element has the correct return type
+ // i.e. array of original anno
+ Type valueRetType = containerValueSymbol.type.getReturnType();
+ Type expectedType = types.makeArrayType(originalAnnoType);
+ if (!(types.isArray(valueRetType) &&
+ types.isSameType(expectedType, valueRetType))) {
+ log.error(pos,
+ "invalid.containedby.annotation.value.return",
+ targetContainerType,
+ valueRetType,
+ expectedType);
+ fatalError = true;
+ }
+
+ // validate that all other elements of containing type has defaults
+ scope = targetContainerType.tsym.members();
+ error = false;
+ for(Symbol elm : scope.getElements()) {
+ if (elm.name != names.value &&
+ elm.kind == Kinds.MTH &&
+ ((MethodSymbol)elm).defaultValue == null) {
+ log.error(pos,
+ "invalid.containedby.annotation.elem.nondefault",
+ targetContainerType,
+ elm);
+ containerValueSymbol = null;
+ error = true;
+ }
+ }
+ if (error) {
+ fatalError = true;
+ }
+
+ // Explicitly no check for/validity of @ContainerFor. That is
+ // done on declaration of the container, and at reflect time.
+
+ // The rest of the conditions for a valid containing annotation are made
+ // in Check.validateRepeatedAnnotaton();
+
+ return fatalError ? null : containerValueSymbol;
+ }
+}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Sep 14 10:14:02 2012 -0700
@@ -662,10 +662,12 @@
// env.info.enclVar.attributes_field might not yet have been evaluated, and so might be
// null. In that case, calling augment will throw an NPE. To avoid this, for now we
// revert to the jdk 6 behavior and ignore the (unevaluated) attributes.
- if (env.info.enclVar.attributes_field == null)
+ if (env.info.enclVar.annotations.pendingCompletion()) {
env.info.lint = lintEnv.info.lint;
- else
- env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.attributes_field, env.info.enclVar.flags());
+ } else {
+ env.info.lint = lintEnv.info.lint.augment(env.info.enclVar.annotations,
+ env.info.enclVar.flags());
+ }
Lint prevLint = chk.setLint(env.info.lint);
JavaFileObject prevSource = log.useSource(env.toplevel.sourcefile);
@@ -776,7 +778,7 @@
public void visitMethodDef(JCMethodDecl tree) {
MethodSymbol m = tree.sym;
- Lint lint = env.info.lint.augment(m.attributes_field, m.flags());
+ Lint lint = env.info.lint.augment(m.annotations, m.flags());
Lint prevLint = chk.setLint(lint);
MethodSymbol prevMethod = chk.setMethod(m);
try {
@@ -921,7 +923,7 @@
}
VarSymbol v = tree.sym;
- Lint lint = env.info.lint.augment(v.attributes_field, v.flags());
+ Lint lint = env.info.lint.augment(v.annotations, v.flags());
Lint prevLint = chk.setLint(lint);
// Check that the variable's declared type is well-formed.
@@ -3069,7 +3071,7 @@
lintEnv = lintEnv.next;
// Having found the enclosing lint value, we can initialize the lint value for this class
- env.info.lint = lintEnv.info.lint.augment(c.attributes_field, c.flags());
+ env.info.lint = lintEnv.info.lint.augment(c.annotations, c.flags());
Lint prevLint = chk.setLint(env.info.lint);
JavaFileObject prev = log.useSource(c.sourcefile);
@@ -3133,6 +3135,26 @@
if (tree.typarams.nonEmpty())
log.error(tree.typarams.head.pos(),
"intf.annotation.cant.have.type.params");
+
+ // If this annotation has a @ContainedBy, validate
+ Attribute.Compound containedBy = c.attribute(syms.containedByType.tsym);
+ if (containedBy != null) {
+ // get diagnositc position for error reporting
+ DiagnosticPosition cbPos = getDiagnosticPosition(tree, containedBy.type);
+ Assert.checkNonNull(cbPos);
+
+ chk.validateContainedBy(c, containedBy, cbPos);
+ }
+
+ // If this annotation has a @ContainerFor, validate
+ Attribute.Compound containerFor = c.attribute(syms.containerForType.tsym);
+ if (containerFor != null) {
+ // get diagnositc position for error reporting
+ DiagnosticPosition cfPos = getDiagnosticPosition(tree, containerFor.type);
+ Assert.checkNonNull(cfPos);
+
+ chk.validateContainerFor(c, containerFor, cfPos);
+ }
} else {
// Check that all extended classes and interfaces
// are compatible (i.e. no two define methods with same arguments
@@ -3194,6 +3216,16 @@
}
}
// where
+ /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
+ private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
+ for(List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
+ if (types.isSameType(al.head.annotationType.type, t))
+ return al.head.pos();
+ }
+
+ return null;
+ }
+
/** check if a class is a subtype of Serializable, if that is available. */
private boolean isSerializable(ClassSymbol c) {
try {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Sep 14 10:14:02 2012 -0700
@@ -69,7 +69,6 @@
private final Infer infer;
private final Types types;
private final JCDiagnostic.Factory diags;
- private final boolean skipAnnotations;
private boolean warnOnSyntheticConflicts;
private boolean suppressAbortOnBadClassFile;
private boolean enableSunApiLintControl;
@@ -113,7 +112,6 @@
allowCovariantReturns = source.allowCovariantReturns();
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
complexInference = options.isSet("complexinference");
- skipAnnotations = options.isSet("skipAnnotations");
warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
enableSunApiLintControl = options.isSet("enableSunApiLintControl");
@@ -2422,14 +2420,13 @@
/** Check the annotations of a symbol.
*/
public void validateAnnotations(List<JCAnnotation> annotations, Symbol s) {
- if (skipAnnotations) return;
for (JCAnnotation a : annotations)
validateAnnotation(a, s);
}
/** Check an annotation of a symbol.
*/
- public void validateAnnotation(JCAnnotation a, Symbol s) {
+ private void validateAnnotation(JCAnnotation a, Symbol s) {
validateAnnotationTree(a);
if (!annotationApplicable(a, s))
@@ -2441,6 +2438,215 @@
}
}
+ /**
+ * Validate the proposed container 'containedBy' on the
+ * annotation type symbol 's'. Report errors at position
+ * 'pos'.
+ *
+ * @param s The (annotation)type declaration annotated with a @ContainedBy
+ * @param containerAnno the @ContainedBy on 's'
+ * @param pos where to report errors
+ */
+ public void validateContainedBy(TypeSymbol s, Attribute.Compound containedBy, DiagnosticPosition pos) {
+ Assert.check(types.isSameType(containedBy.type, syms.containedByType));
+
+ Type t = null;
+ List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
+ if (!l.isEmpty()) {
+ Assert.check(l.head.fst.name == names.value);
+ t = ((Attribute.Class)l.head.snd).getValue();
+ }
+
+ if (t == null) {
+ log.error(pos, "invalid.container.wrong.containedby", s, containedBy);
+ return;
+ }
+
+ validateHasContainerFor(t.tsym, s, pos);
+ validateRetention(t.tsym, s, pos);
+ validateDocumented(t.tsym, s, pos);
+ validateInherited(t.tsym, s, pos);
+ validateTarget(t.tsym, s, pos);
+ }
+
+ /**
+ * Validate the proposed container 'containerFor' on the
+ * annotation type symbol 's'. Report errors at position
+ * 'pos'.
+ *
+ * @param s The (annotation)type declaration annotated with a @ContainerFor
+ * @param containerFor the @ContainedFor on 's'
+ * @param pos where to report errors
+ */
+ public void validateContainerFor(TypeSymbol s, Attribute.Compound containerFor, DiagnosticPosition pos) {
+ Assert.check(types.isSameType(containerFor.type, syms.containerForType));
+
+ Type t = null;
+ List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
+ if (!l.isEmpty()) {
+ Assert.check(l.head.fst.name == names.value);
+ t = ((Attribute.Class)l.head.snd).getValue();
+ }
+
+ if (t == null) {
+ log.error(pos, "invalid.container.wrong.containerfor", s, containerFor);
+ return;
+ }
+
+ validateHasContainedBy(t.tsym, s, pos);
+ }
+
+ private void validateHasContainedBy(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
+ Attribute.Compound containedBy = container.attribute(syms.containedByType.tsym);
+
+ if (containedBy == null) {
+ log.error(pos, "invalid.container.no.containedby", container, syms.containedByType.tsym);
+ return;
+ }
+
+ Type t = null;
+ List<Pair<MethodSymbol,Attribute>> l = containedBy.values;
+ if (!l.isEmpty()) {
+ Assert.check(l.head.fst.name == names.value);
+ t = ((Attribute.Class)l.head.snd).getValue();
+ }
+
+ if (t == null) {
+ log.error(pos, "invalid.container.wrong.containedby", container, contained);
+ return;
+ }
+
+ if (!types.isSameType(t, contained.type))
+ log.error(pos, "invalid.container.wrong.containedby", t.tsym, contained);
+ }
+
+ private void validateHasContainerFor(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
+ Attribute.Compound containerFor = container.attribute(syms.containerForType.tsym);
+
+ if (containerFor == null) {
+ log.error(pos, "invalid.container.no.containerfor", container, syms.containerForType.tsym);
+ return;
+ }
+
+ Type t = null;
+ List<Pair<MethodSymbol,Attribute>> l = containerFor.values;
+ if (!l.isEmpty()) {
+ Assert.check(l.head.fst.name == names.value);
+ t = ((Attribute.Class)l.head.snd).getValue();
+ }
+
+ if (t == null) {
+ log.error(pos, "invalid.container.wrong.containerfor", container, contained);
+ return;
+ }
+
+ if (!types.isSameType(t, contained.type))
+ log.error(pos, "invalid.container.wrong.containerfor", t.tsym, contained);
+ }
+
+ private void validateRetention(Symbol container, Symbol contained, DiagnosticPosition pos) {
+ Attribute.RetentionPolicy containerRetention = types.getRetention(container);
+ Attribute.RetentionPolicy containedRetention = types.getRetention(contained);
+
+ boolean error = false;
+ switch (containedRetention) {
+ case RUNTIME:
+ if (containerRetention != Attribute.RetentionPolicy.RUNTIME) {
+ error = true;
+ }
+ break;
+ case CLASS:
+ if (containerRetention == Attribute.RetentionPolicy.SOURCE) {
+ error = true;
+ }
+ }
+ if (error ) {
+ log.error(pos, "invalid.containedby.annotation.retention",
+ container, containerRetention,
+ contained, containedRetention);
+ }
+ }
+
+ private void validateDocumented(Symbol container, Symbol contained, DiagnosticPosition pos) {
+ if (contained.attribute(syms.documentedType.tsym) != null) {
+ if (container.attribute(syms.documentedType.tsym) == null) {
+ log.error(pos, "invalid.containedby.annotation.not.documented", container, contained);
+ }
+ }
+ }
+
+ private void validateInherited(Symbol container, Symbol contained, DiagnosticPosition pos) {
+ if (contained.attribute(syms.inheritedType.tsym) != null) {
+ if (container.attribute(syms.inheritedType.tsym) == null) {
+ log.error(pos, "invalid.containedby.annotation.not.inherited", container, contained);
+ }
+ }
+ }
+
+ private void validateTarget(Symbol container, Symbol contained, DiagnosticPosition pos) {
+ Attribute.Array containedTarget = getAttributeTargetAttribute(contained);
+
+ // If contained has no Target, we are done
+ if (containedTarget == null) {
+ return;
+ }
+
+ // If contained has Target m1, container must have a Target
+ // annotation, m2, and m2 must be a subset of m1. (This is
+ // trivially true if contained has no target as per above).
+
+ // contained has target, but container has not, error
+ Attribute.Array containerTarget = getAttributeTargetAttribute(container);
+ if (containerTarget == null) {
+ log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+ return;
+ }
+
+ Set<Name> containerTargets = new HashSet<Name>();
+ for (Attribute app : containerTarget.values) {
+ if (!(app instanceof Attribute.Enum)) {
+ continue; // recovery
+ }
+ Attribute.Enum e = (Attribute.Enum)app;
+ containerTargets.add(e.value.name);
+ }
+
+ Set<Name> containedTargets = new HashSet<Name>();
+ for (Attribute app : containedTarget.values) {
+ if (!(app instanceof Attribute.Enum)) {
+ continue; // recovery
+ }
+ Attribute.Enum e = (Attribute.Enum)app;
+ containedTargets.add(e.value.name);
+ }
+
+ if (!isTargetSubset(containedTargets, containerTargets)) {
+ log.error(pos, "invalid.containedby.annotation.incompatible.target", container, contained);
+ }
+ }
+
+ /** Checks that t is a subset of s, with respect to ElementType
+ * semantics, specifically {ANNOTATION_TYPE} is a subset of {TYPE}
+ */
+ private boolean isTargetSubset(Set<Name> s, Set<Name> t) {
+ // Check that all elements in t are present in s
+ for (Name n2 : t) {
+ boolean currentElementOk = false;
+ for (Name n1 : s) {
+ if (n1 == n2) {
+ currentElementOk = true;
+ break;
+ } else if (n1 == names.TYPE && n2 == names.ANNOTATION_TYPE) {
+ currentElementOk = true;
+ break;
+ }
+ }
+ if (!currentElementOk)
+ return false;
+ }
+ return true;
+ }
+
/** Is s a method symbol that overrides a method in a superclass? */
boolean isOverrider(Symbol s) {
if (s.kind != MTH || s.isStatic())
@@ -2461,12 +2667,10 @@
/** Is the annotation applicable to the symbol? */
boolean annotationApplicable(JCAnnotation a, Symbol s) {
- Attribute.Compound atTarget =
- a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
- if (atTarget == null) return true;
- Attribute atValue = atTarget.member(names.value);
- if (!(atValue instanceof Attribute.Array)) return true; // error recovery
- Attribute.Array arr = (Attribute.Array) atValue;
+ Attribute.Array arr = getAttributeTargetAttribute(a.annotationType.type.tsym);
+ if (arr == null) {
+ return true;
+ }
for (Attribute app : arr.values) {
if (!(app instanceof Attribute.Enum)) return true; // recovery
Attribute.Enum e = (Attribute.Enum) app;
@@ -2508,6 +2712,16 @@
return false;
}
+
+ Attribute.Array getAttributeTargetAttribute(Symbol s) {
+ Attribute.Compound atTarget =
+ s.attribute(syms.annotationTargetType.tsym);
+ if (atTarget == null) return null; // ok, is applicable
+ Attribute atValue = atTarget.member(names.value);
+ if (!(atValue instanceof Attribute.Array)) return null; // error recovery
+ return (Attribute.Array) atValue;
+ }
+
/** Check an annotation value.
*/
public void validateAnnotation(JCAnnotation a) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Fri Sep 14 10:14:02 2012 -0700
@@ -157,7 +157,7 @@
Env<AttrContext> lintEnv = localEnv;
while (lintEnv.info.lint == null)
lintEnv = lintEnv.next;
- localEnv.info.lint = lintEnv.info.lint.augment(sym.attributes_field, sym.flags());
+ localEnv.info.lint = lintEnv.info.lint.augment(sym.annotations, sym.flags());
return localEnv;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Sep 14 10:14:02 2012 -0700
@@ -406,7 +406,7 @@
Lint lintPrev = lint;
pendingExits = new ListBuffer<PendingExit>();
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try {
// process all the static initializers
@@ -442,7 +442,7 @@
if (tree.body == null) return;
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
Assert.check(pendingExits.isEmpty());
@@ -468,7 +468,7 @@
public void visitVarDef(JCVariableDecl tree) {
if (tree.init != null) {
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try{
scan(tree.init);
} finally {
@@ -783,7 +783,7 @@
}
classDef = tree;
thrown = List.nil();
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try {
// process all the static initializers
@@ -863,7 +863,7 @@
List<Type> mthrown = tree.sym.type.getThrownTypes();
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
Assert.check(pendingExits.isEmpty());
@@ -902,7 +902,7 @@
public void visitVarDef(JCVariableDecl tree) {
if (tree.init != null) {
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try{
scan(tree.init);
} finally {
@@ -1491,7 +1491,7 @@
firstadr = nextadr;
}
classDef = tree;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try {
// define all the static fields
@@ -1558,7 +1558,7 @@
int firstadrPrev = firstadr;
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
Assert.check(pendingExits.isEmpty());
@@ -1609,7 +1609,7 @@
if (track && tree.sym.owner.kind == MTH) newVar(tree.sym);
if (tree.init != null) {
Lint lintPrev = lint;
- lint = lint.augment(tree.sym.attributes_field);
+ lint = lint.augment(tree.sym.annotations);
try{
scanExpr(tree.init);
if (track) letInit(tree.pos(), tree.sym);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Sep 14 10:14:02 2012 -0700
@@ -2257,7 +2257,7 @@
null, List.<JCExpression>nil(), List.<JCTree>nil());
ClassSymbol c = tree.packge.package_info;
c.flags_field |= flags;
- c.attributes_field = tree.packge.attributes_field;
+ c.annotations.setAttributes(tree.packge.annotations);
ClassType ctype = (ClassType) c.type;
ctype.supertype_field = syms.objectType;
ctype.interfaces_field = List.nil();
@@ -2274,7 +2274,8 @@
case LEGACY:
return tree.packageAnnotations.nonEmpty();
case NONEMPTY:
- for (Attribute.Compound a: tree.packge.attributes_field) {
+ for (Attribute.Compound a :
+ tree.packge.annotations.getAttributes()) {
Attribute.RetentionPolicy p = types.getRetention(a);
if (p != Attribute.RetentionPolicy.SOURCE)
return true;
@@ -3499,7 +3500,6 @@
JCExpression expression = oneCase.getExpression();
if (expression != null) { // expression for a "default" case is null
- expression = TreeInfo.skipParens(expression);
String labelExpr = (String) expression.type.constValue();
Integer mapping = caseLabelToPosition.put(labelExpr, casePosition);
Assert.checkNull(mapping);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Sep 14 10:14:02 2012 -0700
@@ -76,11 +76,10 @@
private final Annotate annotate;
private final Types types;
private final JCDiagnostic.Factory diags;
+ private final Source source;
private final Target target;
private final DeferredLintHandler deferredLintHandler;
- private final boolean skipAnnotations;
-
public static MemberEnter instance(Context context) {
MemberEnter instance = context.get(memberEnterKey);
if (instance == null)
@@ -102,10 +101,9 @@
annotate = Annotate.instance(context);
types = Types.instance(context);
diags = JCDiagnostic.Factory.instance(context);
+ source = Source.instance(context);
target = Target.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
- Options options = Options.instance(context);
- skipAnnotations = options.isSet("skipAnnotations");
}
/** A queue for classes whose members still need to be entered into the
@@ -690,7 +688,7 @@
public Env<AttrContext> getMethodEnv(JCMethodDecl tree, Env<AttrContext> env) {
Env<AttrContext> mEnv = methodEnv(tree, env);
- mEnv.info.lint = mEnv.info.lint.augment(tree.sym.attributes_field, tree.sym.flags());
+ mEnv.info.lint = mEnv.info.lint.augment(tree.sym.annotations, tree.sym.flags());
for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
mEnv.info.scope.enterIfAbsent(l.head.type.tsym);
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail)
@@ -727,18 +725,24 @@
void annotateLater(final List<JCAnnotation> annotations,
final Env<AttrContext> localEnv,
final Symbol s) {
- if (annotations.isEmpty()) return;
- if (s.kind != PCK) s.attributes_field = null; // mark it incomplete for now
- annotate.later(new Annotate.Annotator() {
+ if (annotations.isEmpty()) {
+ return;
+ }
+ if (s.kind != PCK) {
+ s.annotations.reset(); // mark Annotations as incomplete for now
+ }
+ annotate.normal(new Annotate.Annotator() {
+ @Override
public String toString() {
return "annotate " + annotations + " onto " + s + " in " + s.owner;
}
+
+ @Override
public void enterAnnotation() {
- Assert.check(s.kind == PCK || s.attributes_field == null);
+ Assert.check(s.kind == PCK || s.annotations.pendingCompletion());
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
try {
- if (s.attributes_field != null &&
- s.attributes_field.nonEmpty() &&
+ if (!s.annotations.isEmpty() &&
annotations.nonEmpty())
log.error(annotations.head.pos,
"already.annotated",
@@ -756,7 +760,7 @@
* java.lang.Deprecated.
**/
private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
- for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
+ for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
return true;
@@ -764,42 +768,62 @@
return false;
}
-
/** Enter a set of annotations. */
private void enterAnnotations(List<JCAnnotation> annotations,
Env<AttrContext> env,
Symbol s) {
- ListBuffer<Attribute.Compound> buf =
- new ListBuffer<Attribute.Compound>();
- Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
- if (!skipAnnotations)
- for (List<JCAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
+ Map<TypeSymbol, ListBuffer<Attribute.Compound>> annotated =
+ new LinkedHashMap<TypeSymbol, ListBuffer<Attribute.Compound>>();
+ Map<Attribute.Compound, DiagnosticPosition> pos =
+ new HashMap<Attribute.Compound, DiagnosticPosition>();
+
+ for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
Attribute.Compound c = annotate.enterAnnotation(a,
syms.annotationType,
env);
- if (c == null) continue;
- buf.append(c);
+ if (c == null) {
+ continue;
+ }
+
+ if (annotated.containsKey(a.type.tsym)) {
+ if (source.allowRepeatedAnnotations()) {
+ ListBuffer<Attribute.Compound> l = annotated.get(a.type.tsym);
+ l = l.append(c);
+ annotated.put(a.type.tsym, l);
+ pos.put(c, a.pos());
+ } else {
+ log.error(a.pos(), "duplicate.annotation");
+ }
+ } else {
+ annotated.put(a.type.tsym, ListBuffer.of(c));
+ pos.put(c, a.pos());
+ }
+
// Note: @Deprecated has no effect on local variables and parameters
if (!c.type.isErroneous()
&& s.owner.kind != MTH
- && types.isSameType(c.type, syms.deprecatedType))
+ && types.isSameType(c.type, syms.deprecatedType)) {
s.flags_field |= Flags.DEPRECATED;
- if (!annotated.add(a.type.tsym))
- log.error(a.pos, "duplicate.annotation");
+ }
}
- s.attributes_field = buf.toList();
+
+ s.annotations.setAttributesWithCompletion(
+ annotate.new AnnotateRepeatedContext(env, annotated, pos, log));
}
/** Queue processing of an attribute default value. */
void annotateDefaultValueLater(final JCExpression defaultValue,
final Env<AttrContext> localEnv,
final MethodSymbol m) {
- annotate.later(new Annotate.Annotator() {
+ annotate.normal(new Annotate.Annotator() {
+ @Override
public String toString() {
return "annotate " + m.owner + "." +
m + " default " + defaultValue;
}
+
+ @Override
public void enterAnnotation() {
JavaFileObject prev = log.useSource(localEnv.toplevel.sourcefile);
try {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Sep 14 10:14:02 2012 -0700
@@ -188,7 +188,7 @@
/** The current input pointer.
*/
- int bp;
+ protected int bp;
/** The objects of the constant pool.
*/
@@ -890,13 +890,13 @@
protected enum AttributeKind { CLASS, MEMBER };
protected abstract class AttributeReader {
- AttributeReader(Name name, ClassFile.Version version, Set<AttributeKind> kinds) {
+ protected AttributeReader(Name name, ClassFile.Version version, Set<AttributeKind> kinds) {
this.name = name;
this.version = version;
this.kinds = kinds;
}
- boolean accepts(AttributeKind kind) {
+ protected boolean accepts(AttributeKind kind) {
if (kinds.contains(kind)) {
if (majorVersion > version.major || (majorVersion == version.major && minorVersion >= version.minor))
return true;
@@ -915,11 +915,11 @@
return false;
}
- abstract void read(Symbol sym, int attrLen);
+ protected abstract void read(Symbol sym, int attrLen);
- final Name name;
- final ClassFile.Version version;
- final Set<AttributeKind> kinds;
+ protected final Name name;
+ protected final ClassFile.Version version;
+ protected final Set<AttributeKind> kinds;
}
protected Set<AttributeKind> CLASS_ATTRIBUTE =
@@ -936,7 +936,7 @@
// v45.3 attributes
new AttributeReader(names.Code, V45_3, MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
if (readAllOfClassFile || saveParameterNames)
((MethodSymbol)sym).code = readCode(sym);
else
@@ -945,7 +945,7 @@
},
new AttributeReader(names.ConstantValue, V45_3, MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
Object v = readPool(nextChar());
// Ignore ConstantValue attribute if field not final.
if ((sym.flags() & FINAL) != 0)
@@ -954,13 +954,13 @@
},
new AttributeReader(names.Deprecated, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
sym.flags_field |= DEPRECATED;
}
},
new AttributeReader(names.Exceptions, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
int nexceptions = nextChar();
List<Type> thrown = List.nil();
for (int j = 0; j < nexceptions; j++)
@@ -971,14 +971,14 @@
},
new AttributeReader(names.InnerClasses, V45_3, CLASS_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
ClassSymbol c = (ClassSymbol) sym;
readInnerClasses(c);
}
},
new AttributeReader(names.LocalVariableTable, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
int newbp = bp + attrLen;
if (saveParameterNames) {
// Pick up parameter names from the variable table.
@@ -1014,7 +1014,7 @@
},
new AttributeReader(names.SourceFile, V45_3, CLASS_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
ClassSymbol c = (ClassSymbol) sym;
Name n = readName(nextChar());
c.sourcefile = new SourceFileObject(n, c.flatname);
@@ -1022,7 +1022,7 @@
},
new AttributeReader(names.Synthetic, V45_3, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
// bridge methods are visible when generics not enabled
if (allowGenerics || (sym.flags_field & BRIDGE) == 0)
sym.flags_field |= SYNTHETIC;
@@ -1032,7 +1032,7 @@
// standard v49 attributes
new AttributeReader(names.EnclosingMethod, V49, CLASS_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
int newbp = bp + attrLen;
readEnclosingMethodAttr(sym);
bp = newbp;
@@ -1041,11 +1041,11 @@
new AttributeReader(names.Signature, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
@Override
- boolean accepts(AttributeKind kind) {
+ protected boolean accepts(AttributeKind kind) {
return super.accepts(kind) && allowGenerics;
}
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
if (sym.kind == TYP) {
ClassSymbol c = (ClassSymbol) sym;
readingClassAttr = true;
@@ -1074,31 +1074,31 @@
// v49 annotation attributes
new AttributeReader(names.AnnotationDefault, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
attachAnnotationDefault(sym);
}
},
new AttributeReader(names.RuntimeInvisibleAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
attachAnnotations(sym);
}
},
new AttributeReader(names.RuntimeInvisibleParameterAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
attachParameterAnnotations(sym);
}
},
new AttributeReader(names.RuntimeVisibleAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
attachAnnotations(sym);
}
},
new AttributeReader(names.RuntimeVisibleParameterAnnotations, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
attachParameterAnnotations(sym);
}
},
@@ -1106,14 +1106,14 @@
// additional "legacy" v49 attributes, superceded by flags
new AttributeReader(names.Annotation, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
if (allowAnnotations)
sym.flags_field |= ANNOTATION;
}
},
new AttributeReader(names.Bridge, V49, MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
sym.flags_field |= BRIDGE;
if (!allowGenerics)
sym.flags_field &= ~SYNTHETIC;
@@ -1121,13 +1121,13 @@
},
new AttributeReader(names.Enum, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
sym.flags_field |= ENUM;
}
},
new AttributeReader(names.Varargs, V49, CLASS_OR_MEMBER_ATTRIBUTE) {
- void read(Symbol sym, int attrLen) {
+ protected void read(Symbol sym, int attrLen) {
if (allowVarargs)
sym.flags_field |= VARARGS;
}
@@ -1153,7 +1153,7 @@
- void readEnclosingMethodAttr(Symbol sym) {
+ protected void readEnclosingMethodAttr(Symbol sym) {
// sym is a nested class with an "Enclosing Method" attribute
// remove sym from it's current owners scope and place it in
// the scope specified by the attribute
@@ -1321,7 +1321,7 @@
else
proxies.append(proxy);
}
- annotate.later(new AnnotationCompleter(sym, proxies.toList()));
+ annotate.normal(new AnnotationCompleter(sym, proxies.toList()));
}
}
@@ -1347,7 +1347,7 @@
void attachAnnotationDefault(final Symbol sym) {
final MethodSymbol meth = (MethodSymbol)sym; // only on methods
final Attribute value = readAttributeValue();
- annotate.later(new AnnotationDefaultCompleter(meth, value));
+ annotate.normal(new AnnotationDefaultCompleter(meth, value));
}
Type readTypeOrClassSymbol(int i) {
@@ -1693,10 +1693,13 @@
JavaFileObject previousClassFile = currentClassFile;
try {
currentClassFile = classFile;
+ Annotations annotations = sym.annotations;
List<Attribute.Compound> newList = deproxyCompoundList(l);
- sym.attributes_field = ((sym.attributes_field == null)
- ? newList
- : newList.prependList(sym.attributes_field));
+ if (annotations.pendingCompletion()) {
+ annotations.setAttributes(newList);
+ } else {
+ annotations.append(newList);
+ }
} finally {
currentClassFile = previousClassFile;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Sep 14 10:14:02 2012 -0700
@@ -164,7 +164,7 @@
/** Construct a class writer, given an options table.
*/
- private ClassWriter(Context context) {
+ protected ClassWriter(Context context) {
context.put(classWriterKey, this);
log = Log.instance(context);
@@ -601,12 +601,20 @@
* Returns the number of attributes written (0 or 1).
*/
int writeEnclosingMethodAttribute(ClassSymbol c) {
- if (!target.hasEnclosingMethodAttribute() ||
- c.owner.kind != MTH && // neither a local class
+ if (!target.hasEnclosingMethodAttribute())
+ return 0;
+ return writeEnclosingMethodAttribute(names.EnclosingMethod, c);
+ }
+
+ /** Write the EnclosingMethod attribute with a specified name.
+ * Returns the number of attributes written (0 or 1).
+ */
+ protected int writeEnclosingMethodAttribute(Name attributeName, ClassSymbol c) {
+ if (c.owner.kind != MTH && // neither a local class
c.name != names.empty) // nor anonymous
return 0;
- int alenIdx = writeAttr(names.EnclosingMethod);
+ int alenIdx = writeAttr(attributeName);
ClassSymbol enclClass = c.owner.enclClass();
MethodSymbol enclMethod =
(c.owner.type == null // local to init block
@@ -817,7 +825,7 @@
}
public void visitClass(Attribute.Class clazz) {
databuf.appendByte('c');
- databuf.appendChar(pool.put(typeSig(clazz.type)));
+ databuf.appendChar(pool.put(typeSig(clazz.classType)));
}
public void visitCompound(Attribute.Compound compound) {
databuf.appendByte('@');
@@ -1569,6 +1577,7 @@
acount += writeFlagAttrs(c.flags());
acount += writeJavaAnnotations(c.getAnnotationMirrors());
acount += writeEnclosingMethodAttribute(c);
+ acount += writeExtraClassAttributes(c);
poolbuf.appendInt(JAVA_MAGIC);
poolbuf.appendChar(target.minorVersion);
@@ -1588,6 +1597,14 @@
pool = c.pool = null; // to conserve space
}
+ /**Allows subclasses to write additional class attributes
+ *
+ * @return the number of attributes written
+ */
+ protected int writeExtraClassAttributes(ClassSymbol c) {
+ return 0;
+ }
+
int adjustFlags(final long flags) {
int result = (int)flags;
if ((flags & SYNTHETIC) != 0 && !target.useSyntheticFlag())
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Fri Sep 14 10:14:02 2012 -0700
@@ -157,7 +157,7 @@
if (c.isLocal() || (c.flags() & Flags.SYNTHETIC) != 0)
return false;
- for (Attribute.Compound a: c.attributes_field) {
+ for (Attribute.Compound a: c.annotations.getAttributes()) {
if (a.type.tsym == syms.nativeHeaderType.tsym)
return true;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -177,7 +177,7 @@
}
public void visitClass(Attribute.Class c) {
- value = new MirroredTypeExceptionProxy(c.type);
+ value = new MirroredTypeExceptionProxy(c.classType);
}
public void visitArray(Attribute.Array a) {
@@ -187,7 +187,7 @@
// Construct a proxy for a MirroredTypesException
ListBuffer<TypeMirror> elems = new ListBuffer<TypeMirror>();
for (Attribute value : a.values) {
- Type elem = ((Attribute.Class) value).type;
+ Type elem = ((Attribute.Class) value).classType;
elems.append(elem);
}
value = new MirroredTypesExceptionProxy(elems.toList());
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Sep 14 10:14:02 2012 -0700
@@ -250,6 +250,70 @@
compiler.err.duplicate.annotation.member.value=\
duplicate annotation member value {0} in {1}
+# 0: type
+compiler.err.duplicate.annotation.missing.container=\
+ duplicate annotation, the declaration of {0} does not have a ContainedBy annotation
+
+# 0: type, 1: type
+compiler.err.invalid.container.no.containedby=\
+ invalid contained repeatable annotation, {0} is not annotated with {1}
+
+# 0: type, 1: type
+compiler.err.invalid.container.wrong.containedby=\
+ invalid contained repeatable annotation, {0} does not match {1}
+
+# 0: type, 1: type
+compiler.err.invalid.container.no.containerfor=\
+ invalid container for repeating annotations, {0} is not annotated with {1}
+
+# 0: type, 1: type
+compiler.err.invalid.container.wrong.containerfor=\
+ invalid container for repeating annotations, {0} does not match {1}
+
+# 0: type
+compiler.err.invalid.containedby.annotation=\
+ duplicate annotation, {0} is annotated with an invalid ContainedBy annotation
+
+# 0: type
+compiler.err.invalid.containedby.annotation.no.value=\
+ duplicate annotation, {0} is not a valid ContainedBy, no value element method declared
+
+# 0: type, 1: number
+compiler.err.invalid.containedby.annotation.multiple.values=\
+ duplicate annotation, {0} is not a valid ContainedBy, {1} value element methods declared
+
+# 0: type
+compiler.err.invalid.containedby.annotation.invalid.value=\
+ duplicate annotation, {0} is not a valid ContainedBy, invalid value element, need a method
+
+# 0: type, 1: type, 2: type
+compiler.err.invalid.containedby.annotation.value.return=\
+ duplicate annotation, value element of containing annotation {0} should have type {2}, found {1}
+
+# 0: type, 1: symbol
+compiler.err.invalid.containedby.annotation.elem.nondefault=\
+ duplicate annotation, element {1} in containing annotation {0} does not have a default value
+
+# 0: symbol, 1: type, 2: symbol, 3: type
+compiler.err.invalid.containedby.annotation.retention=\
+ containing annotation {0} has shorter retention ({1}) than the contained annotation {2} with retention {3}
+
+# 0: symbol, 1: symbol
+compiler.err.invalid.containedby.annotation.not.documented=\
+ containing annotation type, {0}, is not @Documented while repeated annotation type, {1}, is
+
+# 0: symbol, 1: symbol
+compiler.err.invalid.containedby.annotation.not.inherited=\
+ containing annotation type, {0}, is not @Inherited while repeated annotation type, {1}, is
+
+# 0: symbol, 1: symbol
+compiler.err.invalid.containedby.annotation.incompatible.target=\
+ target of container annotation {0} is not a subset of target of repeated annotation {1}
+
+# 0: symbol
+compiler.err.invalid.containedby.annotation.repeated.and.container.present=\
+ container {0} must not be present at the same time as the element it contains
+
# 0: name
compiler.err.duplicate.class=\
duplicate class: {0}
--- a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -206,9 +206,7 @@
}
ClassSymbol cs = (ClassSymbol) sym;
if (addLegacyAnnotation) {
- cs.attributes_field = (cs.attributes_field == null)
- ? List.of(proprietary)
- : cs.attributes_field.prepend(proprietary);
+ cs.annotations.prepend(List.of(proprietary));
}
writeClass(pool, cs, writer);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -740,7 +740,7 @@
result = Literal(v.value);
}
public void visitClass(Attribute.Class clazz) {
- result = ClassLiteral(clazz.type).setType(syms.classType);
+ result = ClassLiteral(clazz.classType).setType(syms.classType);
}
public void visitEnum(Attribute.Enum e) {
result = QualIdent(e.value);
--- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -83,7 +83,7 @@
public void visitClass(Attribute.Class c) {
value = TypeMaker.getType(env,
- env.types.erasure(c.type));
+ env.types.erasure(c.classType));
}
public void visitEnum(Attribute.Enum e) {
--- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -506,7 +506,7 @@
List<String> opts = new ArrayList<String>();
opts.add("-proc:only");
opts.addAll(javac_extras);
- CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, internalize(classes), null);
+ CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, classes, null);
JavahProcessor p = new JavahProcessor(g);
t.setProcessors(Collections.singleton(p));
@@ -516,14 +516,6 @@
return ok;
}
- private List<String> internalize(List<String> classes) {
- List<String> l = new ArrayList<String>();
- for (String c: classes) {
- l.add(c.replace('$', '.'));
- }
- return l;
- }
-
private List<File> pathToFiles(String path) {
List<File> files = new ArrayList<File>();
for (String f: path.split(File.pathSeparator)) {
--- a/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/ProtectedInnerClass/ProtectedInnerClass.sh Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/BinOpInCaseLabel.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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 7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile BinOpInCaseLabel.java
+ */
+
+public class BinOpInCaseLabel {
+ public static void main(String [] args) {
+ switch (args[0]) {
+ case "hello" + "world":
+ break;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/CastInCaseLabel.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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 7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile CastInCaseLabel.java
+ */
+
+public class CastInCaseLabel {
+ public static void main(String [] args) {
+ switch (args[0]) {
+ case (String)"hello":
+ break;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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 7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile CondExprInCaseLabel.java
+ */
+
+public class CondExprInCaseLabel {
+ public static void main(String [] args) {
+ final boolean cond = true;
+ switch (args[0]) {
+ case cond ? "hello" : "world":
+ break;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel1.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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 7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile CondExprInCaseLabel1.java
+ */
+
+public class CondExprInCaseLabel1 {
+ public static void main(String [] args) {
+ final boolean cond = true;
+ switch (args[0]) {
+ case cond ? (String)"hello" : "world":
+ break;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel2.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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 7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile CondExprInCaseLabel2.java
+ */
+
+public class CondExprInCaseLabel2 {
+ public static void main(String [] args) {
+ final boolean cond = true;
+ switch (args[0]) {
+ case cond ? "hello" : (String)"world":
+ break;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/BasicRepeatingAnnotations.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean BasicRepeatingAnnotations BasicRepeatingAnnos BasicNonRepeatingAnno Foo Foos Bar
+ * @run compile BasicRepeatingAnnotations.java
+ * @run main BasicRepeatingAnnotations
+ */
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface Foos {
+ Foo[] value();
+}
+
+@interface Bar {}
+
+@Foo @Foo
+@Foo
+@Bar
+@Foo
+@Foo
+@Foo
+@Foo
+@Foo @Foo
+@Foo
+class BasicRepeatingAnnos {}
+
+@Foo
+class BasicNonRepeatingAnno {}
+
+public class BasicRepeatingAnnotations {
+ public static void main(String[] args) throws Exception {
+ Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class);
+ if (a == null) {
+ throw new RuntimeException("Container annotation missing");
+ }
+
+ // verify that container not present on nonrepeating
+ a = BasicNonRepeatingAnno.class.getAnnotation(Foos.class);
+ if (a != null) {
+ throw new RuntimeException("Container annotation present");
+ }
+ a = BasicNonRepeatingAnno.class.getAnnotation(Foo.class);
+ if (a == null) {
+ throw new RuntimeException("Repeated annoation not directly present");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/CheckTargets.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,67 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean Foos Foo Bars Bar Baz Bazs CheckTargets
+ * @run compile CheckTargets.java
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@Target(ElementType.TYPE)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@Target(ElementType.ANNOTATION_TYPE)
+@interface Foos {
+ Foo[] value();
+}
+
+@ContainedBy(Bars.class)
+@Target(ElementType.TYPE)
+@interface Bar {}
+
+@ContainerFor(Bar.class)
+@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
+@interface Bars {
+ Bar[] value();
+}
+
+
+@ContainedBy(Bazs.class)
+@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
+@interface Baz {}
+
+@ContainerFor(Baz.class)
+@Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE })
+@interface Bazs {
+ Baz[] value();
+}
+
+
+public class CheckTargets {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/ContainerHasRepeatedContained.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,46 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean Bar BarContainer ContainerHasRepeatedContained
+ * @run compile ContainerHasRepeatedContained.java
+ */
+
+import java.lang.annotation.ContainedBy;
+import java.lang.annotation.ContainerFor;
+
+@ContainedBy(BarContainer.class)
+@interface Bar {}
+
+@Bar
+@Bar
+@ContainerFor(Bar.class)
+@interface BarContainer {
+ Bar[] value();
+}
+
+public class ContainerHasRepeatedContained {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/DelayRepeatedContainer.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,50 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean DelayRepeatedContainer Bar BarContainer
+ * @run compile DelayRepeatedContainer.java
+ */
+
+import java.lang.annotation.*;
+
+public class DelayRepeatedContainer {
+ @Bar("apa") @Bar("banan")
+ String meh() { return "meh"; }
+}
+
+@Bar("katt")
+@Bar("lol")
+@ContainedBy(BarContainer.class)
+@interface Bar {
+ String value();
+}
+
+@ContainerFor(Bar.class)
+@interface BarContainer {
+ Bar[] value();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/InvalidTarget.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,45 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean Foos Foo
+ * @run compile/fail InvalidTarget.java
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@Target(ElementType.ANNOTATION_TYPE)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@Target(ElementType.TYPE)
+@interface Foos {
+ Foo[] value();
+}
+
+public class InvalidTargets {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainedBy.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @compile/fail MissingContainedBy.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+
+@ContainerFor(MissingContainedBy.class)
+@interface Foos {
+ MissingContainedBy[] value();
+}
+
+public @interface MissingContainedBy {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/MissingContainerFor.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,38 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @compile/fail MissingContainerFor.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@interface Foos {
+ MissingContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface MissingContainerFor {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/NestedContainers.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,74 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean NestedContainers BasicRepeatingAnnos BasicRepeatingAnnos2 Foo Foos FoosFoos
+ * @run compile NestedContainers.java
+ * @run main NestedContainers
+ */
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(FoosFoos.class)
+@ContainerFor(Foo.class)
+@interface Foos {
+ Foo[] value();
+}
+
+@ContainerFor(Foos.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface FoosFoos {
+ Foos[] value();
+}
+
+@Foo
+@Foo
+class BasicRepeatingAnnos {}
+
+@Foos({})
+@Foos({})
+class BasicRepeatingAnnos2 {}
+
+public class NestedContainers {
+ public static void main(String[] args) throws Exception {
+ Annotation a = BasicRepeatingAnnos.class.getAnnotation(Foos.class);
+ if (a == null) {
+ throw new RuntimeException("Container annotation missing");
+ }
+
+ // Check 2:nd level container
+ a = BasicRepeatingAnnos2.class.getAnnotation(FoosFoos.class);
+ if (a == null) {
+ throw new RuntimeException("Container annotation missing");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepMemberAnno.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,49 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean RepMemberAnno Bar BarContainer
+ * @run compile RepMemberAnno.java
+ */
+
+import java.lang.annotation.ContainedBy;
+import java.lang.annotation.ContainerFor;
+
+public class RepMemberAnno {
+ @Bar("Apa") @Bar("Banan")
+ public void meh() {}
+}
+
+@ContainedBy(BarContainer.class)
+@interface Bar {
+ String value();
+}
+
+@ContainerFor(Bar.class)
+@interface BarContainer {
+ Bar[] value();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepSelfMemberAnno.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,60 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean RepSelfMemberAnno BarContainer BarContainerContainer
+ * @run compile RepSelfMemberAnno.java
+ */
+
+import java.lang.annotation.*;
+
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(BarContainer.class)
+public @interface RepSelfMemberAnno {
+ @RepSelfMemberAnno @RepSelfMemberAnno
+ String meh() default "banan";
+}
+
+
+@ContainedBy(BarContainerContainer.class)
+@Retention(RetentionPolicy.RUNTIME)
+@ContainerFor(RepSelfMemberAnno.class)
+@interface BarContainer {
+ RepSelfMemberAnno[] value();
+}
+
+@ContainerFor(BarContainer.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface BarContainerContainer {
+ BarContainer[] value();
+ String meh() default "apa";
+}
+
+@BarContainer(value={})
+@BarContainer(value={})
+@interface Bar {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/RepeatingAndContainerPresent.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Smoke test for repeating annotations
+ * @compile/fail RepeatingAndContainerPresent.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@interface Foos {
+ Foo[] value();
+}
+
+
+@Foo
+@Foo
+@Foos({})
+public class RepeatingAndContainerPresent {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SelfRepeatingAnnotations.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,55 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @bug 7151010
+ *
+ * @run clean SelfRepeatingAnnotations Foos SelfRepeatingAnno
+ * @run compile SelfRepeatingAnnotations.java
+ * @run main SelfRepeatingAnnotations
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(SelfRepeatingAnno.class)
+@Retention(RetentionPolicy.RUNTIME)
+@interface Foos {
+ SelfRepeatingAnno[] value();
+}
+
+@SelfRepeatingAnno
+@Retention(RetentionPolicy.RUNTIME)
+@SelfRepeatingAnno
+@ContainedBy(Foos.class)
+@interface SelfRepeatingAnno {}
+
+public class SelfRepeatingAnnotations {
+ public static void main(String[] args) throws Exception {
+ Annotation a = SelfRepeatingAnno.class.getAnnotation(Foos.class);
+ if (a == null) {
+ throw new RuntimeException("Container annotation missing");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/SingleRepeatingAndContainer.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,43 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @compile SingleRepeatingAndContainer.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainedBy(Foos.class)
+@interface Foo {}
+
+@ContainerFor(Foo.class)
+@interface Foos {
+ Foo[] value();
+}
+
+@Foo
+@Foos({})
+public class SingleRepeatingAndContainer {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainedBy.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @compile/fail UseWrongContainedBy.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(UseWrongContainedBy.class)
+@interface Foos {
+ UseWrongContainedBy[] value();
+}
+
+@ContainedBy(Target.class)
+public @interface UseWrongContainedBy {}
+
+@UseWrongContainedBy @UseWrongContainedBy
+@interface Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/UseWrongContainerFor.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,42 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @compile/fail UseWrongContainerFor.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(Retention.class)
+@interface Foos {
+ UseWrongContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface UseWrongContainerFor {}
+
+@UseWrongContainerFor @UseWrongContainerFor
+@interface Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainedBy.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @compile/fail WrongContainedBy.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(WrongContainedBy.class)
+@interface Foos {
+ WrongContainedBy[] value();
+}
+
+@ContainedBy(Target.class)
+public @interface WrongContainedBy {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/WrongContainerFor.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * @summary Smoke test for repeating annotations
+ * @compile/fail WrongContainerFor.java
+ * @bug 7151010
+ */
+
+import java.lang.annotation.*;
+
+@ContainerFor(Retention.class)
+@interface Foos {
+ WrongContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/api/7086261/T7086261.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/api/7086261/T7086261.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/api/T6397104.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/api/T6397104.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/CheckExamples.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/CheckExamples.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/MessageInfo.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/MessageInfo.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/RunExamples.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/RunExamples.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Fri Sep 14 10:14:02 2012 -0700
@@ -5,6 +5,9 @@
compiler.err.cant.read.file # (apt.JavaCompiler?)
compiler.err.cant.select.static.class.from.param.type
compiler.err.illegal.char.for.encoding
+compiler.err.invalid.containedby.annotation # should not happen
+compiler.err.invalid.containedby.annotation.invalid.value # "can't" happen
+compiler.err.invalid.containedby.annotation.multiple.values # can't happen
compiler.err.io.exception # (javah.JavahTask?)
compiler.err.limit.code # Code
compiler.err.limit.code.too.large.for.try.stmt # Gen
--- a/langtools/test/tools/javac/diags/examples/ApplicableMethodFound1.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/ApplicableMethodFound1.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByDocumentedMismatch.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.not.documented
+
+import java.lang.annotation.*;
+
+@Documented
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class ContainedByDocumentedMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByInheritedMismatch.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.not.inherited
+
+import java.lang.annotation.*;
+
+@Inherited
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class ContainedByInheritedMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByNoValue.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.no.value
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos {}
+
+@Anno
+@Anno
+class ContainedByNoValue { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByNonDefault.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.elem.nondefault
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); String foo(); }
+
+@Anno
+@Anno
+class ContainedByNonDefault { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByRetentionMismatch.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.retention
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+class ContainedByRetentionMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByTargetMismatch.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.incompatible.target
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@Target(ElementType.METHOD)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+class ContainedByTargetMismatch { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ContainedByWrongValueType.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.value.return
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { String value(); }
+
+@Anno
+@Anno
+class ContainedByWrongValueType { }
--- a/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotation.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,8 @@
*/
// key: compiler.err.duplicate.annotation
+// key: compiler.warn.source.no.bootclasspath
+// options: -source 7
@interface Anno { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/DuplicateAnnotationJava8.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.duplicate.annotation.missing.container
+
+@interface Anno { }
+
+@Anno
+@Anno
+class DuplicateAnnotationJava8 { }
--- a/langtools/test/tools/javac/diags/examples/IllegalDot.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/IllegalDot.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/InconvertibleTypes.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/InconvertibleTypes.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/KindnameConstructor.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/KindnameConstructor.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/NotApplicableMethodFound.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/NotApplicableMethodFound.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/PossibleLossPrecision.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/PossibleLossPrecision.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RepeatingAnnotationAndContainer.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.containedby.annotation.repeated.and.container.present
+
+import java.lang.annotation.*;
+
+@ContainedBy(Annos.class)
+@interface Anno { }
+
+@ContainerFor(Anno.class)
+@interface Annos { Anno[] value(); }
+
+@Anno
+@Anno
+@Annos(@Anno)
+class RepeatingAnnotationAndContainer { }
--- a/langtools/test/tools/javac/diags/examples/ResourceNotApplicableToType.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/ResourceNotApplicableToType.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/VarargsArgumentMismatch.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/VarargsArgumentMismatch.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/VerboseResolveMulti1.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/VerboseResolveMulti1.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/WhereCaptured.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/WhereCaptured.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/WhereCaptured1.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/WhereCaptured1.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/WhereIntersection.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/WhereIntersection.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/diags/examples/WhereTypeVar.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/diags/examples/WhereTypeVar.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/WrongContainedBy.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.container.no.containerfor
+// key: compiler.err.invalid.container.wrong.containedby
+
+import java.lang.annotation.*;
+
+@ContainerFor(WrongContainedBy.class)
+@interface Foos {
+ WrongContainedBy[] value();
+}
+
+@ContainedBy(Target.class)
+public @interface WrongContainedBy {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/WrongContainerFor.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.invalid.container.wrong.containerfor
+// key: compiler.err.invalid.container.no.containedby
+
+import java.lang.annotation.*;
+
+@ContainerFor(Retention.class)
+@interface Foos {
+ WrongContainerFor[] value();
+}
+
+@ContainedBy(Foos.class)
+public @interface WrongContainerFor {}
--- a/langtools/test/tools/javac/generics/typevars/T7148242.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/generics/typevars/T7148242.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/newlines/Newlines.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/newlines/Newlines.sh Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/parser/T4881269.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/parser/T4881269.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/processing/6348499/T6348499.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/processing/6348499/T6348499.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,7 @@
public static void main(String... args) {
String testSrc = System.getProperty("test.src", ".");
String testClasses = System.getProperty("test.classes");
+ String testClassPath = System.getProperty("test.class.path", testClasses);
String A_java = new File(testSrc, "A.java").getPath();
JavacTool tool = JavacTool.create();
MyDiagListener dl = new MyDiagListener();
@@ -55,7 +56,7 @@
fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java")));
Iterable<String> opts = Arrays.asList("-proc:only",
"-processor", "A",
- "-processorpath", testClasses);
+ "-processorpath", testClassPath);
StringWriter out = new StringWriter();
JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
task.call();
--- a/langtools/test/tools/javac/processing/6414633/T6414633.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/processing/6414633/T6414633.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,20 +43,20 @@
public static void main(String... args) {
String testSrc = System.getProperty("test.src", ".");
String testClasses = System.getProperty("test.classes", ".");
+ String testClassPath = System.getProperty("test.class.path", testClasses);
JavacTool tool = JavacTool.create();
MyDiagListener dl = new MyDiagListener();
StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null);
try {
- fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File(testClasses)));
+ fm.setLocation(StandardLocation.CLASS_PATH, pathToFiles(testClassPath));
} catch (IOException e) {
throw new AssertionError(e);
}
Iterable<? extends JavaFileObject> files =
fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java")));
String[] opts = { "-proc:only",
- "-processor", A.class.getName(),
- "-classpath", testClasses + System.getProperty("path.separator") + "../../lib" };
+ "-processor", A.class.getName() };
JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files);
task.call();
@@ -65,6 +65,15 @@
throw new AssertionError(dl.diags + " diagnostics reported");
}
+ private static List<File> pathToFiles(String path) {
+ List<File> list = new ArrayList<File>();
+ for (String s: path.split(File.pathSeparator)) {
+ if (!s.isEmpty())
+ list.add(new File(s));
+ }
+ return list;
+ }
+
private static class MyDiagListener implements DiagnosticListener<JavaFileObject>
{
public void report(Diagnostic d) {
--- a/langtools/test/tools/javac/processing/T6920317.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/processing/T6920317.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -156,7 +156,9 @@
String expect = null;
opts.add("-processorpath");
- opts.add(System.getProperty("test.classes"));
+ String testClasses = System.getProperty("test.classes");
+ String testClassPath = System.getProperty("test.class.path", testClasses);
+ opts.add(testClassPath);
opts.add("-processor");
opts.add(Processor.class.getName());
opts.add("-proc:only");
--- a/langtools/test/tools/javac/processing/TestWarnErrorCount.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/processing/TestWarnErrorCount.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
--- a/langtools/test/tools/javac/processing/options/testPrintProcessorInfo/TestWithXstdout.java Fri Sep 14 09:47:14 2012 -0700
+++ b/langtools/test/tools/javac/processing/options/testPrintProcessorInfo/TestWithXstdout.java Fri Sep 14 10:14:02 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,8 @@
public class TestWithXstdout {
public static void main(String... args) throws Exception {
File testSrc = new File(System.getProperty("test.src"));
- File testClasses = new File(System.getProperty("test.classes"));
+ String testClasses = System.getProperty("test.classes", ".");
+ String testClassPath = System.getProperty("test.class.path", testClasses);
File stdout = new File("stdout.out");
run_javac("-XDrawDiagnostics",
"-XprintProcessorInfo",
@@ -46,7 +47,7 @@
"-proc:only",
"-processor", "Test",
"-Xstdout", stdout.getPath(),
- "-classpath", testClasses.getPath(),
+ "-classpath", testClassPath,
new File(testSrc, "Test.java").getPath());
boolean ok = compare(stdout, new File(testSrc, "Test.out"));
if (!ok)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javah/T7185778.java Fri Sep 14 10:14:02 2012 -0700
@@ -0,0 +1,56 @@
+/*
+ * 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 7185778
+ * @summary javah error "Not a valid class name" on class names with dollar signs
+ * The first two tests are on an inner class name whose name does not contain $.
+ * The second two tests are on an inner class name whose name does contain $.
+ * The last test is on an outer class whose name contains $.
+ * @run main T7185778 T7185778$inner
+ * @run main T7185778 T7185778.inner
+ * @run main T7185778 T7185778$inner$
+ * @run main T7185778 T7185778.inner$
+ * @run main T7185778 xx$yy
+ */
+
+public class T7185778 {
+ class inner {
+ native byte[] xxxxx(String name);
+ }
+ class inner$ {
+ native byte[] xxxxx(String name);
+ }
+
+ static public void main(String[] args) {
+ int rc = com.sun.tools.javah.Main.run(args, null);
+ if ( rc != 0) {
+ throw new Error("javah returned non zero: " + rc);
+ }
+ }
+}
+
+class xx$yy {
+ native byte[] xxxxx(String name);
+}
--- a/make/scripts/hgforest.sh Fri Sep 14 09:47:14 2012 -0700
+++ b/make/scripts/hgforest.sh Fri Sep 14 10:14:02 2012 -0700
@@ -58,7 +58,7 @@
fi
done
if [ "${pull_extra_base}" != "" ] ; then
- subrepos_extra="jdk/src/closed jdk/make/closed jdk/test/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
+ subrepos_extra="jdk/src/closed jdk/make/closed jdk/test/closed hotspot/make/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
pull_default_tail=`echo ${pull_default} | sed -e 's@^.*://[^/]*/\(.*\)@\1@'`
pull_extra="${pull_extra_base}/${pull_default_tail}"
for i in ${subrepos_extra} ; do