# HG changeset patch # User prr # Date 1401224280 25200 # Node ID fb7374c4fd87ad9b42f2f062988c6de07788a042 # Parent 080de8ffa3f676c6a0e82ae700e697ecd6224ac8# Parent b3bf9c82a050911fb5c10ee48cf9a0a391f3f45c Merge diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/make/CompileJavaClasses.gmk --- a/jdk/make/CompileJavaClasses.gmk Tue May 27 12:50:51 2014 -0700 +++ b/jdk/make/CompileJavaClasses.gmk Tue May 27 13:58:00 2014 -0700 @@ -38,7 +38,7 @@ ########################################################################################## -EXCLUDES += com/sun/pept \ +EXCLUDES += \ com/sun/tools/example/trace \ com/sun/tools/example/debug/bdi \ com/sun/tools/example/debug/event \ diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/jndi/ldap/Connection.java --- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java Tue May 27 13:58:00 2014 -0700 @@ -474,7 +474,7 @@ } if ((rber == null) && waited) { - removeRequest(ldr); + abandonRequest(ldr, null); throw new NamingException("LDAP response read timed out, timeout used:" + readTimeout + "ms." ); diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/Delegate.java --- a/jdk/src/share/classes/com/sun/pept/Delegate.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Delegate.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept; - -import com.sun.pept.presentation.MessageStruct; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface Delegate { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - * @return a MessageStruct with ... - *

- */ - public MessageStruct getMessageStruct(); -/** - *

- * Does ... - *

- * - *

- * - * @param message ... - *

- */ - public void send(MessageStruct message); - -} // end Delegate diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/encoding/Decoder.java --- a/jdk/src/share/classes/com/sun/pept/encoding/Decoder.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Decoder.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.encoding; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface Decoder { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - *

- * - * @param messageInfo ... - *

- */ - public void decode(MessageInfo messageInfo); -/** - *

- * Does ... - *

- * - *

- * - * @param messageInfo ... - *

- */ - public void receiveAndDecode(MessageInfo messageInfo); - -} // end Decoder diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/encoding/Encoder.java --- a/jdk/src/share/classes/com/sun/pept/encoding/Encoder.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Encoder.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.encoding; - -import com.sun.pept.ept.MessageInfo; -import java.nio.ByteBuffer; -import java.util.*; - -/** - *

- * - * @author Arun Gupta - *

- */ -public interface Encoder { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - *

- * - * @param messageInfo ... - *

- */ - public void encodeAndSend(MessageInfo messageInfo); -/** - *

- * Does ... - *

- * - * @return a ByteBuffer with ... - *

- * @param messageInfo ... - *

- */ - public ByteBuffer encode(MessageInfo messageInfo); - -} // end Encoder diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/ept/Acceptor.java --- a/jdk/src/share/classes/com/sun/pept/ept/Acceptor.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Acceptor.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.ept; - -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface Acceptor extends EPTFactory { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - *

- */ - public void accept(); - -} // end Acceptor diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/ept/ContactInfo.java --- a/jdk/src/share/classes/com/sun/pept/ept/ContactInfo.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "ContactInfo.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.ept; - -import com.sun.pept.transport.Connection; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface ContactInfo extends EPTFactory { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - * @return a Connection with ... - *

- * @param messageInfo ... - *

- */ - public Connection getConnection(MessageInfo messageInfo); - -} // end ContactInfo diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/ept/ContactInfoList.java --- a/jdk/src/share/classes/com/sun/pept/ept/ContactInfoList.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "ContactInfoList.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.ept; - -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface ContactInfoList { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - * @return a ContactInfoListIterator with ... - *

- */ - public ContactInfoListIterator iterator(); - -} // end ContactInfoList diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/ept/ContactInfoListIterator.java --- a/jdk/src/share/classes/com/sun/pept/ept/ContactInfoListIterator.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "ContactInfoListIterator.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.ept; - -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface ContactInfoListIterator { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - * @return a boolean with ... - *

- */ - public boolean hasNext(); -/** - *

- * Does ... - *

- * - * @return a ContactInfo with ... - *

- */ - public ContactInfo next(); - -} // end ContactInfoListIterator diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/ept/EPTFactory.java --- a/jdk/src/share/classes/com/sun/pept/ept/EPTFactory.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "EPTFactory.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.ept; - -import com.sun.pept.encoding.Decoder; -import com.sun.pept.encoding.Encoder; -import com.sun.pept.presentation.TargetFinder; -import com.sun.pept.protocol.Interceptors; -import com.sun.pept.protocol.MessageDispatcher; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface EPTFactory { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - * @return a MessageDispatcher with ... - *

- * @param messageInfo ... - *

- */ - public MessageDispatcher getMessageDispatcher(MessageInfo messageInfo); -/** - *

- * Does ... - *

- * - * @return a Encoder with ... - *

- * @param messageInfo ... - *

- */ - public Encoder getEncoder(MessageInfo messageInfo); -/** - *

- * Does ... - *

- * - * @return a Decoder with ... - *

- * @param messageInfo ... - *

- */ - public Decoder getDecoder(MessageInfo messageInfo); -/** - *

- * Does ... - *

- * - * @return a Interceptors with ... - *

- * @param x ... - *

- */ - public Interceptors getInterceptors(MessageInfo x); -/** - *

- * Does ... - *

- * - * @return a TargetFinder with ... - *

- * @param x ... - *

- */ - public TargetFinder getTargetFinder(MessageInfo x); - -} // end EPTFactory diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/ept/MessageInfo.java --- a/jdk/src/share/classes/com/sun/pept/ept/MessageInfo.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "MessageInfo.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.ept; - -import com.sun.pept.encoding.Decoder; -import com.sun.pept.encoding.Encoder; -import com.sun.pept.presentation.MessageStruct; -import com.sun.pept.protocol.MessageDispatcher; -import com.sun.pept.transport.Connection; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface MessageInfo extends MessageStruct { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - * @return a EPTFactory with ... - *

- */ - public EPTFactory getEPTFactory(); -/** - *

- * Does ... - *

- * - * @return a MessageDispatcher with ... - *

- */ - public MessageDispatcher getMessageDispatcher(); -/** - *

- * Does ... - *

- * - * @return a Encoder with ... - *

- */ - public Encoder getEncoder(); -/** - *

- * Does ... - *

- * - * @return a Decoder with ... - *

- */ - public Decoder getDecoder(); -/** - *

- * Does ... - *

- * - * @return a Connection with ... - *

- */ - public Connection getConnection(); -/** - *

- * Does ... - *

- * - *

- * - * @param eptFactory ... - *

- */ - public void setEPTFactory(EPTFactory eptFactory); -/** - *

- * Does ... - *

- * - *

- * - * @param messageDispatcher ... - *

- */ - public void setMessageDispatcher(MessageDispatcher messageDispatcher); -/** - *

- * Does ... - *

- * - *

- * - * @param encoder ... - *

- */ - public void setEncoder(Encoder encoder); -/** - *

- * Does ... - *

- * - *

- * - * @param decoder ... - *

- */ - public void setDecoder(Decoder decoder); -/** - *

- * Does ... - *

- * - *

- * - * @param connection ... - *

- */ - public void setConnection(Connection connection); - -} // end MessageInfo diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/presentation/MessageStruct.java --- a/jdk/src/share/classes/com/sun/pept/presentation/MessageStruct.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "MessageStruct.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.presentation; - -import java.util.*; -import java.lang.reflect.Method; -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface MessageStruct { - - /////////////////////////////////////// - //attributes - - -/** - *

- * Represents ... - *

- */ - public static final int NORMAL_RESPONSE = 0; - -/** - *

- * Represents ... - *

- */ - public static final int CHECKED_EXCEPTION_RESPONSE = 1; - -/** - *

- * Represents ... - *

- */ - public static final int UNCHECKED_EXCEPTION_RESPONSE = 2; - -/** - *

- * Represents ... - *

- */ - public static final int REQUEST_RESPONSE_MEP = 1; - -/** - *

- * Represents ... - *

- */ - public static final int ONE_WAY_MEP = 2; - -/** - *

- * Represents ... - *

- */ - public static final int ASYNC_POLL_MEP = 3; - -/** - *

- * Represents ... - *

- */ - public static final int ASYNC_CALLBACK_MEP = 4; - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - * @param data ... - *

- * - *

- */ - public void setData(Object[] data); -/** - *

- * Does ... - *

- * - * @return a Object[] with ... - *

- */ - public Object[] getData(); -/** - *

- * Does ... - *

- * - *

- * - * @param name ... - *

- * @param value ... - *

- */ - public void setMetaData(Object name, Object value); -/** - *

- * Does ... - *

- * - * @return a Object with ... - *

- * @param name ... - *

- */ - public Object getMetaData(Object name); -/** - *

- * Does ... - *

- * - *

- * - * @param messageExchangePattern ... - *

- */ - public void setMEP(int messageExchangePattern); -/** - *

- * Does ... - *

- * - * @return a int with ... - *

- */ - public int getMEP(); -/** - *

- * Does ... - *

- * - * @return a int with ... - *

- */ - public int getResponseType(); -/** - *

- * Does ... - *

- * - *

- * - * @param responseType ... - *

- */ - public void setResponseType(int responseType); -/** - *

- * Does ... - *

- * - * @return a Object with ... - *

- */ - public Object getResponse(); -/** - *

- * Does ... - *

- * - *

- * - * @param response ... - *

- */ - public void setResponse(Object response); -/** - *

- * Does ... - *

- * - *

- * - * @param method ... - *

- */ - public void setMethod(Method method); -/** - *

- * Does ... - *

- * - * @return a Method with ... - *

- */ - public Method getMethod(); - -} // end MessageStruct diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/presentation/Stub.java --- a/jdk/src/share/classes/com/sun/pept/presentation/Stub.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Stub.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.presentation; - -import com.sun.pept.Delegate; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface Stub { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - *

- * - * @param delegate ... - *

- */ - public void _setDelegate(Delegate delegate); -/** - *

- * Does ... - *

- * - * @return a Delegate with ... - *

- */ - public Delegate _getDelegate(); - -} // end Stub diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/presentation/TargetFinder.java --- a/jdk/src/share/classes/com/sun/pept/presentation/TargetFinder.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "TargetFinder.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.presentation; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface TargetFinder { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - * @return a Tie with ... - *

- * @param x ... - *

- */ - public Tie findTarget(MessageInfo x); - -} // end TargetFinder diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/presentation/Tie.java --- a/jdk/src/share/classes/com/sun/pept/presentation/Tie.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** Java interface "Tie.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.presentation; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface Tie { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - *

- * - * @param servant ... - *

- */ - public void _setServant(Object servant); -/** - *

- * Does ... - *

- * - * @return a Object with ... - *

- */ - public Object _getServant(); -/** - *

- * Does ... - *

- * - *

- * - * @param messageInfo ... - *

- */ - public void _invoke(MessageInfo messageInfo); - -} // end Tie diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/protocol/Interceptors.java --- a/jdk/src/share/classes/com/sun/pept/protocol/Interceptors.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** - * $Id: Interceptors.java,v 1.1 2005/05/23 22:09:18 bbissett Exp $ - */ - -/** Java interface "Interceptors.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.protocol; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface Interceptors { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - *

- * - * @param messageInfo ... - *

- */ - public void interceptMessage(MessageInfo messageInfo); - -} // end Interceptors diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/protocol/MessageDispatcher.java --- a/jdk/src/share/classes/com/sun/pept/protocol/MessageDispatcher.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** - * $Id: MessageDispatcher.java,v 1.1 2005/05/23 22:09:18 bbissett Exp $ - */ - -/** Java interface "MessageDispatcher.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.protocol; - -import com.sun.pept.ept.MessageInfo; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface MessageDispatcher { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - *

- * - * @param messageInfo ... - *

- */ - public void send(MessageInfo messageInfo); -/** - *

- * Does ... - *

- * - *

- * - * @param messageInfo ... - *

- */ - public void receive(MessageInfo messageInfo); - -} // end MessageDispatcher diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/pept/transport/Connection.java --- a/jdk/src/share/classes/com/sun/pept/transport/Connection.java Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2005, 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. - */ - -/** - * $Id: Connection.java,v 1.2 2005/07/23 04:09:58 kohlert Exp $ - */ - -/** Java interface "Connection.java" generated from Poseidon for UML. - * Poseidon for UML is developed by Gentleware. - * Generated with velocity template engine. - */ -package com.sun.pept.transport; - -import com.sun.pept.ept.EPTFactory; -import java.nio.ByteBuffer; -import java.util.*; - -/** - *

- * - * @author Dr. Harold Carr - *

- */ -public interface Connection { - - /////////////////////////////////////// - // operations - -/** - *

- * Does ... - *

- * - *

- * - * @param byteBuffer ... - *

- */ - public void write(ByteBuffer byteBuffer); -/** - *

- * Does ... - *

- * - * @return a EPTFactory with ... - *

- */ - public EPTFactory getEPTFactory(); -/** - *

- * Does ... - *

- * - * @return a int with ... - *

- * @param byteBuffer ... - *

- */ - public int read(ByteBuffer byteBuffer); -/** - *

- * Does ... - *

- * - *

- */ - public ByteBuffer readUntilEnd(); - -} // end Connection diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/tools/hat/MANIFEST.mf --- a/jdk/src/share/classes/com/sun/tools/hat/MANIFEST.mf Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -Manifest-Version: 1.0 -Main-Class: com.sun.tools.hat.Main diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/tools/hat/README.txt --- a/jdk/src/share/classes/com/sun/tools/hat/README.txt Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ --------------- -This HAT source originally came from the http://hat.dev.java.net site. - -The utility has been named 'jhat' in the JDK, it is basically the same tool. - -Q: Where do I make changes? In the JDK or hat.dev.java.net? - -A: It depends on whether the change is intended for the JDK jhat version only, - or expected to be given back to the java.net project. - In general, we should putback changes to the java.net project and - bringover those changes to the JDK. - -Q: I want to build just jhat.jar instead of building entire JDK. What should I do? - -A: Use ant makefile (build.xml) in the current directory. This builds just the -jhat sources and creates jhat.jar under ./build directory. - -To run the built jhat.jar, you can use the command: - - java -jar build/jhat.jar heap_dump diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/com/sun/tools/hat/build.xml --- a/jdk/src/share/classes/com/sun/tools/hat/build.xml Tue May 27 12:50:51 2014 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/Process.java --- a/jdk/src/share/classes/java/lang/Process.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/Process.java Tue May 27 13:58:00 2014 -0700 @@ -262,4 +262,18 @@ return true; } } + + /** + * Returns the native process id of the subprocess. + * The native process id is an identification number that the operating + * system assigns to the process. + * + * @return the native process id of the subprocess + * @throws UnsupportedOperationException if the Process implementation + * does not support this operation + * @since 1.9 + */ + public long getPid() { + throw new UnsupportedOperationException(); + } } diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java --- a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java Tue May 27 13:58:00 2014 -0700 @@ -26,11 +26,10 @@ package java.lang.invoke; import static jdk.internal.org.objectweb.asm.Opcodes.*; -import static java.lang.invoke.LambdaForm.basicTypes; -import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic; +import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleStatics.*; -import java.lang.invoke.LambdaForm.Name; import java.lang.invoke.LambdaForm.NamedFunction; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; @@ -61,22 +60,22 @@ // BMH API and internals // - static MethodHandle bindSingle(MethodType type, LambdaForm form, char xtype, Object x) { + static MethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) { // for some type signatures, there exist pre-defined concrete BMH classes try { switch (xtype) { - case 'L': + case L_TYPE: if (true) return bindSingle(type, form, x); // Use known fast path. - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('L').constructor[0].invokeBasic(type, form, x); - case 'I': - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('I').constructor[0].invokeBasic(type, form, ValueConversions.widenSubword(x)); - case 'J': - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('J').constructor[0].invokeBasic(type, form, (long) x); - case 'F': - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('F').constructor[0].invokeBasic(type, form, (float) x); - case 'D': - return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('D').constructor[0].invokeBasic(type, form, (double) x); - default : throw new InternalError("unexpected xtype: " + xtype); + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(L_TYPE).constructor[0].invokeBasic(type, form, x); + case I_TYPE: + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(I_TYPE).constructor[0].invokeBasic(type, form, ValueConversions.widenSubword(x)); + case J_TYPE: + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(J_TYPE).constructor[0].invokeBasic(type, form, (long) x); + case F_TYPE: + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(F_TYPE).constructor[0].invokeBasic(type, form, (float) x); + case D_TYPE: + return (BoundMethodHandle) SpeciesData.EMPTY.extendWith(D_TYPE).constructor[0].invokeBasic(type, form, (double) x); + default : throw newInternalError("unexpected xtype: " + xtype); } } catch (Throwable t) { throw newInternalError(t); @@ -87,23 +86,23 @@ return new Species_L(type, form, x); } - MethodHandle cloneExtend(MethodType type, LambdaForm form, char xtype, Object x) { + MethodHandle cloneExtend(MethodType type, LambdaForm form, BasicType xtype, Object x) { try { switch (xtype) { - case 'L': return cloneExtendL(type, form, x); - case 'I': return cloneExtendI(type, form, ValueConversions.widenSubword(x)); - case 'J': return cloneExtendJ(type, form, (long) x); - case 'F': return cloneExtendF(type, form, (float) x); - case 'D': return cloneExtendD(type, form, (double) x); + case L_TYPE: return copyWithExtendL(type, form, x); + case I_TYPE: return copyWithExtendI(type, form, ValueConversions.widenSubword(x)); + case J_TYPE: return copyWithExtendJ(type, form, (long) x); + case F_TYPE: return copyWithExtendF(type, form, (float) x); + case D_TYPE: return copyWithExtendD(type, form, (double) x); } } catch (Throwable t) { throw newInternalError(t); } - throw new InternalError("unexpected type: " + xtype); + throw newInternalError("unexpected type: " + xtype); } @Override - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { MethodType type = type().dropParameterTypes(pos, pos+1); LambdaForm form = internalForm().bind(1+pos, speciesData()); return cloneExtend(type, form, basicType, value); @@ -111,9 +110,9 @@ @Override MethodHandle dropArguments(MethodType srcType, int pos, int drops) { - LambdaForm form = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos+drops)); + LambdaForm form = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos + drops)); try { - return clone(srcType, form); + return copyWith(srcType, form); } catch (Throwable t) { throw newInternalError(t); } @@ -122,26 +121,23 @@ @Override MethodHandle permuteArguments(MethodType newType, int[] reorder) { try { - return clone(newType, form.permuteArguments(1, reorder, basicTypes(newType.parameterList()))); + return copyWith(newType, form.permuteArguments(1, reorder, basicTypes(newType.parameterList()))); } catch (Throwable t) { throw newInternalError(t); } } - static final String EXTENSION_TYPES = "LIJFD"; - static final byte INDEX_L = 0, INDEX_I = 1, INDEX_J = 2, INDEX_F = 3, INDEX_D = 4; - static byte extensionIndex(char type) { - int i = EXTENSION_TYPES.indexOf(type); - if (i < 0) throw new InternalError(); - return (byte) i; - } - /** * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a * static field containing this value, and they must accordingly implement this method. */ /*non-public*/ abstract SpeciesData speciesData(); + /** + * Return the number of fields in this BMH. Equivalent to speciesData().fieldCount(). + */ + /*non-public*/ abstract int fieldCount(); + @Override final Object internalProperties() { return "/BMH="+internalValues(); @@ -159,38 +155,33 @@ /*non-public*/ final Object arg(int i) { try { switch (speciesData().fieldType(i)) { - case 'L': return argL(i); - case 'I': return argI(i); - case 'F': return argF(i); - case 'D': return argD(i); - case 'J': return argJ(i); + case L_TYPE: return speciesData().getters[i].invokeBasic(this); + case I_TYPE: return (int) speciesData().getters[i].invokeBasic(this); + case J_TYPE: return (long) speciesData().getters[i].invokeBasic(this); + case F_TYPE: return (float) speciesData().getters[i].invokeBasic(this); + case D_TYPE: return (double) speciesData().getters[i].invokeBasic(this); } } catch (Throwable ex) { throw newInternalError(ex); } - throw new InternalError("unexpected type: " + speciesData().types+"."+i); + throw new InternalError("unexpected type: " + speciesData().typeChars+"."+i); } - /*non-public*/ final Object argL(int i) throws Throwable { return speciesData().getters[i].invokeBasic(this); } - /*non-public*/ final int argI(int i) throws Throwable { return (int) speciesData().getters[i].invokeBasic(this); } - /*non-public*/ final float argF(int i) throws Throwable { return (float) speciesData().getters[i].invokeBasic(this); } - /*non-public*/ final double argD(int i) throws Throwable { return (double) speciesData().getters[i].invokeBasic(this); } - /*non-public*/ final long argJ(int i) throws Throwable { return (long) speciesData().getters[i].invokeBasic(this); } // // cloning API // - /*non-public*/ abstract BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable; - /*non-public*/ abstract BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable; + /*non-public*/ abstract BoundMethodHandle copyWith(MethodType mt, LambdaForm lf); + /*non-public*/ abstract BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg); + /*non-public*/ abstract BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg); + /*non-public*/ abstract BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg); + /*non-public*/ abstract BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg); + /*non-public*/ abstract BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg); // The following is a grossly irregular hack: @Override MethodHandle reinvokerTarget() { try { - return (MethodHandle) argL(0); + return (MethodHandle) arg(0); } catch (Throwable ex) { throw newInternalError(ex); } @@ -203,7 +194,7 @@ private // make it private to force users to access the enclosing class first static final class Species_L extends BoundMethodHandle { final Object argL0; - /*non-public*/ Species_L(MethodType mt, LambdaForm lf, Object argL0) { + private Species_L(MethodType mt, LambdaForm lf, Object argL0) { super(mt, lf); this.argL0 = argL0; } @@ -213,140 +204,95 @@ /*non-public*/ SpeciesData speciesData() { return SPECIES_DATA; } - /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class); @Override - /*non-public*/ final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable { + /*non-public*/ int fieldCount() { + return 1; + } + /*non-public*/ static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class); + /*non-public*/ static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0) { + return new Species_L(mt, lf, argL0); + } + @Override + /*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) { return new Species_L(mt, lf, argL0); } @Override - /*non-public*/ final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, narg); - } - @Override - /*non-public*/ final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, narg); - } - @Override - /*non-public*/ final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, narg); - } - @Override - /*non-public*/ final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, narg); + /*non-public*/ final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(L_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } } @Override - /*non-public*/ final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, narg); - } - } - -/* - static final class Species_LL extends BoundMethodHandle { - final Object argL0; - final Object argL1; - public Species_LL(MethodType mt, LambdaForm lf, Object argL0, Object argL1) { - super(mt, lf); - this.argL0 = argL0; - this.argL1 = argL1; - } - @Override - public SpeciesData speciesData() { - return SPECIES_DATA; - } - public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LL", Species_LL.class); - @Override - public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable { - return new Species_LL(mt, lf, argL0, argL1); - } - @Override - public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); + /*non-public*/ final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(I_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } } @Override - public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg); - } - } - - static final class Species_JL extends BoundMethodHandle { - final long argJ0; - final Object argL1; - public Species_JL(MethodType mt, LambdaForm lf, long argJ0, Object argL1) { - super(mt, lf); - this.argJ0 = argJ0; - this.argL1 = argL1; + /*non-public*/ final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(J_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } } @Override - public SpeciesData speciesData() { - return SPECIES_DATA; - } - public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("JL", Species_JL.class); - @Override public final long argJ0() { return argJ0; } - @Override public final Object argL1() { return argL1; } - @Override - public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable { - return new Species_JL(mt, lf, argJ0, argL1); - } - @Override - public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); + /*non-public*/ final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(F_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } } @Override - public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); - } - @Override - public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable { - return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg); + /*non-public*/ final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) { + try { + return (BoundMethodHandle) SPECIES_DATA.extendWith(D_TYPE).constructor[0].invokeBasic(mt, lf, argL0, narg); + } catch (Throwable ex) { + throw uncaughtException(ex); + } } } -*/ // // BMH species meta-data // /** - * Meta-data wrapper for concrete BMH classes. + * Meta-data wrapper for concrete BMH types. + * Each BMH type corresponds to a given sequence of basic field types (LIJFD). + * The fields are immutable; their values are fully specified at object construction. + * Each BMH type supplies an array of getter functions which may be used in lambda forms. + * A BMH is constructed by cloning a shorter BMH and adding one or more new field values. + * As a degenerate and common case, the "shorter BMH" can be missing, and contributes zero prior fields. */ static class SpeciesData { - final String types; + final String typeChars; + final BasicType[] typeCodes; final Class clazz; // Bootstrapping requires circular relations MH -> BMH -> SpeciesData -> MH // Therefore, we need a non-final link in the chain. Use array elements. final MethodHandle[] constructor; final MethodHandle[] getters; + final NamedFunction[] nominalGetters; final SpeciesData[] extensions; /*non-public*/ int fieldCount() { - return types.length(); + return typeCodes.length; } - /*non-public*/ char fieldType(int i) { - return types.charAt(i); + /*non-public*/ BasicType fieldType(int i) { + return typeCodes[i]; + } + /*non-public*/ char fieldTypeChar(int i) { + return typeChars.charAt(i); } public String toString() { - return "SpeciesData["+(isPlaceholder() ? "" : clazz.getSimpleName())+":"+types+"]"; + return "SpeciesData["+(isPlaceholder() ? "" : clazz.getSimpleName())+":"+typeChars+"]"; } /** @@ -354,45 +300,46 @@ * represents a MH bound to a generic invoker, which in turn forwards to the corresponding * getter. */ - Name getterName(Name mhName, int i) { - MethodHandle mh = getters[i]; - assert(mh != null) : this+"."+i; - return new Name(mh, mhName); - } - NamedFunction getterFunction(int i) { - return new NamedFunction(getters[i]); + return nominalGetters[i]; } static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class); private SpeciesData(String types, Class clazz) { - this.types = types; + this.typeChars = types; + this.typeCodes = basicTypes(types); this.clazz = clazz; if (!INIT_DONE) { - this.constructor = new MethodHandle[1]; + this.constructor = new MethodHandle[1]; // only one ctor this.getters = new MethodHandle[types.length()]; + this.nominalGetters = new NamedFunction[types.length()]; } else { this.constructor = Factory.makeCtors(clazz, types, null); this.getters = Factory.makeGetters(clazz, types, null); + this.nominalGetters = Factory.makeNominalGetters(types, null, this.getters); } - this.extensions = new SpeciesData[EXTENSION_TYPES.length()]; + this.extensions = new SpeciesData[ARG_TYPE_LIMIT]; } private void initForBootstrap() { assert(!INIT_DONE); if (constructor[0] == null) { + String types = typeChars; Factory.makeCtors(clazz, types, this.constructor); Factory.makeGetters(clazz, types, this.getters); + Factory.makeNominalGetters(types, this.nominalGetters, this.getters); } } - private SpeciesData(String types) { + private SpeciesData(String typeChars) { // Placeholder only. - this.types = types; + this.typeChars = typeChars; + this.typeCodes = basicTypes(typeChars); this.clazz = null; this.constructor = null; this.getters = null; + this.nominalGetters = null; this.extensions = null; } private boolean isPlaceholder() { return clazz == null; } @@ -401,18 +348,15 @@ static { CACHE.put("", EMPTY); } // make bootstrap predictable private static final boolean INIT_DONE; // set after finishes... - SpeciesData extendWithType(char type) { - int i = extensionIndex(type); - SpeciesData d = extensions[i]; - if (d != null) return d; - extensions[i] = d = get(types+type); - return d; + SpeciesData extendWith(byte type) { + return extendWith(BasicType.basicType(type)); } - SpeciesData extendWithIndex(byte index) { - SpeciesData d = extensions[index]; + SpeciesData extendWith(BasicType type) { + int ord = type.ordinal(); + SpeciesData d = extensions[ord]; if (d != null) return d; - extensions[index] = d = get(types+EXTENSION_TYPES.charAt(index)); + extensions[ord] = d = get(typeChars+type.basicTypeChar()); return d; } @@ -456,8 +400,6 @@ static { // pre-fill the BMH speciesdata cache with BMH's inner classes final Class rootCls = BoundMethodHandle.class; - SpeciesData d0 = BoundMethodHandle.SPECIES_DATA; // trigger class init - assert(d0 == null || d0 == lookupCache("")) : d0; try { for (Class c : rootCls.getDeclaredClasses()) { if (rootCls.isAssignableFrom(c)) { @@ -465,7 +407,7 @@ SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh); assert(d != null) : cbmh.getName(); assert(d.clazz == cbmh); - assert(d == lookupCache(d.types)); + assert(d == lookupCache(d.typeChars)); } } } catch (Throwable e) { @@ -516,11 +458,10 @@ static final String BMHSPECIES_DATA_GFC_SIG = "(" + JLS_SIG + JLC_SIG + ")" + SPECIES_DATA_SIG; static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG; static final String VOID_SIG = "()V"; + static final String INT_SIG = "()I"; static final String SIG_INCIPIT = "(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;"; - static final Class[] TYPES = new Class[] { Object.class, int.class, long.class, float.class, double.class }; - static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" }; /** @@ -551,31 +492,35 @@ * final Object argL0; * final Object argL1; * final int argI2; - * Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) { + * private Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) { * super(mt, lf); * this.argL0 = argL0; * this.argL1 = argL1; * this.argI2 = argI2; * } * final SpeciesData speciesData() { return SPECIES_DATA; } + * final int fieldCount() { return 3; } * static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class); - * final BoundMethodHandle clone(MethodType mt, LambdaForm lf) { - * return SPECIES_DATA.constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2); + * static BoundMethodHandle make(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) { + * return new Species_LLI(mt, lf, argL0, argL1, argI2); * } - * final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) { + * return new Species_LLI(mt, lf, argL0, argL1, argI2); + * } + * final BoundMethodHandle copyWithExtendL(MethodType mt, LambdaForm lf, Object narg) { + * return SPECIES_DATA.extendWith(L_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * final BoundMethodHandle copyWithExtendI(MethodType mt, LambdaForm lf, int narg) { + * return SPECIES_DATA.extendWith(I_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * final BoundMethodHandle copyWithExtendJ(MethodType mt, LambdaForm lf, long narg) { + * return SPECIES_DATA.extendWith(J_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * final BoundMethodHandle copyWithExtendF(MethodType mt, LambdaForm lf, float narg) { + * return SPECIES_DATA.extendWith(F_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } - * final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) { - * return SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); + * public final BoundMethodHandle copyWithExtendD(MethodType mt, LambdaForm lf, double narg) { + * return SPECIES_DATA.extendWith(D_TYPE).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg); * } * } * @@ -586,8 +531,9 @@ static Class generateConcreteBMHClass(String types) { final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES); - final String className = SPECIES_PREFIX_PATH + types; - final String sourceFile = SPECIES_PREFIX_NAME + types; + String shortTypes = LambdaForm.shortenSignature(types); + final String className = SPECIES_PREFIX_PATH + shortTypes; + final String sourceFile = SPECIES_PREFIX_NAME + shortTypes; final int NOT_ACC_PUBLIC = 0; // not ACC_PUBLIC cw.visit(V1_6, NOT_ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null); cw.visitSource(sourceFile, null); @@ -606,11 +552,11 @@ MethodVisitor mv; // emit constructor - mv = cw.visitMethod(NOT_ACC_PUBLIC, "", makeSignature(types, true), null, null); + mv = cw.visitMethod(ACC_PRIVATE, "", makeSignature(types, true), null, null); mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); + mv.visitVarInsn(ALOAD, 0); // this + mv.visitVarInsn(ALOAD, 1); // type + mv.visitVarInsn(ALOAD, 2); // form mv.visitMethodInsn(INVOKESPECIAL, BMH, "", makeSignature("", true), false); @@ -647,39 +593,73 @@ mv.visitMaxs(0, 0); mv.visitEnd(); - // emit clone() - mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE); + // emit implementation of fieldCount() + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "fieldCount", INT_SIG, null, null); + mv.visitCode(); + int fc = types.length(); + if (fc <= (ICONST_5 - ICONST_0)) { + mv.visitInsn(ICONST_0 + fc); + } else { + mv.visitIntInsn(SIPUSH, fc); + } + mv.visitInsn(IRETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + // emit make() ...factory method wrapping constructor + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_STATIC, "make", makeSignature(types, false), null, null); mv.visitCode(); - // return speciesData().constructor[0].invokeBasic(mt, lf, argL0, ...) - // obtain constructor - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG); - mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG); - mv.visitInsn(ICONST_0); - mv.visitInsn(AALOAD); + // make instance + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); + // load mt, lf + mv.visitVarInsn(ALOAD, 0); // type + mv.visitVarInsn(ALOAD, 1); // form + // load factory method arguments + for (int i = 0, j = 0; i < types.length(); ++i, ++j) { + // i counts the arguments, j counts corresponding argument slots + char t = types.charAt(i); + mv.visitVarInsn(typeLoadOp(t), j + 2); // parameters start at 3 + if (t == 'J' || t == 'D') { + ++j; // adjust argument register access + } + } + + // finally, invoke the constructor and return + mv.visitMethodInsn(INVOKESPECIAL, className, "", makeSignature(types, true), false); + mv.visitInsn(ARETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + + // emit copyWith() + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWith", makeSignature("", false), null, null); + mv.visitCode(); + // make instance + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); // load mt, lf mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); // put fields on the stack emitPushFields(types, className, mv); // finally, invoke the constructor and return - mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types, false), false); + mv.visitMethodInsn(INVOKESPECIAL, className, "", makeSignature(types, true), false); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); - // for each type, emit cloneExtendT() - for (Class c : TYPES) { - char t = Wrapper.basicTypeChar(c); - mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE); + // for each type, emit copyWithExtendT() + for (BasicType type : BasicType.ARG_TYPES) { + int ord = type.ordinal(); + char btChar = type.basicTypeChar(); + mv = cw.visitMethod(NOT_ACC_PUBLIC + ACC_FINAL, "copyWithExtend" + btChar, makeSignature(String.valueOf(btChar), false), null, E_THROWABLE); mv.visitCode(); - // return SPECIES_DATA.extendWithIndex(extensionIndex(t)).constructor[0].invokeBasic(mt, lf, argL0, ..., narg) + // return SPECIES_DATA.extendWith(t).constructor[0].invokeBasic(mt, lf, argL0, ..., narg) // obtain constructor mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG); - int iconstInsn = ICONST_0 + extensionIndex(t); + int iconstInsn = ICONST_0 + ord; assert(iconstInsn <= ICONST_5); mv.visitInsn(iconstInsn); - mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWithIndex", BMHSPECIES_DATA_EWI_SIG, false); + mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWith", BMHSPECIES_DATA_EWI_SIG, false); mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG); mv.visitInsn(ICONST_0); mv.visitInsn(AALOAD); @@ -689,9 +669,9 @@ // put fields on the stack emitPushFields(types, className, mv); // put narg on stack - mv.visitVarInsn(typeLoadOp(t), 3); + mv.visitVarInsn(typeLoadOp(btChar), 3); // finally, invoke the constructor and return - mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + t, false), false); + mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + btChar, false), false); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); @@ -730,7 +710,7 @@ case 'J': return LLOAD; case 'F': return FLOAD; case 'D': return DLOAD; - default : throw new InternalError("unrecognized type " + t); + default : throw newInternalError("unrecognized type " + t); } } @@ -771,10 +751,19 @@ static MethodHandle[] makeCtors(Class cbmh, String types, MethodHandle mhs[]) { if (mhs == null) mhs = new MethodHandle[1]; + if (types.equals("")) return mhs; // hack for empty BMH species mhs[0] = makeCbmhCtor(cbmh, types); return mhs; } + static NamedFunction[] makeNominalGetters(String types, NamedFunction[] nfs, MethodHandle[] getters) { + if (nfs == null) nfs = new NamedFunction[types.length()]; + for (int i = 0; i < nfs.length; ++i) { + nfs[i] = new NamedFunction(getters[i]); + } + return nfs; + } + // // Auxiliary methods. // @@ -808,52 +797,11 @@ static MethodHandle makeCbmhCtor(Class cbmh, String types) { try { - return linkConstructor(LOOKUP.findConstructor(cbmh, MethodType.fromMethodDescriptorString(makeSignature(types, true), null))); + return LOOKUP.findStatic(cbmh, "make", MethodType.fromMethodDescriptorString(makeSignature(types, false), null)); } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) { throw newInternalError(e); } } - - /** - * Wrap a constructor call in a {@link LambdaForm}. - * - * If constructors ({@code } methods) are called in LFs, problems might arise if the LFs - * are turned into bytecode, because the call to the allocator is routed through an MH, and the - * verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to - * {@code }. To avoid this, we add an indirection by invoking {@code } through - * {@link MethodHandle#linkToSpecial}. - * - * The last {@link LambdaForm.Name Name} in the argument's form is expected to be the {@code void} - * result of the {@code } invocation. This entry is replaced. - */ - private static MethodHandle linkConstructor(MethodHandle cmh) { - final LambdaForm lf = cmh.form; - final int initNameIndex = lf.names.length - 1; - final Name initName = lf.names[initNameIndex]; - final MemberName ctorMN = initName.function.member; - final MethodType ctorMT = ctorMN.getInvocationType(); - - // obtain function member (call target) - // linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!) - final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class); - MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic); - try { - linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class); - assert(linkerMN.isStatic()); - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); - } - // extend arguments array - Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1); - newArgs[newArgs.length - 1] = ctorMN; - // replace function - final NamedFunction nf = new NamedFunction(linkerMN); - final Name linkedCtor = new Name(nf, newArgs); - linkedCtor.initIndex(initNameIndex); - lf.names[initNameIndex] = linkedCtor; - return cmh; - } - } private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP; diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java --- a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java Tue May 27 13:58:00 2014 -0700 @@ -31,6 +31,7 @@ import sun.invoke.util.VerifyAccess; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.LambdaForm.*; +import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodTypeForm.*; import static java.lang.invoke.MethodHandleStatics.*; import java.lang.ref.WeakReference; @@ -125,11 +126,6 @@ } @Override - MethodHandle copyWith(MethodType mt, LambdaForm lf) { - return new DirectMethodHandle(mt, lf, member); - } - - @Override String internalProperties() { return "/DMH="+member.toString(); } @@ -146,9 +142,9 @@ } @Override - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { // If the member needs dispatching, do so. - if (pos == 0 && basicType == 'L') { + if (pos == 0 && basicType == L_TYPE) { DirectMethodHandle concrete = maybeRebind(value); if (concrete != null) return concrete.bindReceiver(value); @@ -274,7 +270,7 @@ result = NEW_OBJ; } names[LINKER_CALL] = new Name(linker, outArgs); - lambdaName += "_" + LambdaForm.basicTypeSignature(mtype); + lambdaName += "_" + shortenSignature(basicTypeSignature(mtype)); LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result); // This is a tricky bit of code. Don't send it through the LF interpreter. lform.compileToBytecode(); diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java --- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Tue May 27 13:58:00 2014 -0700 @@ -26,7 +26,7 @@ package java.lang.invoke; import sun.invoke.util.VerifyAccess; -import java.lang.invoke.LambdaForm.Name; +import static java.lang.invoke.LambdaForm.*; import sun.invoke.util.Wrapper; @@ -38,6 +38,7 @@ import java.lang.reflect.*; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; +import static java.lang.invoke.LambdaForm.BasicType.*; import sun.invoke.util.VerifyType; /** @@ -115,7 +116,7 @@ Name[] names = form.names; for (int i = 0, index = 0; i < localsMap.length; i++) { localsMap[i] = index; - index += Wrapper.forBasicType(names[i].type).stackSlots(); + index += names[i].type.basicTypeSlots(); } } @@ -358,47 +359,52 @@ /* * NOTE: These load/store methods use the localsMap to find the correct index! */ - private void emitLoadInsn(char type, int index) { - int opcode; + private void emitLoadInsn(BasicType type, int index) { + int opcode = loadInsnOpcode(type); + mv.visitVarInsn(opcode, localsMap[index]); + } + + private int loadInsnOpcode(BasicType type) throws InternalError { switch (type) { - case 'I': opcode = Opcodes.ILOAD; break; - case 'J': opcode = Opcodes.LLOAD; break; - case 'F': opcode = Opcodes.FLOAD; break; - case 'D': opcode = Opcodes.DLOAD; break; - case 'L': opcode = Opcodes.ALOAD; break; - default: - throw new InternalError("unknown type: " + type); + case I_TYPE: return Opcodes.ILOAD; + case J_TYPE: return Opcodes.LLOAD; + case F_TYPE: return Opcodes.FLOAD; + case D_TYPE: return Opcodes.DLOAD; + case L_TYPE: return Opcodes.ALOAD; + default: + throw new InternalError("unknown type: " + type); } - mv.visitVarInsn(opcode, localsMap[index]); } private void emitAloadInsn(int index) { - emitLoadInsn('L', index); + emitLoadInsn(L_TYPE, index); + } + + private void emitStoreInsn(BasicType type, int index) { + int opcode = storeInsnOpcode(type); + mv.visitVarInsn(opcode, localsMap[index]); } - private void emitStoreInsn(char type, int index) { - int opcode; + private int storeInsnOpcode(BasicType type) throws InternalError { switch (type) { - case 'I': opcode = Opcodes.ISTORE; break; - case 'J': opcode = Opcodes.LSTORE; break; - case 'F': opcode = Opcodes.FSTORE; break; - case 'D': opcode = Opcodes.DSTORE; break; - case 'L': opcode = Opcodes.ASTORE; break; - default: - throw new InternalError("unknown type: " + type); + case I_TYPE: return Opcodes.ISTORE; + case J_TYPE: return Opcodes.LSTORE; + case F_TYPE: return Opcodes.FSTORE; + case D_TYPE: return Opcodes.DSTORE; + case L_TYPE: return Opcodes.ASTORE; + default: + throw new InternalError("unknown type: " + type); } - mv.visitVarInsn(opcode, localsMap[index]); } private void emitAstoreInsn(int index) { - emitStoreInsn('L', index); + emitStoreInsn(L_TYPE, index); } /** * Emit a boxing call. * - * @param type primitive type class to box. + * @param wrapper primitive type class to box. */ - private void emitBoxing(Class type) { - Wrapper wrapper = Wrapper.forPrimitiveType(type); + private void emitBoxing(Wrapper wrapper) { String owner = "java/lang/" + wrapper.wrapperType().getSimpleName(); String name = "valueOf"; String desc = "(" + wrapper.basicTypeChar() + ")L" + owner + ";"; @@ -408,10 +414,9 @@ /** * Emit an unboxing call (plus preceding checkcast). * - * @param type wrapper type class to unbox. + * @param wrapper wrapper type class to unbox. */ - private void emitUnboxing(Class type) { - Wrapper wrapper = Wrapper.forWrapperType(type); + private void emitUnboxing(Wrapper wrapper) { String owner = "java/lang/" + wrapper.wrapperType().getSimpleName(); String name = wrapper.primitiveSimpleName() + "Value"; String desc = "()" + wrapper.basicTypeChar(); @@ -425,9 +430,12 @@ * @param ptype type of value present on stack * @param pclass type of value required on stack */ - private void emitImplicitConversion(char ptype, Class pclass) { + private void emitImplicitConversion(BasicType ptype, Class pclass) { + assert(basicType(pclass) == ptype); // boxing/unboxing handled by caller + if (pclass == ptype.basicTypeClass() && ptype != L_TYPE) + return; // nothing to do switch (ptype) { - case 'L': + case L_TYPE: if (VerifyType.isNullConversion(Object.class, pclass)) return; if (isStaticallyNameable(pclass)) { @@ -441,18 +449,9 @@ mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY); } return; - case 'I': + case I_TYPE: if (!VerifyType.isNullConversion(int.class, pclass)) - emitPrimCast(ptype, Wrapper.basicTypeChar(pclass)); - return; - case 'J': - assert(pclass == long.class); - return; - case 'F': - assert(pclass == float.class); - return; - case 'D': - assert(pclass == double.class); + emitPrimCast(ptype.basicTypeWrapper(), Wrapper.forPrimitiveType(pclass)); return; } throw new InternalError("bad implicit conversion: tc="+ptype+": "+pclass); @@ -461,15 +460,15 @@ /** * Emits an actual return instruction conforming to the given return type. */ - private void emitReturnInsn(Class type) { + private void emitReturnInsn(BasicType type) { int opcode; - switch (Wrapper.basicTypeChar(type)) { - case 'I': opcode = Opcodes.IRETURN; break; - case 'J': opcode = Opcodes.LRETURN; break; - case 'F': opcode = Opcodes.FRETURN; break; - case 'D': opcode = Opcodes.DRETURN; break; - case 'L': opcode = Opcodes.ARETURN; break; - case 'V': opcode = Opcodes.RETURN; break; + switch (type) { + case I_TYPE: opcode = Opcodes.IRETURN; break; + case J_TYPE: opcode = Opcodes.LRETURN; break; + case F_TYPE: opcode = Opcodes.FRETURN; break; + case D_TYPE: opcode = Opcodes.DRETURN; break; + case L_TYPE: opcode = Opcodes.ARETURN; break; + case V_TYPE: opcode = Opcodes.RETURN; break; default: throw new InternalError("unknown return type: " + type); } @@ -531,7 +530,7 @@ // avoid store/load/return and just return) if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) { // return value - do nothing - } else if (name.type != 'V') { + } else if (name.type != V_TYPE) { // non-void: actually assign emitStoreInsn(name.type, name.index()); } @@ -865,20 +864,24 @@ private void emitPushArgument(Name name, int paramIndex) { Object arg = name.arguments[paramIndex]; - char ptype = name.function.parameterType(paramIndex); - MethodType mtype = name.function.methodType(); + Class ptype = name.function.methodType().parameterType(paramIndex); + emitPushArgument(ptype, arg); + } + + private void emitPushArgument(Class ptype, Object arg) { + BasicType bptype = basicType(ptype); if (arg instanceof Name) { Name n = (Name) arg; emitLoadInsn(n.type, n.index()); - emitImplicitConversion(n.type, mtype.parameterType(paramIndex)); - } else if ((arg == null || arg instanceof String) && ptype == 'L') { + emitImplicitConversion(n.type, ptype); + } else if ((arg == null || arg instanceof String) && bptype == L_TYPE) { emitConst(arg); } else { - if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') { + if (Wrapper.isWrapperType(arg.getClass()) && bptype != L_TYPE) { emitConst(arg); } else { mv.visitLdcInsn(constantPlaceholder(arg)); - emitImplicitConversion('L', mtype.parameterType(paramIndex)); + emitImplicitConversion(L_TYPE, ptype); } } } @@ -888,52 +891,33 @@ */ private void emitReturn() { // return statement - if (lambdaForm.result == -1) { + Class rclass = invokerType.returnType(); + BasicType rtype = lambdaForm.returnType(); + assert(rtype == basicType(rclass)); // must agree + if (rtype == V_TYPE) { // void mv.visitInsn(Opcodes.RETURN); + // it doesn't matter what rclass is; the JVM will discard any value } else { LambdaForm.Name rn = lambdaForm.names[lambdaForm.result]; - char rtype = Wrapper.basicTypeChar(invokerType.returnType()); // put return value on the stack if it is not already there - if (lambdaForm.result != lambdaForm.names.length - 1) { + if (lambdaForm.result != lambdaForm.names.length - 1 || + lambdaForm.result < lambdaForm.arity) { emitLoadInsn(rn.type, lambdaForm.result); } - // potentially generate cast - // rtype is the return type of the invoker - generated code must conform to this - // rn.type is the type of the result Name in the LF - if (rtype != rn.type) { - // need cast - if (rtype == 'L') { - // possibly cast the primitive to the correct type for boxing - char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar(); - if (boxedType != rn.type) { - emitPrimCast(rn.type, boxedType); - } - // cast primitive to reference ("boxing") - emitBoxing(invokerType.returnType()); - } else { - // to-primitive cast - if (rn.type != 'L') { - // prim-to-prim cast - emitPrimCast(rn.type, rtype); - } else { - // ref-to-prim cast ("unboxing") - throw new InternalError("no ref-to-prim (unboxing) casts supported right now"); - } - } - } + emitImplicitConversion(rtype, rclass); // generate actual return statement - emitReturnInsn(invokerType.returnType()); + emitReturnInsn(rtype); } } /** * Emit a type conversion bytecode casting from "from" to "to". */ - private void emitPrimCast(char from, char to) { + private void emitPrimCast(Wrapper from, Wrapper to) { // Here's how. // - indicates forbidden // <-> indicates implicit @@ -950,17 +934,15 @@ // no cast required, should be dead code anyway return; } - Wrapper wfrom = Wrapper.forBasicType(from); - Wrapper wto = Wrapper.forBasicType(to); - if (wfrom.isSubwordOrInt()) { + if (from.isSubwordOrInt()) { // cast from {byte,short,char,int} to anything emitI2X(to); } else { // cast from {long,float,double} to anything - if (wto.isSubwordOrInt()) { + if (to.isSubwordOrInt()) { // cast to {byte,short,char,int} emitX2I(from); - if (wto.bitWidth() < 32) { + if (to.bitWidth() < 32) { // targets other than int require another conversion emitI2X(to); } @@ -968,20 +950,26 @@ // cast to {long,float,double} - this is verbose boolean error = false; switch (from) { - case 'J': - if (to == 'F') { mv.visitInsn(Opcodes.L2F); } - else if (to == 'D') { mv.visitInsn(Opcodes.L2D); } - else error = true; + case LONG: + switch (to) { + case FLOAT: mv.visitInsn(Opcodes.L2F); break; + case DOUBLE: mv.visitInsn(Opcodes.L2D); break; + default: error = true; break; + } break; - case 'F': - if (to == 'J') { mv.visitInsn(Opcodes.F2L); } - else if (to == 'D') { mv.visitInsn(Opcodes.F2D); } - else error = true; + case FLOAT: + switch (to) { + case LONG : mv.visitInsn(Opcodes.F2L); break; + case DOUBLE: mv.visitInsn(Opcodes.F2D); break; + default: error = true; break; + } break; - case 'D': - if (to == 'J') { mv.visitInsn(Opcodes.D2L); } - else if (to == 'F') { mv.visitInsn(Opcodes.D2F); } - else error = true; + case DOUBLE: + switch (to) { + case LONG : mv.visitInsn(Opcodes.D2L); break; + case FLOAT: mv.visitInsn(Opcodes.D2F); break; + default: error = true; break; + } break; default: error = true; @@ -994,16 +982,16 @@ } } - private void emitI2X(char type) { + private void emitI2X(Wrapper type) { switch (type) { - case 'B': mv.visitInsn(Opcodes.I2B); break; - case 'S': mv.visitInsn(Opcodes.I2S); break; - case 'C': mv.visitInsn(Opcodes.I2C); break; - case 'I': /* naught */ break; - case 'J': mv.visitInsn(Opcodes.I2L); break; - case 'F': mv.visitInsn(Opcodes.I2F); break; - case 'D': mv.visitInsn(Opcodes.I2D); break; - case 'Z': + case BYTE: mv.visitInsn(Opcodes.I2B); break; + case SHORT: mv.visitInsn(Opcodes.I2S); break; + case CHAR: mv.visitInsn(Opcodes.I2C); break; + case INT: /* naught */ break; + case LONG: mv.visitInsn(Opcodes.I2L); break; + case FLOAT: mv.visitInsn(Opcodes.I2F); break; + case DOUBLE: mv.visitInsn(Opcodes.I2D); break; + case BOOLEAN: // For compatibility with ValueConversions and explicitCastArguments: mv.visitInsn(Opcodes.ICONST_1); mv.visitInsn(Opcodes.IAND); @@ -1012,39 +1000,24 @@ } } - private void emitX2I(char type) { + private void emitX2I(Wrapper type) { switch (type) { - case 'J': mv.visitInsn(Opcodes.L2I); break; - case 'F': mv.visitInsn(Opcodes.F2I); break; - case 'D': mv.visitInsn(Opcodes.D2I); break; - default: throw new InternalError("unknown type: " + type); + case LONG: mv.visitInsn(Opcodes.L2I); break; + case FLOAT: mv.visitInsn(Opcodes.F2I); break; + case DOUBLE: mv.visitInsn(Opcodes.D2I); break; + default: throw new InternalError("unknown type: " + type); } } - private static String basicTypeCharSignature(String prefix, MethodType type) { - StringBuilder buf = new StringBuilder(prefix); - for (Class ptype : type.parameterList()) - buf.append(Wrapper.forBasicType(ptype).basicTypeChar()); - buf.append('_').append(Wrapper.forBasicType(type.returnType()).basicTypeChar()); - return buf.toString(); - } - /** * Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments. */ static MemberName generateLambdaFormInterpreterEntryPoint(String sig) { - assert(LambdaForm.isValidSignature(sig)); - //System.out.println("generateExactInvoker "+sig); - // compute method type - // first parameter and return type - char tret = LambdaForm.signatureReturn(sig); - MethodType type = MethodType.methodType(LambdaForm.typeClass(tret), MethodHandle.class); - // other parameter types - int arity = LambdaForm.signatureArity(sig); - for (int i = 1; i < arity; i++) { - type = type.appendParameterTypes(LambdaForm.typeClass(sig.charAt(i))); - } - InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", "interpret_"+tret, type); + assert(isValidSignature(sig)); + String name = "interpret_"+signatureReturn(sig).basicTypeChar(); + MethodType type = signatureType(sig); // sig includes leading argument + type = type.changeParameterType(0, MethodHandle.class); + InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", name, type); return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes()); } @@ -1066,10 +1039,10 @@ Class ptype = invokerType.parameterType(i); mv.visitInsn(Opcodes.DUP); emitIconstInsn(i); - emitLoadInsn(Wrapper.basicTypeChar(ptype), i); + emitLoadInsn(basicType(ptype), i); // box if primitive type if (ptype.isPrimitive()) { - emitBoxing(ptype); + emitBoxing(Wrapper.forPrimitiveType(ptype)); } mv.visitInsn(Opcodes.AASTORE); } @@ -1082,11 +1055,11 @@ // maybe unbox Class rtype = invokerType.returnType(); if (rtype.isPrimitive() && rtype != void.class) { - emitUnboxing(Wrapper.asWrapperType(rtype)); + emitUnboxing(Wrapper.forPrimitiveType(rtype)); } // return statement - emitReturnInsn(rtype); + emitReturnInsn(basicType(rtype)); classFileEpilogue(); bogusMethod(invokerType); @@ -1100,14 +1073,12 @@ * Generate bytecode for a NamedFunction invoker. */ static MemberName generateNamedFunctionInvoker(MethodTypeForm typeForm) { - MethodType invokerType = LambdaForm.NamedFunction.INVOKER_METHOD_TYPE; - String invokerName = basicTypeCharSignature("invoke_", typeForm.erasedType()); + MethodType invokerType = NamedFunction.INVOKER_METHOD_TYPE; + String invokerName = "invoke_" + shortenSignature(basicTypeSignature(typeForm.erasedType())); InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("NFI", invokerName, invokerType); return g.loadMethod(g.generateNamedFunctionInvokerImpl(typeForm)); } - static int nfi = 0; - private byte[] generateNamedFunctionInvokerImpl(MethodTypeForm typeForm) { MethodType dstType = typeForm.erasedType(); classFilePrologue(); @@ -1133,8 +1104,8 @@ Class sptype = dstType.basicType().wrap().parameterType(i); Wrapper dstWrapper = Wrapper.forBasicType(dptype); Wrapper srcWrapper = dstWrapper.isSubwordOrInt() ? Wrapper.INT : dstWrapper; // narrow subword from int - emitUnboxing(srcWrapper.wrapperType()); - emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar()); + emitUnboxing(srcWrapper); + emitPrimCast(srcWrapper, dstWrapper); } } @@ -1148,15 +1119,15 @@ Wrapper srcWrapper = Wrapper.forBasicType(rtype); Wrapper dstWrapper = srcWrapper.isSubwordOrInt() ? Wrapper.INT : srcWrapper; // widen subword to int // boolean casts not allowed - emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar()); - emitBoxing(dstWrapper.primitiveType()); + emitPrimCast(srcWrapper, dstWrapper); + emitBoxing(dstWrapper); } // If the return type is void we return a null reference. if (rtype == void.class) { mv.visitInsn(Opcodes.ACONST_NULL); } - emitReturnInsn(Object.class); // NOTE: NamedFunction invokers always return a reference value. + emitReturnInsn(L_TYPE); // NOTE: NamedFunction invokers always return a reference value. classFileEpilogue(); bogusMethod(dstType); diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/LambdaForm.java --- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java Tue May 27 13:58:00 2014 -0700 @@ -30,14 +30,14 @@ import java.util.Map; import java.util.List; import java.util.Arrays; -import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; import sun.invoke.util.Wrapper; +import java.lang.reflect.Field; + +import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; -import java.lang.reflect.Field; -import java.util.Objects; /** * The symbolic, non-executable form of a method handle's invocation semantics. @@ -130,13 +130,119 @@ public static final int VOID_RESULT = -1, LAST_RESULT = -2; + enum BasicType { + L_TYPE('L', Object.class, Wrapper.OBJECT), // all reference types + I_TYPE('I', int.class, Wrapper.INT), + J_TYPE('J', long.class, Wrapper.LONG), + F_TYPE('F', float.class, Wrapper.FLOAT), + D_TYPE('D', double.class, Wrapper.DOUBLE), // all primitive types + V_TYPE('V', void.class, Wrapper.VOID); // not valid in all contexts + + static final BasicType[] ALL_TYPES = BasicType.values(); + static final BasicType[] ARG_TYPES = Arrays.copyOf(ALL_TYPES, ALL_TYPES.length-1); + + static final int ARG_TYPE_LIMIT = ARG_TYPES.length; + static final int TYPE_LIMIT = ALL_TYPES.length; + + private final char btChar; + private final Class btClass; + private final Wrapper btWrapper; + + private BasicType(char btChar, Class btClass, Wrapper wrapper) { + this.btChar = btChar; + this.btClass = btClass; + this.btWrapper = wrapper; + } + + char basicTypeChar() { + return btChar; + } + Class basicTypeClass() { + return btClass; + } + Wrapper basicTypeWrapper() { + return btWrapper; + } + int basicTypeSlots() { + return btWrapper.stackSlots(); + } + + static BasicType basicType(byte type) { + return ALL_TYPES[type]; + } + static BasicType basicType(char type) { + switch (type) { + case 'L': return L_TYPE; + case 'I': return I_TYPE; + case 'J': return J_TYPE; + case 'F': return F_TYPE; + case 'D': return D_TYPE; + case 'V': return V_TYPE; + // all subword types are represented as ints + case 'Z': + case 'B': + case 'S': + case 'C': + return I_TYPE; + default: + throw newInternalError("Unknown type char: '"+type+"'"); + } + } + static BasicType basicType(Wrapper type) { + char c = type.basicTypeChar(); + return basicType(c); + } + static BasicType basicType(Class type) { + if (!type.isPrimitive()) return L_TYPE; + return basicType(Wrapper.forPrimitiveType(type)); + } + + static char basicTypeChar(Class type) { + return basicType(type).btChar; + } + static BasicType[] basicTypes(List> types) { + BasicType[] btypes = new BasicType[types.size()]; + for (int i = 0; i < btypes.length; i++) { + btypes[i] = basicType(types.get(i)); + } + return btypes; + } + static BasicType[] basicTypes(String types) { + BasicType[] btypes = new BasicType[types.length()]; + for (int i = 0; i < btypes.length; i++) { + btypes[i] = basicType(types.charAt(i)); + } + return btypes; + } + static boolean isBasicTypeChar(char c) { + return "LIJFDV".indexOf(c) >= 0; + } + static boolean isArgBasicTypeChar(char c) { + return "LIJFD".indexOf(c) >= 0; + } + + static { assert(checkBasicType()); } + private static boolean checkBasicType() { + for (int i = 0; i < ARG_TYPE_LIMIT; i++) { + assert ARG_TYPES[i].ordinal() == i; + assert ARG_TYPES[i] == ALL_TYPES[i]; + } + for (int i = 0; i < TYPE_LIMIT; i++) { + assert ALL_TYPES[i].ordinal() == i; + } + assert ALL_TYPES[TYPE_LIMIT - 1] == V_TYPE; + assert !Arrays.asList(ARG_TYPES).contains(V_TYPE); + return true; + } + } + LambdaForm(String debugName, int arity, Name[] names, int result) { assert(namesOK(arity, names)); this.arity = arity; this.result = fixResult(result, names); this.names = names.clone(); - this.debugName = debugName; + this.debugName = fixDebugName(debugName); normalize(); } @@ -168,12 +274,12 @@ // Called only from getPreparedForm. assert(isValidSignature(sig)); this.arity = signatureArity(sig); - this.result = (signatureReturn(sig) == 'V' ? -1 : arity); + this.result = (signatureReturn(sig) == V_TYPE ? -1 : arity); this.names = buildEmptyNames(arity, sig); this.debugName = "LF.zero"; assert(nameRefsAreLegal()); assert(isEmpty()); - assert(sig.equals(basicTypeSignature())); + assert(sig.equals(basicTypeSignature())) : sig + " != " + basicTypeSignature(); } private static Name[] buildEmptyNames(int arity, String basicTypeSignature) { @@ -181,22 +287,53 @@ int resultPos = arity + 1; // skip '_' if (arity < 0 || basicTypeSignature.length() != resultPos+1) throw new IllegalArgumentException("bad arity for "+basicTypeSignature); - int numRes = (basicTypeSignature.charAt(resultPos) == 'V' ? 0 : 1); + int numRes = (basicType(basicTypeSignature.charAt(resultPos)) == V_TYPE ? 0 : 1); Name[] names = arguments(numRes, basicTypeSignature.substring(0, arity)); for (int i = 0; i < numRes; i++) { - names[arity + i] = constantZero(arity + i, basicTypeSignature.charAt(resultPos + i)); + Name zero = new Name(constantZero(basicType(basicTypeSignature.charAt(resultPos + i)))); + names[arity + i] = zero.newIndex(arity + i); } return names; } private static int fixResult(int result, Name[] names) { - if (result >= 0) { - if (names[result].type == 'V') - return -1; - } else if (result == LAST_RESULT) { - return names.length - 1; + if (result == LAST_RESULT) + result = names.length - 1; // might still be void + if (result >= 0 && names[result].type == V_TYPE) + result = VOID_RESULT; + return result; + } + + private static String fixDebugName(String debugName) { + if (DEBUG_NAME_COUNTERS != null) { + int under = debugName.indexOf('_'); + int length = debugName.length(); + if (under < 0) under = length; + String debugNameStem = debugName.substring(0, under); + Integer ctr; + synchronized (DEBUG_NAME_COUNTERS) { + ctr = DEBUG_NAME_COUNTERS.get(debugNameStem); + if (ctr == null) ctr = 0; + DEBUG_NAME_COUNTERS.put(debugNameStem, ctr+1); + } + StringBuilder buf = new StringBuilder(debugNameStem); + buf.append('_'); + int leadingZero = buf.length(); + buf.append((int) ctr); + for (int i = buf.length() - leadingZero; i < 3; i++) + buf.insert(leadingZero, '0'); + if (under < length) { + ++under; // skip "_" + while (under < length && Character.isDigit(debugName.charAt(under))) { + ++under; + } + if (under < length && debugName.charAt(under) == '_') ++under; + if (under < length) + buf.append('_').append(debugName, under, length); + } + return buf.toString(); } - return result; + return debugName; } private static boolean namesOK(int arity, Name[] names) { @@ -294,14 +431,14 @@ // } /** Report the return type. */ - char returnType() { - if (result < 0) return 'V'; + BasicType returnType() { + if (result < 0) return V_TYPE; Name n = names[result]; return n.type; } /** Report the N-th argument type. */ - char parameterType(int n) { + BasicType parameterType(int n) { assert(n < arity); return names[n].type; } @@ -319,15 +456,15 @@ final String basicTypeSignature() { StringBuilder buf = new StringBuilder(arity() + 3); for (int i = 0, a = arity(); i < a; i++) - buf.append(parameterType(i)); - return buf.append('_').append(returnType()).toString(); + buf.append(parameterType(i).basicTypeChar()); + return buf.append('_').append(returnType().basicTypeChar()).toString(); } static int signatureArity(String sig) { assert(isValidSignature(sig)); return sig.indexOf('_'); } - static char signatureReturn(String sig) { - return sig.charAt(signatureArity(sig)+1); + static BasicType signatureReturn(String sig) { + return basicType(sig.charAt(signatureArity(sig)+1)); } static boolean isValidSignature(String sig) { int arity = sig.indexOf('_'); @@ -339,27 +476,15 @@ char c = sig.charAt(i); if (c == 'V') return (i == siglen - 1 && arity == siglen - 2); - if (ALL_TYPES.indexOf(c) < 0) return false; // must be [LIJFD] + if (!isArgBasicTypeChar(c)) return false; // must be [LIJFD] } return true; // [LIJFD]*_[LIJFDV] } - static Class typeClass(char t) { - switch (t) { - case 'I': return int.class; - case 'J': return long.class; - case 'F': return float.class; - case 'D': return double.class; - case 'L': return Object.class; - case 'V': return void.class; - default: assert false; - } - return null; - } static MethodType signatureType(String sig) { Class[] ptypes = new Class[signatureArity(sig)]; for (int i = 0; i < ptypes.length; i++) - ptypes[i] = typeClass(sig.charAt(i)); - Class rtype = typeClass(signatureReturn(sig)); + ptypes[i] = basicType(sig.charAt(i)).btClass; + Class rtype = signatureReturn(sig).btClass; return MethodType.methodType(rtype, ptypes); } @@ -543,21 +668,21 @@ assert(mt.parameterCount() == arity-1); for (int i = 0; i < av.length; i++) { Class pt = (i == 0 ? MethodHandle.class : mt.parameterType(i-1)); - assert(valueMatches(sig.charAt(i), pt, av[i])); + assert(valueMatches(basicType(sig.charAt(i)), pt, av[i])); } return true; } - private static boolean valueMatches(char tc, Class type, Object x) { + private static boolean valueMatches(BasicType tc, Class type, Object x) { // The following line is needed because (...)void method handles can use non-void invokers - if (type == void.class) tc = 'V'; // can drop any kind of value + if (type == void.class) tc = V_TYPE; // can drop any kind of value assert tc == basicType(type) : tc + " == basicType(" + type + ")=" + basicType(type); switch (tc) { - case 'I': assert checkInt(type, x) : "checkInt(" + type + "," + x +")"; break; - case 'J': assert x instanceof Long : "instanceof Long: " + x; break; - case 'F': assert x instanceof Float : "instanceof Float: " + x; break; - case 'D': assert x instanceof Double : "instanceof Double: " + x; break; - case 'L': assert checkRef(type, x) : "checkRef(" + type + "," + x + ")"; break; - case 'V': break; // allow anything here; will be dropped + case I_TYPE: assert checkInt(type, x) : "checkInt(" + type + "," + x +")"; break; + case J_TYPE: assert x instanceof Long : "instanceof Long: " + x; break; + case F_TYPE: assert x instanceof Float : "instanceof Float: " + x; break; + case D_TYPE: assert x instanceof Double : "instanceof Double: " + x; break; + case L_TYPE: assert checkRef(type, x) : "checkRef(" + type + "," + x + ")"; break; + case V_TYPE: break; // allow anything here; will be dropped default: assert(false); } return true; @@ -736,7 +861,7 @@ * The first parameter to a LambdaForm, a0:L, always represents the form's method handle, so 0 is not * accepted as valid. */ - LambdaForm bindImmediate(int pos, char basicType, Object value) { + LambdaForm bindImmediate(int pos, BasicType basicType, Object value) { // must be an argument, and the types must match assert pos > 0 && pos < arity && names[pos].type == basicType && Name.typesMatch(basicType, value); @@ -782,8 +907,8 @@ LambdaForm bind(int namePos, BoundMethodHandle.SpeciesData oldData) { Name name = names[namePos]; - BoundMethodHandle.SpeciesData newData = oldData.extendWithType(name.type); - return bind(name, newData.getterName(names[0], oldData.fieldCount()), oldData, newData); + BoundMethodHandle.SpeciesData newData = oldData.extendWith(name.type); + return bind(name, new Name(newData.getterFunction(oldData.fieldCount()), names[0]), oldData, newData); } LambdaForm bind(Name name, Name binding, BoundMethodHandle.SpeciesData oldData, @@ -874,7 +999,7 @@ return false; } - LambdaForm addArguments(int pos, char... types) { + LambdaForm addArguments(int pos, BasicType... types) { assert(pos <= arity); int length = names.length; int inTypes = types.length; @@ -895,13 +1020,10 @@ } LambdaForm addArguments(int pos, List> types) { - char[] basicTypes = new char[types.size()]; - for (int i = 0; i < basicTypes.length; i++) - basicTypes[i] = basicType(types.get(i)); - return addArguments(pos, basicTypes); + return addArguments(pos, basicTypes(types)); } - LambdaForm permuteArguments(int skip, int[] reorder, char[] types) { + LambdaForm permuteArguments(int skip, int[] reorder, BasicType[] types) { // Note: When inArg = reorder[outArg], outArg is fed by a copy of inArg. // The types are the types of the new (incoming) arguments. int length = names.length; @@ -960,7 +1082,7 @@ return new LambdaForm(debugName, arity2, names2, result2); } - static boolean permutedTypesMatch(int[] reorder, char[] types, Name[] names, int skip) { + static boolean permutedTypesMatch(int[] reorder, BasicType[] types, Name[] names, int skip) { int inTypes = types.length; int outArgs = reorder.length; for (int i = 0; i < outArgs; i++) { @@ -1044,7 +1166,7 @@ String sig = m.getName().substring("invoke_".length()); int arity = LambdaForm.signatureArity(sig); MethodType srcType = MethodType.genericMethodType(arity); - if (LambdaForm.signatureReturn(sig) == 'V') + if (LambdaForm.signatureReturn(sig) == V_TYPE) srcType = srcType.changeReturnType(void.class); MethodTypeForm typeForm = srcType.form(); typeForm.namedFunctionInvoker = DirectMethodHandle.make(m); @@ -1134,7 +1256,7 @@ MethodHandle mh2 = typeForm.namedFunctionInvoker; if (mh2 != null) return mh2; // benign race if (!mh.type().equals(INVOKER_METHOD_TYPE)) - throw new InternalError(mh.debugString()); + throw newInternalError(mh.debugString()); return typeForm.namedFunctionInvoker = mh; } @@ -1193,11 +1315,6 @@ return true; } - String basicTypeSignature() { - //return LambdaForm.basicTypeSignature(resolvedHandle.type()); - return LambdaForm.basicTypeSignature(methodType()); - } - MethodType methodType() { if (resolvedHandle != null) return resolvedHandle.type(); @@ -1224,18 +1341,15 @@ return (member == null) ? null : member.getDeclaringClass(); } - char returnType() { + BasicType returnType() { return basicType(methodType().returnType()); } - char parameterType(int n) { + BasicType parameterType(int n) { return basicType(methodType().parameterType(n)); } int arity() { - //int siglen = member.getMethodType().parameterCount(); - //if (!member.isStatic()) siglen += 1; - //return siglen; return methodType().parameterCount(); } @@ -1243,44 +1357,63 @@ if (member == null) return String.valueOf(resolvedHandle); return member.getDeclaringClass().getSimpleName()+"."+member.getName(); } - } - void resolve() { - for (Name n : names) n.resolve(); + public boolean isIdentity() { + return this.equals(identity(returnType())); + } + + public boolean isConstantZero() { + return this.equals(constantZero(returnType())); + } } - public static char basicType(Class type) { - char c = Wrapper.basicTypeChar(type); - if ("ZBSC".indexOf(c) >= 0) c = 'I'; - assert("LIJFDV".indexOf(c) >= 0); - return c; - } - public static char[] basicTypes(List> types) { - char[] btypes = new char[types.size()]; - for (int i = 0; i < btypes.length; i++) { - btypes[i] = basicType(types.get(i)); - } - return btypes; - } public static String basicTypeSignature(MethodType type) { char[] sig = new char[type.parameterCount() + 2]; int sigp = 0; for (Class pt : type.parameterList()) { - sig[sigp++] = basicType(pt); + sig[sigp++] = basicTypeChar(pt); } sig[sigp++] = '_'; - sig[sigp++] = basicType(type.returnType()); + sig[sigp++] = basicTypeChar(type.returnType()); assert(sigp == sig.length); return String.valueOf(sig); } + public static String shortenSignature(String signature) { + // Hack to make signatures more readable when they show up in method names. + final int NO_CHAR = -1, MIN_RUN = 3; + int c0, c1 = NO_CHAR, c1reps = 0; + StringBuilder buf = null; + int len = signature.length(); + if (len < MIN_RUN) return signature; + for (int i = 0; i <= len; i++) { + // shift in the next char: + c0 = c1; c1 = (i == len ? NO_CHAR : signature.charAt(i)); + if (c1 == c0) { ++c1reps; continue; } + // shift in the next count: + int c0reps = c1reps; c1reps = 1; + // end of a character run + if (c0reps < MIN_RUN) { + if (buf != null) { + while (--c0reps >= 0) + buf.append((char)c0); + } + continue; + } + // found three or more in a row + if (buf == null) + buf = new StringBuilder().append(signature, 0, i - c0reps); + buf.append((char)c0).append(c0reps); + } + return (buf == null) ? signature : buf.toString(); + } static final class Name { - final char type; + final BasicType type; private short index; final NamedFunction function; @Stable final Object[] arguments; - private Name(int index, char type, NamedFunction function, Object[] arguments) { + private Name(int index, BasicType type, NamedFunction function, Object[] arguments) { this.index = (short)index; this.type = type; this.function = function; @@ -1292,7 +1425,7 @@ } Name(MethodType functionType, Object... arguments) { this(new NamedFunction(functionType), arguments); - assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == 'L'); + assert(arguments[0] instanceof Name && ((Name)arguments[0]).type == L_TYPE); } Name(MemberName function, Object... arguments) { this(new NamedFunction(function), arguments); @@ -1303,14 +1436,14 @@ for (int i = 0; i < arguments.length; i++) assert(typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString(); } - Name(int index, char type) { + /** Create a raw parameter of the given type, with an expected index. */ + Name(int index, BasicType type) { this(index, type, null, null); } - Name(char type) { - this(-1, type); - } + /** Create a raw parameter of the given type. */ + Name(BasicType type) { this(-1, type); } - char type() { return type; } + BasicType type() { return type; } int index() { return index; } boolean initIndex(int i) { if (index != i) { @@ -1319,7 +1452,9 @@ } return true; } - + char typeChar() { + return type.btChar; + } void resolve() { if (function != null) @@ -1397,18 +1532,18 @@ return function == null; } boolean isConstantZero() { - return !isParam() && arguments.length == 0 && function.equals(constantZero(0, type).function); + return !isParam() && arguments.length == 0 && function.isConstantZero(); } public String toString() { - return (isParam()?"a":"t")+(index >= 0 ? index : System.identityHashCode(this))+":"+type; + return (isParam()?"a":"t")+(index >= 0 ? index : System.identityHashCode(this))+":"+typeChar(); } public String debugString() { String s = toString(); return (function == null) ? s : s + "=" + exprString(); } public String exprString() { - if (function == null) return "null"; + if (function == null) return toString(); StringBuilder buf = new StringBuilder(function.toString()); buf.append("("); String cma = ""; @@ -1423,17 +1558,17 @@ return buf.toString(); } - private static boolean typesMatch(char parameterType, Object object) { + static boolean typesMatch(BasicType parameterType, Object object) { if (object instanceof Name) { return ((Name)object).type == parameterType; } switch (parameterType) { - case 'I': return object instanceof Integer; - case 'J': return object instanceof Long; - case 'F': return object instanceof Float; - case 'D': return object instanceof Double; + case I_TYPE: return object instanceof Integer; + case J_TYPE: return object instanceof Long; + case F_TYPE: return object instanceof Float; + case D_TYPE: return object instanceof Double; } - assert(parameterType == 'L'); + assert(parameterType == L_TYPE); return true; } @@ -1510,7 +1645,7 @@ @Override public int hashCode() { if (isParam()) - return index | (type << 8); + return index | (type.ordinal() << 8); return function.hashCode() ^ Arrays.hashCode(arguments); } } @@ -1545,10 +1680,12 @@ } static Name argument(int which, char type) { - int tn = ALL_TYPES.indexOf(type); - if (tn < 0 || which >= INTERNED_ARGUMENT_LIMIT) + return argument(which, basicType(type)); + } + static Name argument(int which, BasicType type) { + if (which >= INTERNED_ARGUMENT_LIMIT) return new Name(which, type); - return INTERNED_ARGUMENTS[tn][which]; + return INTERNED_ARGUMENTS[type.ordinal()][which]; } static Name internArgument(Name n) { assert(n.isParam()) : "not param: " + n; @@ -1590,56 +1727,118 @@ names[i] = argument(i, basicType(types.parameterType(i))); return names; } - static final String ALL_TYPES = "LIJFD"; // omit V, not an argument type static final int INTERNED_ARGUMENT_LIMIT = 10; private static final Name[][] INTERNED_ARGUMENTS - = new Name[ALL_TYPES.length()][INTERNED_ARGUMENT_LIMIT]; + = new Name[ARG_TYPE_LIMIT][INTERNED_ARGUMENT_LIMIT]; static { - for (int tn = 0; tn < ALL_TYPES.length(); tn++) { - for (int i = 0; i < INTERNED_ARGUMENTS[tn].length; i++) { - char type = ALL_TYPES.charAt(tn); - INTERNED_ARGUMENTS[tn][i] = new Name(i, type); + for (BasicType type : BasicType.ARG_TYPES) { + int ord = type.ordinal(); + for (int i = 0; i < INTERNED_ARGUMENTS[ord].length; i++) { + INTERNED_ARGUMENTS[ord][i] = new Name(i, type); } } } private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory(); - static Name constantZero(int which, char type) { - return CONSTANT_ZERO[ALL_TYPES.indexOf(type)].newIndex(which); + static LambdaForm identityForm(BasicType type) { + return LF_identityForm[type.ordinal()]; + } + static LambdaForm zeroForm(BasicType type) { + return LF_zeroForm[type.ordinal()]; + } + static NamedFunction identity(BasicType type) { + return NF_identity[type.ordinal()]; + } + static NamedFunction constantZero(BasicType type) { + return NF_zero[type.ordinal()]; } - private static final Name[] CONSTANT_ZERO - = new Name[ALL_TYPES.length()]; - static { - for (int tn = 0; tn < ALL_TYPES.length(); tn++) { - char bt = ALL_TYPES.charAt(tn); - Wrapper wrap = Wrapper.forBasicType(bt); - MemberName zmem = new MemberName(LambdaForm.class, "zero"+bt, MethodType.methodType(wrap.primitiveType()), REF_invokeStatic); + private static final LambdaForm[] LF_identityForm = new LambdaForm[TYPE_LIMIT]; + private static final LambdaForm[] LF_zeroForm = new LambdaForm[TYPE_LIMIT]; + private static final NamedFunction[] NF_identity = new NamedFunction[TYPE_LIMIT]; + private static final NamedFunction[] NF_zero = new NamedFunction[TYPE_LIMIT]; + private static void createIdentityForms() { + for (BasicType type : BasicType.ALL_TYPES) { + int ord = type.ordinal(); + char btChar = type.basicTypeChar(); + boolean isVoid = (type == V_TYPE); + Class btClass = type.btClass; + MethodType zeType = MethodType.methodType(btClass); + MethodType idType = isVoid ? zeType : zeType.appendParameterTypes(btClass); + + // Look up some symbolic names. It might not be necessary to have these, + // but if we need to emit direct references to bytecodes, it helps. + // Zero is built from a call to an identity function with a constant zero input. + MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic); + MemberName zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic); try { - zmem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zmem, null, NoSuchMethodException.class); + zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, NoSuchMethodException.class); + idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, NoSuchMethodException.class); } catch (IllegalAccessException|NoSuchMethodException ex) { throw newInternalError(ex); } - NamedFunction zcon = new NamedFunction(zmem); - Name n = new Name(zcon).newIndex(0); - assert(n.type == ALL_TYPES.charAt(tn)); - CONSTANT_ZERO[tn] = n; - assert(n.isConstantZero()); + + NamedFunction idFun = new NamedFunction(idMem); + LambdaForm idForm; + if (isVoid) { + Name[] idNames = new Name[] { argument(0, L_TYPE) }; + idForm = new LambdaForm(idMem.getName(), 1, idNames, VOID_RESULT); + } else { + Name[] idNames = new Name[] { argument(0, L_TYPE), argument(1, type) }; + idForm = new LambdaForm(idMem.getName(), 2, idNames, 1); + } + LF_identityForm[ord] = idForm; + NF_identity[ord] = idFun; + + NamedFunction zeFun = new NamedFunction(zeMem); + LambdaForm zeForm; + if (isVoid) { + zeForm = idForm; + } else { + Object zeValue = Wrapper.forBasicType(btChar).zero(); + Name[] zeNames = new Name[] { argument(0, L_TYPE), new Name(idFun, zeValue) }; + zeForm = new LambdaForm(zeMem.getName(), 1, zeNames, 1); + } + LF_zeroForm[ord] = zeForm; + NF_zero[ord] = zeFun; + + assert(idFun.isIdentity()); + assert(zeFun.isConstantZero()); + assert(new Name(zeFun).isConstantZero()); + } + + // Do this in a separate pass, so that SimpleMethodHandle.make can see the tables. + for (BasicType type : BasicType.ALL_TYPES) { + int ord = type.ordinal(); + NamedFunction idFun = NF_identity[ord]; + LambdaForm idForm = LF_identityForm[ord]; + MemberName idMem = idFun.member; + idFun.resolvedHandle = SimpleMethodHandle.make(idMem.getInvocationType(), idForm); + + NamedFunction zeFun = NF_zero[ord]; + LambdaForm zeForm = LF_zeroForm[ord]; + MemberName zeMem = zeFun.member; + zeFun.resolvedHandle = SimpleMethodHandle.make(zeMem.getInvocationType(), zeForm); + + assert(idFun.isIdentity()); + assert(zeFun.isConstantZero()); + assert(new Name(zeFun).isConstantZero()); } } // Avoid appealing to ValueConversions at bootstrap time: - private static int zeroI() { return 0; } - private static long zeroJ() { return 0; } - private static float zeroF() { return 0; } - private static double zeroD() { return 0; } - private static Object zeroL() { return null; } - - // Put this last, so that previous static inits can run before. - static { - if (USE_PREDEFINED_INTERPRET_METHODS) - PREPARED_FORMS.putAll(computeInitialPreparedForms()); - } + private static int identity_I(int x) { return x; } + private static long identity_J(long x) { return x; } + private static float identity_F(float x) { return x; } + private static double identity_D(double x) { return x; } + private static Object identity_L(Object x) { return x; } + private static void identity_V() { return; } // same as zeroV, but that's OK + private static int zero_I() { return 0; } + private static long zero_J() { return 0; } + private static float zero_F() { return 0; } + private static double zero_D() { return 0; } + private static Object zero_L() { return null; } + private static void zero_V() { return; } /** * Internal marker for byte-compiled LambdaForms. @@ -1690,7 +1889,21 @@ static final native Object linkToInterface(Object x1, MemberName mn) throws Throwable; */ - static { NamedFunction.initializeInvokers(); } + private static final HashMap DEBUG_NAME_COUNTERS; + static { + if (debugEnabled()) + DEBUG_NAME_COUNTERS = new HashMap<>(); + else + DEBUG_NAME_COUNTERS = null; + } + + // Put this last, so that previous static inits can run before. + static { + createIdentityForms(); + if (USE_PREDEFINED_INTERPRET_METHODS) + PREPARED_FORMS.putAll(computeInitialPreparedForms()); + NamedFunction.initializeInvokers(); + } // The following hack is necessary in order to suppress TRACE_INTERPRETER // during execution of the static initializes of this class. diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/MethodHandle.java --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java Tue May 27 13:58:00 2014 -0700 @@ -27,10 +27,12 @@ import java.util.*; +import java.lang.invoke.LambdaForm.BasicType; import sun.invoke.util.*; import sun.misc.Unsafe; import static java.lang.invoke.MethodHandleStatics.*; +import static java.lang.invoke.LambdaForm.BasicType.*; /** * A method handle is a typed, directly executable reference to an underlying method, @@ -729,7 +731,7 @@ *
  • If the return type T0 is void and T1 a primitive, * a zero value is introduced. * - * (Note: Both T0 and T1 may be regarded as static types, + * (Note: Both T0 and T1 may be regarded as static types, * because neither corresponds specifically to the dynamic type of any * actual argument or return value.) *

    @@ -1374,7 +1376,7 @@ } /*non-public*/ - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { // Override this if it can be improved. return rebind().bindArgument(pos, basicType, value); } @@ -1382,26 +1384,7 @@ /*non-public*/ MethodHandle bindReceiver(Object receiver) { // Override this if it can be improved. - return bindArgument(0, 'L', receiver); - } - - /*non-public*/ - MethodHandle bindImmediate(int pos, char basicType, Object value) { - // Bind an immediate value to a position in the arguments. - // This means, elide the respective argument, - // and replace all references to it in NamedFunction args with the specified value. - - // CURRENT RESTRICTIONS - // * only for pos 0 and UNSAFE (position is adjusted in MHImpl to make API usable for others) - assert pos == 0 && basicType == 'L' && value instanceof Unsafe; - MethodType type2 = type.dropParameterTypes(pos, pos + 1); // adjustment: ignore receiver! - LambdaForm form2 = form.bindImmediate(pos + 1, basicType, value); // adjust pos to form-relative pos - return copyWith(type2, form2); - } - - /*non-public*/ - MethodHandle copyWith(MethodType mt, LambdaForm lf) { - throw new InternalError("copyWith: " + this.getClass()); + return bindArgument(0, L_TYPE, receiver); } /*non-public*/ diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Tue May 27 13:58:00 2014 -0700 @@ -412,7 +412,7 @@ @Override - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { return asFixedArity().bindArgument(pos, basicType, value); } diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java Tue May 27 13:58:00 2014 -0700 @@ -78,7 +78,7 @@ // The JVM calls MethodHandleNatives.. Cascade the calls as needed: MethodHandleImpl.initStatics(); -} + } // All compile-time constants go here. // There is an opportunity to check them against the JVM's idea of them. @@ -293,6 +293,17 @@ Class caller = (Class)callerObj; String name = nameObj.toString().intern(); MethodType type = (MethodType)typeObj; + if (!TRACE_METHOD_LINKAGE) + return linkCallSiteImpl(caller, bootstrapMethod, name, type, + staticArguments, appendixResult); + return linkCallSiteTracing(caller, bootstrapMethod, name, type, + staticArguments, appendixResult); + } + static MemberName linkCallSiteImpl(Class caller, + MethodHandle bootstrapMethod, + String name, MethodType type, + Object staticArguments, + Object[] appendixResult) { CallSite callSite = CallSite.makeSite(bootstrapMethod, name, type, @@ -306,6 +317,30 @@ return Invokers.linkToCallSiteMethod(type); } } + // Tracing logic: + static MemberName linkCallSiteTracing(Class caller, + MethodHandle bootstrapMethod, + String name, MethodType type, + Object staticArguments, + Object[] appendixResult) { + Object bsmReference = bootstrapMethod.internalMemberName(); + if (bsmReference == null) bsmReference = bootstrapMethod; + Object staticArglist = (staticArguments instanceof Object[] ? + java.util.Arrays.asList((Object[]) staticArguments) : + staticArguments); + System.out.println("linkCallSite "+caller.getName()+" "+ + bsmReference+" "+ + name+type+"/"+staticArglist); + try { + MemberName res = linkCallSiteImpl(caller, bootstrapMethod, name, type, + staticArguments, appendixResult); + System.out.println("linkCallSite => "+res+" + "+appendixResult[0]); + return res; + } catch (Throwable ex) { + System.out.println("linkCallSite => throw "+ex); + throw ex; + } + } /** * The JVM wants a pointer to a MethodType. Oblige it by finding or creating one. diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java Tue May 27 13:58:00 2014 -0700 @@ -65,6 +65,16 @@ COMPILE_THRESHOLD = (Integer) values[4]; } + /** Tell if any of the debugging switches are turned on. + * If this is the case, it is reasonable to perform extra checks or save extra information. + */ + /*non-public*/ static boolean debugEnabled() { + return (DEBUG_METHOD_HANDLE_NAMES | + DUMP_CLASS_FILES | + TRACE_INTERPRETER | + TRACE_METHOD_LINKAGE); + } + /*non-public*/ static String getNameString(MethodHandle target, MethodType type) { if (type == null) type = target.type(); @@ -93,6 +103,9 @@ } // handy shared exception makers (they simplify the common case code) + /*non-public*/ static InternalError newInternalError(String message) { + return new InternalError(message); + } /*non-public*/ static InternalError newInternalError(String message, Throwable cause) { return new InternalError(message, cause); } diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/MethodHandles.java --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java Tue May 27 13:58:00 2014 -0700 @@ -37,10 +37,11 @@ import sun.reflect.Reflection; import sun.reflect.misc.ReflectUtil; import sun.security.util.SecurityConstants; +import java.lang.invoke.LambdaForm.BasicType; +import static java.lang.invoke.LambdaForm.BasicType.*; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleNatives.Constants.*; import java.util.concurrent.ConcurrentHashMap; -import sun.security.util.SecurityConstants; /** * This class consists exclusively of static methods that operate on or return @@ -2189,12 +2190,12 @@ Object value = values[i]; Class ptype = oldType.parameterType(pos+i); if (ptype.isPrimitive()) { - char btype = 'I'; + BasicType btype = I_TYPE; Wrapper w = Wrapper.forPrimitiveType(ptype); switch (w) { - case LONG: btype = 'J'; break; - case FLOAT: btype = 'F'; break; - case DOUBLE: btype = 'D'; break; + case LONG: btype = J_TYPE; break; + case FLOAT: btype = F_TYPE; break; + case DOUBLE: btype = D_TYPE; break; } // perform unboxing and/or primitive conversion value = w.convert(value, ptype); @@ -2205,7 +2206,7 @@ if (pos == 0) { result = result.bindReceiver(value); } else { - result = result.bindArgument(pos, 'L', value); + result = result.bindArgument(pos, L_TYPE, value); } } return result; diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java --- a/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java Tue May 27 13:58:00 2014 -0700 @@ -26,7 +26,7 @@ package java.lang.invoke; import static java.lang.invoke.LambdaForm.*; -import static java.lang.invoke.MethodHandleNatives.Constants.*; +import static java.lang.invoke.LambdaForm.BasicType.*; /** * A method handle whose behavior is determined only by its LambdaForm. @@ -42,7 +42,7 @@ } @Override - MethodHandle bindArgument(int pos, char basicType, Object value) { + MethodHandle bindArgument(int pos, BasicType basicType, Object value) { MethodType type2 = type().dropParameterTypes(pos, pos+1); LambdaForm form2 = internalForm().bind(1+pos, BoundMethodHandle.SpeciesData.EMPTY); return BoundMethodHandle.bindSingle(type2, form2, basicType, value); @@ -59,10 +59,4 @@ LambdaForm form2 = internalForm().permuteArguments(1, reorder, basicTypes(newType.parameterList())); return new SimpleMethodHandle(newType, form2); } - - @Override - MethodHandle copyWith(MethodType mt, LambdaForm lf) { - return new SimpleMethodHandle(mt, lf); - } - } diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/sun/security/provider/DigestBase.java --- a/jdk/src/share/classes/sun/security/provider/DigestBase.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/sun/security/provider/DigestBase.java Tue May 27 13:58:00 2014 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2014, 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 @@ -122,10 +122,10 @@ } } // compress complete blocks - while (len >= blockSize) { - implCompress(b, ofs); - len -= blockSize; - ofs += blockSize; + if (len >= blockSize) { + int limit = ofs + len; + ofs = implCompressMultiBlock(b, ofs, limit - blockSize); + len = limit - ofs; } // copy remainder to buffer if (len > 0) { @@ -134,6 +134,14 @@ } } + // compress complete blocks + private int implCompressMultiBlock(byte[] b, int ofs, int limit) { + for (; ofs <= limit; ofs += blockSize) { + implCompress(b, ofs); + } + return ofs; + } + // reset this object. See JCA doc. protected final void engineReset() { if (bytesProcessed == 0) { diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/share/classes/sun/tools/jinfo/JInfo.java --- a/jdk/src/share/classes/sun/tools/jinfo/JInfo.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/share/classes/sun/tools/jinfo/JInfo.java Tue May 27 13:58:00 2014 -0700 @@ -158,6 +158,8 @@ sysprops(pid); System.out.println(); flags(pid); + System.out.println(); + commandLine(pid); } else { usage(1); } @@ -248,6 +250,12 @@ drain(vm, in); } + private static void commandLine(String pid) throws IOException { + HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid); + InputStream in = vm.executeJCmd("VM.command_line"); + drain(vm, in); + } + private static void sysprops(String pid) throws IOException { HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid); InputStream in = vm.executeJCmd("VM.system_properties"); diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/solaris/classes/java/lang/UNIXProcess.java --- a/jdk/src/solaris/classes/java/lang/UNIXProcess.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/solaris/classes/java/lang/UNIXProcess.java Tue May 27 13:58:00 2014 -0700 @@ -483,6 +483,11 @@ } @Override + public long getPid() { + return pid; + } + + @Override public synchronized boolean isAlive() { return !hasExited; } diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c --- a/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/solaris/native/sun/nio/ch/FileChannelImpl.c Tue May 27 13:58:00 2014 -0700 @@ -39,6 +39,8 @@ #if defined(__linux__) || defined(__solaris__) #include +#elif defined(_AIX) +#include #elif defined(_ALLBSD_SOURCE) #include #include @@ -207,9 +209,7 @@ numBytes = count; -#ifdef __APPLE__ result = sendfile(srcFD, dstFD, position, &numBytes, NULL, 0); -#endif if (numBytes > 0) return numBytes; @@ -228,7 +228,48 @@ } return result; + +#elif defined(_AIX) + jlong max = (jlong)java_lang_Integer_MAX_VALUE; + struct sf_parms sf_iobuf; + jlong result; + + if (position > max) + return IOS_UNSUPPORTED_CASE; + + if (count > max) + count = max; + + memset(&sf_iobuf, 0, sizeof(sf_iobuf)); + sf_iobuf.file_descriptor = srcFD; + sf_iobuf.file_offset = (off_t)position; + sf_iobuf.file_bytes = count; + + result = send_file(&dstFD, &sf_iobuf, SF_SYNC_CACHE); + + /* AIX send_file() will return 0 when this operation complete successfully, + * return 1 when partial bytes transfered and return -1 when an error has + * Occured. + */ + if (result == -1) { + if (errno == EWOULDBLOCK) + return IOS_UNAVAILABLE; + if ((errno == EINVAL) && ((ssize_t)count >= 0)) + return IOS_UNSUPPORTED_CASE; + if (errno == EINTR) + return IOS_INTERRUPTED; + if (errno == ENOTSOCK) + return IOS_UNSUPPORTED; + JNU_ThrowIOExceptionWithLastError(env, "Transfer failed"); + return IOS_THROWN; + } + + if (sf_iobuf.bytes_sent > 0) + return (jlong)sf_iobuf.bytes_sent; + + return IOS_UNSUPPORTED_CASE; #else return IOS_UNSUPPORTED_CASE; #endif } + diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/windows/classes/java/lang/ProcessImpl.java --- a/jdk/src/windows/classes/java/lang/ProcessImpl.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/windows/classes/java/lang/ProcessImpl.java Tue May 27 13:58:00 2014 -0700 @@ -25,15 +25,15 @@ package java.lang; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.FileOutputStream; import java.io.IOException; -import java.io.File; import java.io.InputStream; import java.io.OutputStream; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileDescriptor; -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; import java.lang.ProcessBuilder.Redirect; import java.security.AccessController; import java.security.PrivilegedAction; @@ -483,6 +483,14 @@ private static native void terminateProcess(long handle); @Override + public long getPid() { + int pid = getProcessId0(handle); + return pid; + } + + private static native int getProcessId0(long handle); + + @Override public boolean isAlive() { return isProcessAlive(handle); } diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/windows/lib/tzmappings --- a/jdk/src/windows/lib/tzmappings Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/windows/lib/tzmappings Tue May 27 13:58:00 2014 -0700 @@ -137,8 +137,8 @@ Central Standard Time:36,37::America/Chicago: Eastern:38,39::America/New_York: Eastern Standard Time:38,39::America/New_York: -E. Europe:4,5:BY:Europe/Minsk: -E. Europe Standard Time:4,5:BY:Europe/Minsk: +E. Europe:4,5::EET: +E. Europe Standard Time:4,5::EET: Egypt:4,68::Africa/Cairo: Egypt Standard Time:4,68::Africa/Cairo: South Africa:4,69::Africa/Harare: @@ -192,5 +192,6 @@ Kaliningrad Standard Time:925,925:RU:Europe/Kaliningrad: Turkey Standard Time:926,926::Asia/Istanbul: Bahia Standard Time:927,927::America/Bahia: -Western Brazilian Standard Time:928,928:BR:America/Rio_Branco: -Armenian Standard Time:929,929:AM:Asia/Yerevan: +Libya Standard Time:928,928:LY:Africa/Tripoli: +Western Brazilian Standard Time:929,929:BR:America/Rio_Branco: +Armenian Standard Time:930,930:AM:Asia/Yerevan: diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/src/windows/native/java/lang/ProcessImpl_md.c --- a/jdk/src/windows/native/java/lang/ProcessImpl_md.c Tue May 27 12:50:51 2014 -0700 +++ b/jdk/src/windows/native/java/lang/ProcessImpl_md.c Tue May 27 13:58:00 2014 -0700 @@ -248,6 +248,17 @@ } } +/* + * Class: java_lang_ProcessImpl + * Method: getProcessId0 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_java_lang_ProcessImpl_getProcessId0 + (JNIEnv *env, jclass clazz, jlong handle) { + DWORD pid = GetProcessId((HANDLE) jlong_to_ptr(handle)); + return (jint)pid; +} + /* Please, read about the MS inheritance problem http://support.microsoft.com/kb/315939 and critical section/synchronized block solution. */ diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/test/java/lang/ProcessBuilder/Basic.java --- a/jdk/test/java/lang/ProcessBuilder/Basic.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/test/java/lang/ProcessBuilder/Basic.java Tue May 27 13:58:00 2014 -0700 @@ -26,7 +26,7 @@ * @bug 4199068 4738465 4937983 4930681 4926230 4931433 4932663 4986689 * 5026830 5023243 5070673 4052517 4811767 6192449 6397034 6413313 * 6464154 6523983 6206031 4960438 6631352 6631966 6850957 6850958 - * 4947220 7018606 7034570 4244896 5049299 + * 4947220 7018606 7034570 4244896 5049299 8003488 * @summary Basic tests for Process and Environment Variable code * @run main/othervm/timeout=300 Basic * @run main/othervm/timeout=300 -Djdk.lang.Process.launchMechanism=fork Basic @@ -1136,6 +1136,53 @@ } } + static void checkProcessPid() { + long actualPid = 0; + long expectedPid = -1; + if (Windows.is()) { + String[] argsTasklist = {"tasklist.exe", "/NH", "/FI", "\"IMAGENAME eq tasklist.exe\""}; + ProcessBuilder pb = new ProcessBuilder(argsTasklist); + try { + Process proc = pb.start(); + expectedPid = proc.getPid(); + + String output = commandOutput(proc); + String[] splits = output.split("\\s+"); + actualPid = Integer.valueOf(splits[2]); + } catch (Throwable t) { + unexpected(t); + } + } else if (Unix.is() || MacOSX.is()) { + String[] shArgs = {"sh", "-c", "echo $$"}; + ProcessBuilder pb = new ProcessBuilder(shArgs); + try { + Process proc = pb.start(); + expectedPid = proc.getPid(); + + String output = commandOutput(proc); + String[] splits = output.split("\\s+"); + actualPid = Integer.valueOf(splits[0]); + } catch (Throwable t) { + unexpected(t); + } + } else { + fail("No test for checkProcessPid on platform: " + System.getProperty("os.name")); + return; + } + + equal(actualPid, expectedPid); + + // Test the default implementation of Process.getPid + try { + DelegatingProcess p = new DelegatingProcess(null); + p.getPid(); + fail("non-overridden Process.getPid method should throw UOE"); + } catch (UnsupportedOperationException uoe) { + // correct + } + + } + private static void realMain(String[] args) throws Throwable { if (Windows.is()) System.out.println("This appears to be a Windows system."); @@ -1148,6 +1195,11 @@ catch (Throwable t) { unexpected(t); } //---------------------------------------------------------------- + // Basic tests for getPid() + //---------------------------------------------------------------- + checkProcessPid(); + + //---------------------------------------------------------------- // Basic tests for setting, replacing and deleting envvars //---------------------------------------------------------------- try { diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/test/java/lang/invoke/LambdaFormTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/lang/invoke/LambdaFormTest.java Tue May 27 13:58:00 2014 -0700 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014, 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 unit tests for java.lang.invoke.LambdaForm + * @run junit/othervm test.java.lang.invoke.LambdaFormTest + */ +package test.java.lang.invoke; + +import org.junit.Test; +import java.lang.reflect.Method; +import static org.junit.Assert.*; + +public class LambdaFormTest { + static final Method M_shortenSignature; + static { + try { + Class impl = Class.forName("java.lang.invoke.LambdaForm", false, null); + Method m = impl.getDeclaredMethod("shortenSignature", String.class); + m.setAccessible(true); + M_shortenSignature = m; + } catch(Exception e) { + throw new AssertionError(e); + } + } + + public static String shortenSignature(String signature) throws ReflectiveOperationException { + return (String)M_shortenSignature.invoke(null, signature); + } + + @Test + public void testShortenSignature() throws ReflectiveOperationException { + for (String s : new String[] { + // invariant strings: + "L", "LL", "ILL", "LIL", "LLI", "IILL", "ILIL", "ILLI", + // a few mappings: + "LLL=L3", "LLLL=L4", "LLLLLLLLLL=L10", + "IIIDDD=I3D3", "IDDD=ID3", "IIDDD=IID3", "IIID=I3D", "IIIDD=I3DD" + }) { + String s2 = s.substring(s.indexOf('=')+1); + String s1 = s.equals(s2) ? s : s.substring(0, s.length() - s2.length() - 1); + // mix the above cases with before and after reps of Z* + for (int k = -3; k <= 3; k++) { + String beg = (k < 0 ? "ZZZZ".substring(-k) : ""); + String end = (k > 0 ? "ZZZZ".substring(+k) : ""); + String ks1 = beg+s1+end; + String ks2 = shortenSignature(beg)+s2+shortenSignature(end); + String ks3 = shortenSignature(ks1); + assertEquals(ks2, ks3); + } + } + } + + public static void main(String[] args) throws ReflectiveOperationException { + LambdaFormTest test = new LambdaFormTest(); + test.testShortenSignature(); + } +} diff -r 080de8ffa3f6 -r fb7374c4fd87 jdk/test/java/util/BitSet/BSMethods.java --- a/jdk/test/java/util/BitSet/BSMethods.java Tue May 27 12:50:51 2014 -0700 +++ b/jdk/test/java/util/BitSet/BSMethods.java Tue May 27 13:58:00 2014 -0700 @@ -26,6 +26,7 @@ * 4979017 4979028 4979031 5030267 6222207 8040806 * @summary Test the operation of the methods of BitSet class * @author Mike McCloskey, Martin Buchholz + * @run main/othervm BSMethods */ import java.util.*; @@ -897,15 +898,20 @@ private static void testToString() { check(new BitSet().toString().equals("{}")); check(makeSet(2,3,42,43,234).toString().equals("{2, 3, 42, 43, 234}")); - try { - check(makeSet(Integer.MAX_VALUE-1).toString().equals( - "{" + (Integer.MAX_VALUE-1) + "}")); - check(makeSet(Integer.MAX_VALUE).toString().equals( - "{" + Integer.MAX_VALUE + "}")); - check(makeSet(0, 1, Integer.MAX_VALUE-1, Integer.MAX_VALUE).toString().equals( - "{0, 1, " + (Integer.MAX_VALUE-1) + ", " + Integer.MAX_VALUE + "}")); - } catch (IndexOutOfBoundsException exc) { - fail("toString() with indices near MAX_VALUE"); + + final long MB = 1024*1024; + if (Runtime.getRuntime().maxMemory() >= 512*MB) { + // only run it if we have enough memory + try { + check(makeSet(Integer.MAX_VALUE-1).toString().equals( + "{" + (Integer.MAX_VALUE-1) + "}")); + check(makeSet(Integer.MAX_VALUE).toString().equals( + "{" + Integer.MAX_VALUE + "}")); + check(makeSet(0, 1, Integer.MAX_VALUE-1, Integer.MAX_VALUE).toString().equals( + "{0, 1, " + (Integer.MAX_VALUE-1) + ", " + Integer.MAX_VALUE + "}")); + } catch (IndexOutOfBoundsException exc) { + fail("toString() with indices near MAX_VALUE"); + } } }