Skip to content

Commit

Permalink
Merge pull request #8501 from babsingh/jep370_impl4
Browse files Browse the repository at this point in the history
JEP-370 Implementation (Part 3)
  • Loading branch information
DanHeidinga committed Mar 1, 2020
2 parents a18ca6b + 0c32d79 commit dd6fe85
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*[INCLUDE-IF Sidecar18-SE]*/
/*******************************************************************************
* Copyright (c) 2009, 2019 IBM Corp. and others
* Copyright (c) 2009, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -2466,9 +2466,13 @@ public static VarHandle arrayElementVarHandle(Class<?> arrayClass) throws Illega
* @throws NullPointerException If {@code viewArrayClass} or {@code byteOrder} is null
*/
public static VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass, ByteOrder byteOrder) throws IllegalArgumentException {
checkArrayClass(viewArrayClass);
Objects.requireNonNull(byteOrder);
/*[IF Java14]*/
return VarHandles.byteArrayViewHandle(viewArrayClass, (byteOrder == ByteOrder.BIG_ENDIAN));
/*[ELSE] Java14
checkArrayClass(viewArrayClass);
return new ByteArrayViewVarHandle(viewArrayClass.getComponentType(), byteOrder);
/*[ENDIF] Java14 */
}

/**
Expand All @@ -2481,9 +2485,13 @@ public static VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass, ByteOrde
* @throws NullPointerException If {@code viewArrayClass} or {@code byteOrder} is null
*/
public static VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass, ByteOrder byteOrder) throws IllegalArgumentException {
checkArrayClass(viewArrayClass);
Objects.requireNonNull(byteOrder);
/*[IF Java14]*/
return VarHandles.makeByteBufferViewHandle(viewArrayClass, (byteOrder == ByteOrder.BIG_ENDIAN));
/*[ELSE] Java14
checkArrayClass(viewArrayClass);
return new ByteBufferViewVarHandle(viewArrayClass.getComponentType(), byteOrder);
/*[ENDIF] Java14 */
}

private static void checkArrayClass(Class<?> arrayClass) throws IllegalArgumentException {
Expand Down
48 changes: 38 additions & 10 deletions jcl/src/java.base/share/classes/java/lang/invoke/VarHandle.java
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ MethodType accessModeType(Class<?> receiver, Class<?> type, Class<?>... args) {

/*[IF Java14]*/
static final BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> AIOOBE_SUPPLIER = null;
private boolean varFormUsed = false;
/*[ENDIF] Java14 */

private final MethodHandle[] handleTable;
Expand Down Expand Up @@ -419,6 +420,7 @@ MethodType accessModeType(Class<?> receiver, Class<?> type, Class<?>... args) {
this.handleTable = populateMHsJEP370(operationsClass, operationMTs, operationMTs);
}
this.modifiers = 0;
this.varFormUsed = true;
}

/**
Expand Down Expand Up @@ -632,12 +634,17 @@ public final String toString() {
* @return The {@link MethodType} corresponding to the provided {@link AccessMode}.
*/
public final MethodType accessModeType(AccessMode accessMode) {
MethodType internalType = handleTable[accessMode.ordinal()].type;
int numOfArguments = internalType.arguments.length;

// Drop the internal VarHandle argument
MethodType modifiedType = internalType.dropParameterTypes(numOfArguments - 1, numOfArguments);

MethodType modifiedType = null;
MethodHandle internalHandle = handleTable[accessMode.ordinal()];
if (internalHandle == null) {
modifiedType = accessModeTypeUncached(accessMode);
} else {
MethodType internalType = internalHandle.type;
int numOfArguments = internalType.arguments.length;

/* Drop the internal VarHandle argument. */
modifiedType = internalType.dropParameterTypes(numOfArguments - 1, numOfArguments);
}
return modifiedType;
}

Expand All @@ -649,6 +656,12 @@ public final MethodType accessModeType(AccessMode accessMode) {
* @return A boolean value indicating whether the {@link AccessMode} is supported.
*/
boolean isAccessModeSupportedHelper(AccessMode accessMode) {
/*[IF Java14]*/
if (varFormUsed) {
return (handleTable[accessMode.ordinal()] != null);
}
/*[ENDIF] Java14 */

switch (accessMode) {
case GET:
case GET_VOLATILE:
Expand Down Expand Up @@ -712,17 +725,32 @@ public final boolean isAccessModeSupported(AccessMode accessMode) {
*/
public final MethodHandle toMethodHandle(AccessMode accessMode) {
MethodHandle mh = handleTable[accessMode.ordinal()];
mh = MethodHandles.insertArguments(mh, mh.type.parameterCount() - 1, this);

if (!isAccessModeSupported(accessMode)) {
MethodType mt = mh.type;

if (mh != null) {
mh = MethodHandles.insertArguments(mh, mh.type.parameterCount() - 1, this);
}

if ((mh == null) || !isAccessModeSupported(accessMode)) {
MethodType mt = null;

if (mh != null) {
mt = mh.type;
} else {
mt = accessModeTypeUncached(accessMode);
/* accessModeTypeUncached does not return null. It throws InternalError if the method type
* cannot be determined.
*/
mt = mt.appendParameterTypes(this.getClass());
}

try {
mh = _lookup.findStatic(VarHandle.class, "throwUnsupportedOperationException", MethodType.methodType(void.class)); //$NON-NLS-1$
} catch (Throwable e) {
InternalError error = new InternalError("The method throwUnsupportedOperationException should be accessible and defined in this class."); //$NON-NLS-1$
error.initCause(e);
throw error;
}

/* The resulting method handle must come with the same signature as the requested access mode method
* so as to throw out UnsupportedOperationException from that method.
*/
Expand Down
15 changes: 15 additions & 0 deletions runtime/oti/vm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,21 @@ setCurrentExceptionWithUtfCause(J9VMThread *currentThread, UDATA exceptionNumber
void
setCurrentExceptionNLS(J9VMThread * vmThread, UDATA exceptionNumber, U_32 moduleName, U_32 messageNumber);

/**
* Prepare for throwing an exception. Find the exception class using its name.
* Create an object using the exception class. Set an OutOfMemoryError if the
* object cannot be created. Otherwise, set an exception pending using the
* created object.
*
* Note this does not generate the "systhrow" dump event.
*
* @param vmThread[in] the current J9VMThread
* @param exceptionClassName[in] the name of the exception class
* @return void
*/
void
prepareExceptionUsingClassName(J9VMThread *vmThread, const char *exceptionClassName);

/**
* @brief Creates exception with nls message; substitutes string values into error message.
* @param vmThread current VM thread
Expand Down
9 changes: 9 additions & 0 deletions runtime/vm/BytecodeInterpreter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8270,6 +8270,15 @@ done:;
/* Get MethodHandle for this operation from the VarHandles handleTable */
j9object_t handleTable = J9VMJAVALANGINVOKEVARHANDLE_HANDLETABLE(_currentThread, varHandle);
j9object_t methodHandle = J9JAVAARRAYOFOBJECT_LOAD(_currentThread, handleTable, operation);

if (NULL == methodHandle) {
updateVMStruct(REGISTER_ARGS);
prepareExceptionUsingClassName(_currentThread, "java/lang/UnsupportedOperationException");
VMStructHasBeenUpdated(REGISTER_ARGS);
rc = GOTO_THROW_CURRENT_EXCEPTION;
goto done;
}

j9object_t handleType = J9VMJAVALANGINVOKEMETHODHANDLE_TYPE(_currentThread, methodHandle);

/* Get call site MethodType */
Expand Down
14 changes: 13 additions & 1 deletion runtime/vm/MHInterpreter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2019 IBM Corp. and others
* Copyright (c) 2001, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -555,6 +555,18 @@ VM_MHInterpreter::dispatchLoop(j9object_t methodHandle)
/* Get MethodHandle for this operation from the VarHandle's handleTable */
j9object_t handleTable = J9VMJAVALANGINVOKEVARHANDLE_HANDLETABLE(_currentThread, varHandle);
j9object_t methodHandleFromTable = J9JAVAARRAYOFOBJECT_LOAD(_currentThread, handleTable, operation);

if (NULL == methodHandleFromTable) {
/* Building a method type (MT) frame makes the stack walkable since looking up the class below may
* cause a GC or another exception. Also, the MT frame will make it easier to debug and service the
* error as the VarHandle will be on the stack and findable with DDR. The MT frame does not need to
* be restored since throwing the exception will handle it appropriately.
*/
buildMethodTypeFrame(_currentThread, type);
prepareExceptionUsingClassName(_currentThread, "java/lang/UnsupportedOperationException");
goto throwCurrentException;
}

j9object_t handleTypeFromTable = J9VMJAVALANGINVOKEMETHODHANDLE_TYPE(_currentThread, methodHandleFromTable);
j9object_t accessModeType = J9VMJAVALANGINVOKEVARHANDLEINVOKEHANDLE_ACCESSMODETYPE(_currentThread, methodHandle);

Expand Down
27 changes: 27 additions & 0 deletions runtime/vm/exceptionsupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,33 @@ setCurrentExceptionNLS(J9VMThread * vmThread, UDATA exceptionNumber, U_32 module
setCurrentExceptionUTF(vmThread, exceptionNumber, msg);
}

void
prepareExceptionUsingClassName(J9VMThread *vmThread, const char *exceptionClassName)
{
J9Class *exceptionClass = NULL;
j9object_t exception = NULL;

prepareForExceptionThrow(vmThread);

exceptionClass = internalFindClassUTF8(
vmThread,
(U_8 *)exceptionClassName,
strlen(exceptionClassName),
vmThread->javaVM->systemClassLoader,
J9_FINDCLASS_FLAG_THROW_ON_FAIL);

exception = vmThread->javaVM->memoryManagerFunctions->J9AllocateObject(
vmThread,
exceptionClass,
J9_GC_ALLOCATE_OBJECT_NON_INSTRUMENTABLE);

if (J9_UNEXPECTED(NULL == exception)) {
setHeapOutOfMemoryError(vmThread);
} else {
vmThread->currentException = exception;
vmThread->privateFlags |= J9_PRIVATE_FLAGS_REPORT_EXCEPTION_THROW;
}
}

/**
* Creates exception with nls message; substitutes string values into error message.
Expand Down

0 comments on commit dd6fe85

Please sign in to comment.