Skip to content

Commit

Permalink
Merge pull request eclipse-openj9#1183 from gacholio/master
Browse files Browse the repository at this point in the history
Add methods inherited from superinterfaces to iTables
  • Loading branch information
DanHeidinga authored Feb 15, 2018
2 parents 512974d + 171d56a commit fd14d02
Show file tree
Hide file tree
Showing 12 changed files with 202 additions and 135 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*[INCLUDE-IF Sidecar17]*/
/*******************************************************************************
* Copyright (c) 2009, 2009 IBM Corp. and others
* Copyright (c) 2009, 2018 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 @@ -68,12 +68,13 @@ public InterfaceHandle(InterfaceHandle originalHandle, MethodType newType) {
/// {{{ JIT support
protected final long vtableOffset(Object receiver) {
/*[IF]*/
/* Must be 'defc' rather than 'type().parameterType(0)' so that the
* itable index matches the defining interface, otherwise handles
* on interfaces methods defined in parent interfaces will crash
/* Must be 'referenceClass' rather than 'type().parameterType(0)' or
* 'defc' so that the itable index matches the defining interface at
* handle creation time, otherwise handles on interfaces methods defined
* in parent interfaces will crash
*/
/*[ENDIF]*/
Class<?> interfaceClass = defc;
Class<?> interfaceClass = referenceClass;
if (interfaceClass.isInstance(receiver)) {
long interfaceJ9Class = getJ9ClassFromClass(interfaceClass);
long receiverJ9Class = getJ9ClassFromClass(receiver.getClass());
Expand Down
4 changes: 2 additions & 2 deletions runtime/jcl/common/java_dyn_methodhandle.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2017 IBM Corp. and others
* Copyright (c) 2001, 2018 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 @@ -95,7 +95,7 @@ lookupInterfaceMethod(J9VMThread *currentThread, J9Class *lookupClass, J9UTF8 *n
vmFuncs->setCurrentExceptionNLS(currentThread, J9VMCONSTANTPOOL_JAVALANGINCOMPATIBLECLASSCHANGEERROR, J9NLS_JCL_PRIVATE_INTERFACE_REQUIRES_INVOKESPECIAL);
method = NULL;
} else {
*methodIndex = vmFuncs->getITableIndexForMethod(method);
*methodIndex = getITableIndexForMethod(method, lookupClass);
if (*methodIndex == -1) {
method = NULL;
}
Expand Down
1 change: 0 additions & 1 deletion runtime/oti/j9nonbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -4481,7 +4481,6 @@ typedef struct J9InternalVMFunctions {
UDATA ( *resolveVirtualMethodRef)(struct J9VMThread *vmStruct, J9ConstantPool *constantPool, UDATA cpIndex, UDATA resolveFlags, struct J9Method **resolvedMethod) ;
struct J9Method* ( *resolveInterfaceMethodRef)(struct J9VMThread *vmStruct, J9ConstantPool *constantPool, UDATA cpIndex, UDATA resolveFlags) ;
UDATA ( *getVTableIndexForMethod)(struct J9Method * method, struct J9Class *clazz, struct J9VMThread *vmThread) ;
UDATA ( *getITableIndexForMethod)(struct J9Method * method) ;
IDATA ( *checkVisibility)(struct J9VMThread* currentThread, struct J9Class* sourceClass, struct J9Class* destClass, UDATA modifiers, UDATA lookupOptions) ;
void (JNICALL *sendClinit)(struct J9VMThread *vmContext, struct J9Class *clazz, UDATA reserved1, UDATA reserved2, UDATA reserved3) ;
void ( *freeStackWalkCaches)(struct J9VMThread * currentThread, J9StackWalkState * walkState) ;
Expand Down
14 changes: 13 additions & 1 deletion runtime/oti/util_api.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2017 IBM Corp. and others
* Copyright (c) 1991, 2018 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 @@ -1872,6 +1872,18 @@ getReturnTypeFromSignature(U_8 * inData, UDATA inLength, U_8 **outData);

/* ---------------- mthutil.c ---------------- */

/**
* @brief Retrieve the index of an interface method within the iTable for an interface
* (not necessarily the same interface, as iTables contain methods from all
* extended interfaces as well as the local one).
* @param method The interface method
* @param targetInterface The interface in whose table to search
* (NULL to use the declaring class of method)
* @return UDATA The iTable index (not including the fixed J9ITable header), or -1 if not found
*/
UDATA
getITableIndexForMethod(J9Method * method, J9Class *targetInterface);

/**
* Returns the first ROM method following the argument.
* If this is called on the last ROM method in a ROM class
Expand Down
8 changes: 0 additions & 8 deletions runtime/oti/vm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -3885,14 +3885,6 @@ illegalAccessMessage(J9VMThread *currentThread, IDATA badMemberModifier, J9Class
void
fillJITVTableSlot(J9VMThread *vmStruct, UDATA *currentSlot, J9Method *currentMethod);

/**
* @brief
* @param method
* @return UDATA
*/
UDATA
getITableIndexForMethod(J9Method * method);

/**
* @brief
* @param method
Expand Down
88 changes: 54 additions & 34 deletions runtime/util/hshelp.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 1991, 2017 IBM Corp. and others
* Copyright (c) 1991, 2018 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 @@ -993,25 +993,28 @@ fixITablesForFastHCR(J9VMThread *currentThread, J9HashTable *classPairs)
}

while (superITable != iTable) {
J9Class *interfaceClass = iTable->interfaceClass;
J9JVMTIClassPair exemplar;
J9JVMTIClassPair *result;

exemplar.originalRAMClass = interfaceClass;
result = hashTableFind(classPairs, &exemplar);
if ((NULL != result) && (NULL != result->methodRemap)) {
UDATA methodIndex;
J9ITable *allInterfaces = (J9ITable*)iTable->interfaceClass->iTable;
UDATA *iTableMethods = (UDATA *)(iTable + 1);
do {
J9Class *interfaceClass = allInterfaces->interfaceClass;
J9JVMTIClassPair exemplar;
J9JVMTIClassPair *result;
UDATA methodCount = interfaceClass->romClass->romMethodCount;
UDATA *vTable = (UDATA *)(clazz + 1);
UDATA *iTableMethods = (UDATA *)(iTable + 1);

for (methodIndex = 0; methodIndex < methodCount; methodIndex++) {
UDATA vTableIndex = findMethodInVTable(&interfaceClass->ramMethods[methodIndex], vTable);

Assert_hshelp_false((UDATA)-1 == vTableIndex);
iTableMethods[methodIndex] = (vTableIndex * sizeof(UDATA)) + sizeof(J9Class);
exemplar.originalRAMClass = interfaceClass;
result = hashTableFind(classPairs, &exemplar);
if ((NULL != result) && (NULL != result->methodRemap)) {
UDATA methodIndex;
UDATA *vTable = (UDATA *)(clazz + 1);

for (methodIndex = 0; methodIndex < methodCount; methodIndex++) {
UDATA vTableIndex = findMethodInVTable(&interfaceClass->ramMethods[methodIndex], vTable);
iTableMethods[methodIndex] = (vTableIndex * sizeof(UDATA)) + sizeof(J9Class);
}
}
}
iTableMethods += methodCount;
allInterfaces = allInterfaces->next;
} while (NULL != allInterfaces);
iTable = iTable->next;
}
}
Expand Down Expand Up @@ -1695,24 +1698,41 @@ fixRAMConstantPoolForFastHCR(J9ConstantPool *ramConstantPool, J9HashTable *class
case J9CPTYPE_INTERFACE_METHOD: {
J9RAMInterfaceMethodRef *methodRef = (J9RAMInterfaceMethodRef *) &ramConstantPool[cpIndex];
UDATA methodIndex = ((methodRef->methodIndexAndArgCount & ~255) >> 8);
J9Class *interfaceClass = (J9Class *) methodRef->interfaceClass;

classPair.originalRAMClass = interfaceClass;
classResult = hashTableFind(classHashTable, &classPair);
if (NULL != classResult) {
J9Class *obsoleteClass = classResult->replacementClass.ramClass;

if (NULL != obsoleteClass) {
J9Method *method = &obsoleteClass->ramMethods[methodIndex];

methodPair.oldMethod = method;
methodResult = hashTableFind(methodHashTable, &methodPair);
if (NULL != methodResult) {
UDATA argCount = (methodRef->methodIndexAndArgCount & 255);
UDATA newMethodIndex = getMethodIndex(methodResult->newMethod);

methodRef->methodIndexAndArgCount = ((newMethodIndex << 8) | argCount);
J9Class *resolvedClass = (J9Class *) methodRef->interfaceClass;
/* Don't fix unresolved entries */
if (NULL != resolvedClass) {
/* Find the appropriate segment for the referenced method within the
* resolvedClass iTable. This is fast HCR (no addition or removal of
* methods), so the shape of the iTables cannot change, just the ordering
* of methods within them.
*/
J9ITable *allInterfaces = (J9ITable*)resolvedClass->iTable;
for(;;) {
J9Class *interfaceClass = allInterfaces->interfaceClass;
UDATA methodCount = interfaceClass->romClass->romMethodCount;
if (methodIndex < methodCount) {
classPair.originalRAMClass = interfaceClass;
classResult = hashTableFind(classHashTable, &classPair);
/* If the class was not replaced, no need to update the constant pool */
if (NULL != classResult) {
J9Class *obsoleteClass = classResult->replacementClass.ramClass;
if (NULL != obsoleteClass) {
/* If the referenced method was not reordered, no need to update the constant pool */
methodPair.oldMethod = obsoleteClass->ramMethods + methodIndex;
methodResult = hashTableFind(methodHashTable, &methodPair);
if (NULL != methodResult) {
UDATA argCount = (methodRef->methodIndexAndArgCount & 255);
UDATA newMethodIndex = getITableIndexForMethod(methodResult->newMethod, resolvedClass);
/* Fix the index in the resolved CP entry, retaining the argCount */
methodRef->methodIndexAndArgCount = ((newMethodIndex << 8) | argCount);
}
}
}
/* iTable segment was located, stop the scan */
break;
}
methodIndex -= methodCount;
allInterfaces = allInterfaces->next;
}
}
break;
Expand Down
41 changes: 41 additions & 0 deletions runtime/util/mthutil.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,47 @@ getCodeTypeAnnotationsDataFromROMMethod(J9ROMMethod *romMethod)
return result;
}

UDATA
getITableIndexForMethod(J9Method * method, J9Class *targetInterface)
{
J9Class *methodClass = J9_CLASS_FROM_METHOD(method);
const UDATA methodCount = methodClass->romClass->romMethodCount;
const UDATA methodIndex = method - methodClass->ramMethods;
UDATA skip = 0;
/* NULL targetInterface implies searching only within methodClass, which may be an obsolete class.
* This works because the methods for the local interface always appear first in the iTable, with
* extended interface methods appearing after.
*/
if (NULL != targetInterface) {
/* Locate methodClass within the extends chain of targetInterface */
J9ITable *allInterfaces = (J9ITable*)targetInterface->iTable;
for(;;) {
J9Class *interfaceClass = allInterfaces->interfaceClass;
if (interfaceClass == methodClass) {
break;
}
skip += interfaceClass->romClass->romMethodCount;
allInterfaces = allInterfaces->next;
}
}
/* The iTableIndex is the same as the (ram/rom)method index.
* This includes static and private methods - they just exist
* as dead entries in the iTable.
*
* Code below is the equivalent of doing:
* for (; methodIndex < methodCount; methodIndex++) {
* if (ramMethod == method) {
* return methodIndex;
* }
* ramMethod++;
* }
*/
if (methodIndex < methodCount) {
return methodIndex + skip;
}
return -1;
}

J9MethodDebugInfo *
methodDebugInfoFromROMMethod(J9ROMMethod *romMethod)
{
Expand Down
6 changes: 3 additions & 3 deletions runtime/vm/MHInterpreter.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2017 IBM Corp. and others
* Copyright (c) 2001, 2018 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 @@ -186,13 +186,13 @@ VM_MHInterpreter::dispatchLoop(j9object_t methodHandle)
if (NULL != receiver) {
_currentThread->sp += 1;
J9Class *receiverClazz = J9OBJECT_CLAZZ(_currentThread, receiver);
J9Class *interfaceClazz = getPrimitiveHandleDefc(methodHandle);
J9Class *interfaceClazz = J9VM_J9CLASS_FROM_HEAPCLASS(_currentThread, J9VMJAVALANGINVOKEPRIMITIVEHANDLE_REFERENCECLASS(_currentThread, methodHandle));
method = convertITableIndexToVirtualMethod(receiverClazz, interfaceClazz, getVMSlot(methodHandle));
if (NULL != method) {
goto runMethod;
}
prepareForExceptionThrow(_currentThread);
setClassCastException(_currentThread, receiverClazz, interfaceClazz);
setCurrentExceptionUTF(_currentThread, J9VMCONSTANTPOOL_JAVALANGINCOMPATIBLECLASSCHANGEERROR, NULL);
goto throwCurrentException;
}
nextAction = THROW_NPE;
Expand Down
Loading

0 comments on commit fd14d02

Please sign in to comment.