This commit is contained in:
Phil Race 2014-05-27 13:58:00 -07:00
commit 306a48dfd9
42 changed files with 1015 additions and 2079 deletions

View File

@ -38,7 +38,7 @@ EXCLUDES :=
##########################################################################################
EXCLUDES += com/sun/pept \
EXCLUDES += \
com/sun/tools/example/trace \
com/sun/tools/example/debug/bdi \
com/sun/tools/example/debug/event \

View File

@ -474,7 +474,7 @@ public final class Connection implements Runnable {
}
if ((rber == null) && waited) {
removeRequest(ldr);
abandonRequest(ldr, null);
throw new NamingException("LDAP response read timed out, timeout used:"
+ readTimeout + "ms." );

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept;
import com.sun.pept.presentation.MessageStruct;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface Delegate {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* @return a MessageStruct with ...
* </p>
*/
public MessageStruct getMessageStruct();
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param message ...
* </p>
*/
public void send(MessageStruct message);
} // end Delegate

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.encoding;
import com.sun.pept.ept.MessageInfo;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface Decoder {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param messageInfo ...
* </p>
*/
public void decode(MessageInfo messageInfo);
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param messageInfo ...
* </p>
*/
public void receiveAndDecode(MessageInfo messageInfo);
} // end Decoder

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.encoding;
import com.sun.pept.ept.MessageInfo;
import java.nio.ByteBuffer;
import java.util.*;
/**
* <p>
*
* @author Arun Gupta
* </p>
*/
public interface Encoder {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param messageInfo ...
* </p>
*/
public void encodeAndSend(MessageInfo messageInfo);
/**
* <p>
* Does ...
* </p><p>
*
* @return a ByteBuffer with ...
* </p><p>
* @param messageInfo ...
* </p>
*/
public ByteBuffer encode(MessageInfo messageInfo);
} // end Encoder

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.ept;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface Acceptor extends EPTFactory {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* </p>
*/
public void accept();
} // end Acceptor

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.ept;
import com.sun.pept.transport.Connection;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface ContactInfo extends EPTFactory {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* @return a Connection with ...
* </p><p>
* @param messageInfo ...
* </p>
*/
public Connection getConnection(MessageInfo messageInfo);
} // end ContactInfo

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.ept;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface ContactInfoList {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* @return a ContactInfoListIterator with ...
* </p>
*/
public ContactInfoListIterator iterator();
} // end ContactInfoList

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.ept;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface ContactInfoListIterator {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* @return a boolean with ...
* </p>
*/
public boolean hasNext();
/**
* <p>
* Does ...
* </p><p>
*
* @return a ContactInfo with ...
* </p>
*/
public ContactInfo next();
} // end ContactInfoListIterator

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> 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.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface EPTFactory {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* @return a MessageDispatcher with ...
* </p><p>
* @param messageInfo ...
* </p>
*/
public MessageDispatcher getMessageDispatcher(MessageInfo messageInfo);
/**
* <p>
* Does ...
* </p><p>
*
* @return a Encoder with ...
* </p><p>
* @param messageInfo ...
* </p>
*/
public Encoder getEncoder(MessageInfo messageInfo);
/**
* <p>
* Does ...
* </p><p>
*
* @return a Decoder with ...
* </p><p>
* @param messageInfo ...
* </p>
*/
public Decoder getDecoder(MessageInfo messageInfo);
/**
* <p>
* Does ...
* </p><p>
*
* @return a Interceptors with ...
* </p><p>
* @param x ...
* </p>
*/
public Interceptors getInterceptors(MessageInfo x);
/**
* <p>
* Does ...
* </p><p>
*
* @return a TargetFinder with ...
* </p><p>
* @param x ...
* </p>
*/
public TargetFinder getTargetFinder(MessageInfo x);
} // end EPTFactory

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> 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.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface MessageInfo extends MessageStruct {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* @return a EPTFactory with ...
* </p>
*/
public EPTFactory getEPTFactory();
/**
* <p>
* Does ...
* </p><p>
*
* @return a MessageDispatcher with ...
* </p>
*/
public MessageDispatcher getMessageDispatcher();
/**
* <p>
* Does ...
* </p><p>
*
* @return a Encoder with ...
* </p>
*/
public Encoder getEncoder();
/**
* <p>
* Does ...
* </p><p>
*
* @return a Decoder with ...
* </p>
*/
public Decoder getDecoder();
/**
* <p>
* Does ...
* </p><p>
*
* @return a Connection with ...
* </p>
*/
public Connection getConnection();
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param eptFactory ...
* </p>
*/
public void setEPTFactory(EPTFactory eptFactory);
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param messageDispatcher ...
* </p>
*/
public void setMessageDispatcher(MessageDispatcher messageDispatcher);
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param encoder ...
* </p>
*/
public void setEncoder(Encoder encoder);
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param decoder ...
* </p>
*/
public void setDecoder(Decoder decoder);
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param connection ...
* </p>
*/
public void setConnection(Connection connection);
} // end MessageInfo

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.presentation;
import java.util.*;
import java.lang.reflect.Method;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface MessageStruct {
///////////////////////////////////////
//attributes
/**
* <p>
* Represents ...
* </p>
*/
public static final int NORMAL_RESPONSE = 0;
/**
* <p>
* Represents ...
* </p>
*/
public static final int CHECKED_EXCEPTION_RESPONSE = 1;
/**
* <p>
* Represents ...
* </p>
*/
public static final int UNCHECKED_EXCEPTION_RESPONSE = 2;
/**
* <p>
* Represents ...
* </p>
*/
public static final int REQUEST_RESPONSE_MEP = 1;
/**
* <p>
* Represents ...
* </p>
*/
public static final int ONE_WAY_MEP = 2;
/**
* <p>
* Represents ...
* </p>
*/
public static final int ASYNC_POLL_MEP = 3;
/**
* <p>
* Represents ...
* </p>
*/
public static final int ASYNC_CALLBACK_MEP = 4;
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* @param data ...
* </p><p>
*
* </p>
*/
public void setData(Object[] data);
/**
* <p>
* Does ...
* </p><p>
*
* @return a Object[] with ...
* </p>
*/
public Object[] getData();
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param name ...
* </p><p>
* @param value ...
* </p>
*/
public void setMetaData(Object name, Object value);
/**
* <p>
* Does ...
* </p><p>
*
* @return a Object with ...
* </p><p>
* @param name ...
* </p>
*/
public Object getMetaData(Object name);
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param messageExchangePattern ...
* </p>
*/
public void setMEP(int messageExchangePattern);
/**
* <p>
* Does ...
* </p><p>
*
* @return a int with ...
* </p>
*/
public int getMEP();
/**
* <p>
* Does ...
* </p><p>
*
* @return a int with ...
* </p>
*/
public int getResponseType();
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param responseType ...
* </p>
*/
public void setResponseType(int responseType);
/**
* <p>
* Does ...
* </p><p>
*
* @return a Object with ...
* </p>
*/
public Object getResponse();
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param response ...
* </p>
*/
public void setResponse(Object response);
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param method ...
* </p>
*/
public void setMethod(Method method);
/**
* <p>
* Does ...
* </p><p>
*
* @return a Method with ...
* </p>
*/
public Method getMethod();
} // end MessageStruct

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.presentation;
import com.sun.pept.Delegate;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface Stub {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param delegate ...
* </p>
*/
public void _setDelegate(Delegate delegate);
/**
* <p>
* Does ...
* </p><p>
*
* @return a Delegate with ...
* </p>
*/
public Delegate _getDelegate();
} // end Stub

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.presentation;
import com.sun.pept.ept.MessageInfo;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface TargetFinder {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* @return a Tie with ...
* </p><p>
* @param x ...
* </p>
*/
public Tie findTarget(MessageInfo x);
} // end TargetFinder

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.presentation;
import com.sun.pept.ept.MessageInfo;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface Tie {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param servant ...
* </p>
*/
public void _setServant(Object servant);
/**
* <p>
* Does ...
* </p><p>
*
* @return a Object with ...
* </p>
*/
public Object _getServant();
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param messageInfo ...
* </p>
*/
public void _invoke(MessageInfo messageInfo);
} // end Tie

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.protocol;
import com.sun.pept.ept.MessageInfo;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface Interceptors {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param messageInfo ...
* </p>
*/
public void interceptMessage(MessageInfo messageInfo);
} // end Interceptors

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.protocol;
import com.sun.pept.ept.MessageInfo;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface MessageDispatcher {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param messageInfo ...
* </p>
*/
public void send(MessageInfo messageInfo);
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param messageInfo ...
* </p>
*/
public void receive(MessageInfo messageInfo);
} // end MessageDispatcher

View File

@ -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 <A HREF="http://www.gentleware.com">Gentleware</A>.
* Generated with <A HREF="http://jakarta.apache.org/velocity/">velocity</A> template engine.
*/
package com.sun.pept.transport;
import com.sun.pept.ept.EPTFactory;
import java.nio.ByteBuffer;
import java.util.*;
/**
* <p>
*
* @author Dr. Harold Carr
* </p>
*/
public interface Connection {
///////////////////////////////////////
// operations
/**
* <p>
* Does ...
* </p><p>
*
* </p><p>
*
* @param byteBuffer ...
* </p>
*/
public void write(ByteBuffer byteBuffer);
/**
* <p>
* Does ...
* </p><p>
*
* @return a EPTFactory with ...
* </p>
*/
public EPTFactory getEPTFactory();
/**
* <p>
* Does ...
* </p><p>
*
* @return a int with ...
* </p><p>
* @param byteBuffer ...
* </p>
*/
public int read(ByteBuffer byteBuffer);
/**
* <p>
* Does ...
* </p><p>
*
* </p>
*/
public ByteBuffer readUntilEnd();
} // end Connection

View File

@ -1,2 +0,0 @@
Manifest-Version: 1.0
Main-Class: com.sun.tools.hat.Main

View File

@ -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

View File

@ -1,82 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2005, 2008, 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.
-->
<!--
The Original Code is HAT. The Initial Developer of the
Original Code is Bill Foote, with contributions from others
at JavaSoft/Sun.
-->
<!-- This is an Ant project file to build Heap Analysis Tool (HAT).
For more information on Ant, please see http://ant.apache.org/
To build jhat.jar, run ant in current directory. jhat.jar is
built in ./build directory.
-->
<project name="Java Heap Analysis Tool" default="all" basedir=".">
<!-- Property Definitions -->
<property name="app.name" value="jhat"/>
<property name="src.dir" value="."/>
<property name="build.dir" value="build"/>
<property name="classes.dir" value="${build.dir}/classes"/>
<property name="dist.jar" value="${app.name}.jar"/>
<target name="prepare">
<mkdir dir="${build.dir}"/>
<mkdir dir="${classes.dir}"/>
</target>
<target name="clean">
<delete dir="${build.dir}"/>
</target>
<target name="compile" depends="prepare" description="Compiles the sources">
<javac srcdir="${src.dir}" destdir="${classes.dir}"
debug="on" deprecation="on">
</javac>
</target>
<target name="deploy" depends="compile" description="Creates a deployment bundle">
<delete file="${build.dir}/${dist.jar}" />
<mkdir dir="${classes.dir}/com/sun/tools/hat/resources" />
<copy todir="${classes.dir}/com/sun/tools/hat/resources">
<fileset dir="${src.dir}/resources" includes="*" />
</copy>
<jar jarfile="${build.dir}/${dist.jar}"
manifest="${src.dir}/MANIFEST.mf" basedir="${classes.dir}"/>
</target>
<target name="all" depends="deploy" description="Builds sources and deployment jar"/>
</project>

View File

@ -262,4 +262,18 @@ public abstract class Process {
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();
}
}

View File

@ -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 @@ import jdk.internal.org.objectweb.asm.Type;
// 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 @@ import jdk.internal.org.objectweb.asm.Type;
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 @@ import jdk.internal.org.objectweb.asm.Type;
@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 @@ import jdk.internal.org.objectweb.asm.Type;
@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 @@ import jdk.internal.org.objectweb.asm.Type;
/*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 @@ import jdk.internal.org.objectweb.asm.Type;
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 @@ import jdk.internal.org.objectweb.asm.Type;
/*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 cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, narg);
/*non-public*/ final BoundMethodHandle copyWith(MethodType mt, LambdaForm lf) {
return new Species_L(mt, lf, argL0);
}
@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);
/*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 cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, 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
/*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 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
/*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);
/*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
/*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);
}
}
}
/*
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);
}
@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;
}
@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);
}
@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);
}
}
*/
//
// 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<? extends BoundMethodHandle> 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() ? "<placeholder>" : clazz.getSimpleName())+":"+types+"]";
return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+typeChars+"]";
}
/**
@ -354,45 +300,46 @@ import jdk.internal.org.objectweb.asm.Type;
* 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<? extends BoundMethodHandle> 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 @@ import jdk.internal.org.objectweb.asm.Type;
static { CACHE.put("", EMPTY); } // make bootstrap predictable
private static final boolean INIT_DONE; // set after <clinit> 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 @@ import jdk.internal.org.objectweb.asm.Type;
static {
// pre-fill the BMH speciesdata cache with BMH's inner classes
final Class<BoundMethodHandle> 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 @@ import jdk.internal.org.objectweb.asm.Type;
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 @@ import jdk.internal.org.objectweb.asm.Type;
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 @@ import jdk.internal.org.objectweb.asm.Type;
* 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 cloneExtendI(MethodType mt, LambdaForm lf, int narg) {
* return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
* 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 cloneExtendJ(MethodType mt, LambdaForm lf, long narg) {
* return SPECIES_DATA.extendWithIndex(INDEX_J).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 cloneExtendF(MethodType mt, LambdaForm lf, float narg) {
* return SPECIES_DATA.extendWithIndex(INDEX_F).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 cloneExtendD(MethodType mt, LambdaForm lf, double narg) {
* return SPECIES_DATA.extendWithIndex(INDEX_D).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);
* }
* 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);
* }
* }
* </pre>
@ -586,8 +531,9 @@ import jdk.internal.org.objectweb.asm.Type;
static Class<? extends BoundMethodHandle> 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 @@ import jdk.internal.org.objectweb.asm.Type;
MethodVisitor mv;
// emit constructor
mv = cw.visitMethod(NOT_ACC_PUBLIC, "<init>", makeSignature(types, true), null, null);
mv = cw.visitMethod(ACC_PRIVATE, "<init>", 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, "<init>", makeSignature("", true), false);
@ -647,39 +593,73 @@ import jdk.internal.org.objectweb.asm.Type;
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();
// 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);
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();
// 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, "<init>", 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, "<init>", 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 @@ import jdk.internal.org.objectweb.asm.Type;
// 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 @@ import jdk.internal.org.objectweb.asm.Type;
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 @@ import jdk.internal.org.objectweb.asm.Type;
static MethodHandle[] makeCtors(Class<? extends BoundMethodHandle> 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 @@ import jdk.internal.org.objectweb.asm.Type;
static MethodHandle makeCbmhCtor(Class<? extends BoundMethodHandle> 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 <init>} 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 <init>}. To avoid this, we add an indirection by invoking {@code <init>} 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 <init>} 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;

View File

@ -31,6 +31,7 @@ import java.util.Arrays;
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;
@ -124,11 +125,6 @@ class DirectMethodHandle extends MethodHandle {
return new Constructor(mtype, lform, ctor, init, instanceClass);
}
@Override
MethodHandle copyWith(MethodType mt, LambdaForm lf) {
return new DirectMethodHandle(mt, lf, member);
}
@Override
String internalProperties() {
return "/DMH="+member.toString();
@ -146,9 +142,9 @@ class DirectMethodHandle extends MethodHandle {
}
@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 @@ class DirectMethodHandle extends MethodHandle {
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();

View File

@ -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 jdk.internal.org.objectweb.asm.*;
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 @@ class InvokerBytecodeGenerator {
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 @@ class InvokerBytecodeGenerator {
/*
* NOTE: These load/store methods use the localsMap to find the correct index!
*/
private void emitLoadInsn(char type, int index) {
int opcode;
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);
}
private void emitLoadInsn(BasicType type, int index) {
int opcode = loadInsnOpcode(type);
mv.visitVarInsn(opcode, localsMap[index]);
}
private void emitAloadInsn(int index) {
emitLoadInsn('L', index);
}
private void emitStoreInsn(char type, int index) {
int opcode;
private int loadInsnOpcode(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.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);
}
}
private void emitAloadInsn(int index) {
emitLoadInsn(L_TYPE, index);
}
private void emitStoreInsn(BasicType type, int index) {
int opcode = storeInsnOpcode(type);
mv.visitVarInsn(opcode, localsMap[index]);
}
private int storeInsnOpcode(BasicType type) throws InternalError {
switch (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);
}
}
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 @@ class InvokerBytecodeGenerator {
/**
* 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 @@ class InvokerBytecodeGenerator {
* @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 @@ class InvokerBytecodeGenerator {
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 @@ class InvokerBytecodeGenerator {
/**
* 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 @@ class InvokerBytecodeGenerator {
// 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 @@ class InvokerBytecodeGenerator {
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 @@ class InvokerBytecodeGenerator {
*/
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 @@ class InvokerBytecodeGenerator {
// 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 @@ class InvokerBytecodeGenerator {
// 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 @@ class InvokerBytecodeGenerator {
}
}
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 @@ class InvokerBytecodeGenerator {
}
}
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 InvokerBytecodeGenerator {
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 @@ class InvokerBytecodeGenerator {
// 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 @@ class InvokerBytecodeGenerator {
* 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 InvokerBytecodeGenerator {
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 @@ class InvokerBytecodeGenerator {
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);

View File

@ -30,14 +30,14 @@ import java.lang.reflect.Method;
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 @@ class LambdaForm {
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<Class<?>> 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 @@ class LambdaForm {
// 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,24 +287,55 @@ class LambdaForm {
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 debugName;
}
private static boolean namesOK(int arity, Name[] names) {
for (int i = 0; i < names.length; i++) {
Name n = names[i];
@ -294,14 +431,14 @@ class LambdaForm {
// }
/** 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 @@ class LambdaForm {
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 @@ class LambdaForm {
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 @@ class LambdaForm {
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 @@ class LambdaForm {
* 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 @@ class LambdaForm {
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 @@ class LambdaForm {
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 @@ class LambdaForm {
}
LambdaForm addArguments(int pos, List<Class<?>> 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 @@ class LambdaForm {
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 @@ class LambdaForm {
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 @@ class LambdaForm {
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 @@ class LambdaForm {
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 @@ class LambdaForm {
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 @@ class LambdaForm {
if (member == null) return String.valueOf(resolvedHandle);
return member.getDeclaringClass().getSimpleName()+"."+member.getName();
}
}
void resolve() {
for (Name n : names) n.resolve();
}
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<Class<?>> types) {
char[] btypes = new char[types.size()];
for (int i = 0; i < btypes.length; i++) {
btypes[i] = basicType(types.get(i));
public boolean isIdentity() {
return this.equals(identity(returnType()));
}
public boolean isConstantZero() {
return this.equals(constantZero(returnType()));
}
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 @@ class LambdaForm {
}
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 @@ class LambdaForm {
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 @@ class LambdaForm {
}
return true;
}
char typeChar() {
return type.btChar;
}
void resolve() {
if (function != null)
@ -1397,18 +1532,18 @@ class LambdaForm {
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 @@ class LambdaForm {
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 @@ class LambdaForm {
@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 @@ class LambdaForm {
}
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 @@ class LambdaForm {
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()];
}
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);
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 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 @@ class LambdaForm {
static final native Object linkToInterface(Object x1, MemberName mn) throws Throwable;
*/
static { NamedFunction.initializeInvokers(); }
private static final HashMap<String,Integer> 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.

View File

@ -27,10 +27,12 @@ package java.lang.invoke;
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 @@ public abstract class MethodHandle {
* <li>If the return type <em>T0</em> is void and <em>T1</em> a primitive,
* a zero value is introduced.
* </ul>
* (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types,
* (<em>Note:</em> Both <em>T0</em> and <em>T1</em> may be regarded as static types,
* because neither corresponds specifically to the <em>dynamic type</em> of any
* actual argument or return value.)
* <p>
@ -1374,7 +1376,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
}
/*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 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
/*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*/

View File

@ -412,7 +412,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
@Override
MethodHandle bindArgument(int pos, char basicType, Object value) {
MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
return asFixedArity().bindArgument(pos, basicType, value);
}

View File

@ -78,7 +78,7 @@ class MethodHandleNatives {
// The JVM calls MethodHandleNatives.<clinit>. Cascade the <clinit> 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 MethodHandleNatives {
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 @@ class MethodHandleNatives {
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.

View File

@ -65,6 +65,16 @@ import sun.misc.Unsafe;
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 @@ import sun.misc.Unsafe;
}
// 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);
}

View File

@ -37,10 +37,11 @@ import sun.reflect.CallerSensitive;
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 @@ assert((int)twice.invokeExact(21) == 42);
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 @@ assert((int)twice.invokeExact(21) == 42);
if (pos == 0) {
result = result.bindReceiver(value);
} else {
result = result.bindArgument(pos, 'L', value);
result = result.bindArgument(pos, L_TYPE, value);
}
}
return result;

View File

@ -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 @@ final class SimpleMethodHandle extends MethodHandle {
}
@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 @@ final class SimpleMethodHandle extends MethodHandle {
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);
}
}

View File

@ -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 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable {
}
}
// 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 @@ abstract class DigestBase extends MessageDigestSpi implements Cloneable {
}
}
// 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) {

View File

@ -158,6 +158,8 @@ final public class JInfo {
sysprops(pid);
System.out.println();
flags(pid);
System.out.println();
commandLine(pid);
} else {
usage(1);
}
@ -248,6 +250,12 @@ final public class JInfo {
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");

View File

@ -482,6 +482,11 @@ final class UNIXProcess extends Process {
return this;
}
@Override
public long getPid() {
return pid;
}
@Override
public synchronized boolean isAlive() {
return !hasExited;

View File

@ -39,6 +39,8 @@
#if defined(__linux__) || defined(__solaris__)
#include <sys/sendfile.h>
#elif defined(_AIX)
#include <sys/socket.h>
#elif defined(_ALLBSD_SOURCE)
#include <sys/types.h>
#include <sys/socket.h>
@ -207,9 +209,7 @@ Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
numBytes = count;
#ifdef __APPLE__
result = sendfile(srcFD, dstFD, position, &numBytes, NULL, 0);
#endif
if (numBytes > 0)
return numBytes;
@ -228,7 +228,48 @@ Java_sun_nio_ch_FileChannelImpl_transferTo0(JNIEnv *env, jobject this,
}
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
}

View File

@ -25,15 +25,15 @@
package java.lang;
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.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ProcessBuilder.Redirect;
import java.security.AccessController;
import java.security.PrivilegedAction;
@ -482,6 +482,14 @@ final class ProcessImpl extends Process {
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);

View File

@ -137,8 +137,8 @@ Central:36,37::America/Chicago:
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 @@ Magadan Standard Time:924,924::Asia/Magadan:
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:

View File

@ -248,6 +248,17 @@ static void restoreIOEHandleState(
}
}
/*
* 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. */

View File

@ -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 @@ public class Basic {
}
}
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.");
@ -1147,6 +1194,11 @@ public class Basic {
try { testIORedirection(); }
catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// Basic tests for getPid()
//----------------------------------------------------------------
checkProcessPid();
//----------------------------------------------------------------
// Basic tests for setting, replacing and deleting envvars
//----------------------------------------------------------------

View File

@ -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();
}
}

View File

@ -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 @@ public class BSMethods {
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");
}
}
}