Skip to content

Commit

Permalink
Merge pull request #1831 from dnakamura/ret_op3
Browse files Browse the repository at this point in the history
Implement truncated return bytecodes
  • Loading branch information
DanHeidinga authored Oct 17, 2018
2 parents 2e7556f + 43f70b6 commit 8c6d5e2
Show file tree
Hide file tree
Showing 14 changed files with 339 additions and 46 deletions.
4 changes: 4 additions & 0 deletions debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/BCNames.java
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,10 @@ public class BCNames {
public static final int JBinvokehandlegeneric = 233;
public static final int JBinvokestaticsplit = 234;
public static final int JBinvokespecialsplit = 235;
public static final int JBreturnC = 236;
public static final int JBreturnS = 237;
public static final int JBreturnB = 238;
public static final int JBreturnZ = 239;
public static final int JBretFromNative0 = 244;
public static final int JBretFromNative1 = 245;
public static final int JBretFromNativeF = 246;
Expand Down
26 changes: 13 additions & 13 deletions debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/PCStack.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2014 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 @@ -270,10 +270,10 @@ public class PCStack
0x03 /* JBinvokehandlegeneric = 233 */,
0x63 /* JBinvokestaticsplit = 234 */,
0x63 /* JBinvokespecialsplit = 235 */,
0x00 /* JBunimplemented = 236 */,
0x00 /* JBunimplemented = 237 */,
0x00 /* JBunimplemented = 238 */,
0x00 /* JBunimplemented = 239 */,
0x01 /* JBreturnC = 236 */,
0x01 /* JBreturnS = 237 */,
0x01 /* JBreturnB = 238 */,
0x01 /* JBreturnZ = 239 */,
0x00 /* JBunimplemented = 240 */,
0x00 /* JBunimplemented = 241 */,
0x00 /* JBunimplemented = 242 */,
Expand Down Expand Up @@ -529,10 +529,10 @@ public class PCStack
0x80 /* JBinvokehandlegeneric = 233 -- pops: 0 pushes: 0*/ ,
0x80 /* JBinvokestaticsplit = 234 -- pops: 0 pushes: 0*/ ,
0x80 /* JBinvokespecialsplit = 235 -- pops: 0 pushes: 0*/ ,
0x00 /* JBunimplemented = 236 -- pops: 0 pushes: 0*/ ,
0x00 /* JBunimplemented = 237 -- pops: 0 pushes: 0*/ ,
0x00 /* JBunimplemented = 238 -- pops: 0 pushes: 0*/ ,
0x00 /* JBunimplemented = 239 -- pops: 0 pushes: 0*/ ,
0x00 /* JBreturnC = 236 -- pops: 1 pushes: 0*/ ,
0x01 /* JBreturnS = 237 -- pops: 1 pushes: 0*/ ,
0x01 /* JBreturnB = 238 -- pops: 1 pushes: 0*/ ,
0x01 /* JBreturnZ = 239 -- pops: 1 pushes: 0*/ ,
0x00 /* JBunimplemented = 240 -- pops: 0 pushes: 0*/ ,
0x00 /* JBunimplemented = 241 -- pops: 0 pushes: 0*/ ,
0x00 /* JBunimplemented = 242 -- pops: 0 pushes: 0*/ ,
Expand Down Expand Up @@ -788,10 +788,10 @@ public class PCStack
0x0 /* JBinvokehandlegeneric (16rE9) */,
0x0 /* JBinvokestaticsplit (16rEA) */,
0x0 /* JBinvokespecialsplit (16rEB) */,
0x0 /* JBunimplemented (16rEC) */,
0x0 /* JBunimplemented (16rED) */,
0x0 /* JBunimplemented (16rEE) */,
0x0 /* JBunimplemented (16rEF) */,
0x0 /* JBreturnC (16rEC) */,
0x0 /* JBreturnS (16rED) */,
0x0 /* JBreturnB (16rEE) */,
0x0 /* JBreturnZ (16rEF) */,
0x0 /* JBunimplemented (16rF0) */,
0x0 /* JBunimplemented (16rF1) */,
0x0 /* JBunimplemented (16rF2) */,
Expand Down
10 changes: 5 additions & 5 deletions debugtools/DDR_VM/src/com/ibm/j9ddr/vm29/j9/VrfyTbl.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2014 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 @@ -266,10 +266,10 @@ public class VrfyTbl
0x1100 /* JBinvokehandlegeneric - 233 */,
0x1100 /* JBinvokestaticsplit - 234 */,
0x1100 /* JBinvokespecialsplit - 235 */,
0x1700 /* JBunimplemented - 236 */,
0x1700 /* JBunimplemented - 237 */,
0x1700 /* JBunimplemented - 238 */,
0x1700 /* JBunimplemented - 239 */,
0x0F00 /* JBreturnC - 236 */,
0x0F00 /* JBreturnS - 237 */,
0x0F00 /* JBreturnB - 238 */,
0x0F00 /* JBreturnZ - 239 */,
0x1700 /* JBunimplemented - 240 */,
0x1700 /* JBunimplemented - 241 */,
0x1700 /* JBunimplemented - 242 */,
Expand Down
4 changes: 4 additions & 0 deletions runtime/bcutil/ClassFileWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1349,6 +1349,10 @@ ClassFileWriter::rewriteBytecode(J9ROMMethod * method, U_32 length, U_8 * code)
case JBreturn0: /* Fall-through */
case JBreturn1: /* Fall-through */
case JBreturn2: /* Fall-through */
case JBreturnB: /* Fall-through */
case JBreturnC: /* Fall-through */
case JBreturnS: /* Fall-through */
case JBreturnZ: /* Fall-through */
case JBsyncReturn0: /* Fall-through */
case JBsyncReturn1: /* Fall-through */
case JBsyncReturn2: {
Expand Down
6 changes: 4 additions & 2 deletions runtime/bcutil/ComparingCursor.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2001, 2014 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 @@ -33,6 +33,8 @@
#include "bcnames.h"
#include "pcstack.h"
#include "rommeth.h"
#include "vrfytbl.h"
#include "bytecodewalk.h"


ComparingCursor::ComparingCursor(J9JavaVM *javaVM, SRPOffsetTable *srpOffsetTable,
Expand Down Expand Up @@ -324,7 +326,7 @@ ComparingCursor::writeData(U_8* bytes, UDATA length, DataType dataType)
/* Check if the bytecode matches with a special case for JBgenericReturn. */
if (instruction != romInstruction) {
if ((JBgenericReturn != instruction) ||
(((romInstruction < JBreturn0) || (JBsyncReturn2 < romInstruction)) && (JBreturnFromConstructor != romInstruction))
(RTV_RETURN != (J9JavaBytecodeVerificationTable[romInstruction] >> 8))
) {
markUnEqual();
break;
Expand Down
4 changes: 3 additions & 1 deletion runtime/bcverify/j9bcverify.tdf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//*******************************************************************************
// Copyright (c) 2006, 2017 IBM Corp. and others
// Copyright (c) 2006, 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 @@ -185,3 +185,5 @@ TraceException=Trc_RTV_verifyBytecodes_OutOfMemoryException Overhead=1 Level=1 T
TraceException=Trc_RTV_verifyExceptions_OutOfMemoryException Overhead=1 Level=1 Template="verifyExceptions - %.*s %.*s%.*s - Out of Memory Exception"
TraceException=Trc_RTV_j9rtv_verifyArguments_OutOfMemoryException Overhead=1 Level=1 Template="j9rtv_verifyArguments - %.*s %.*s%.*s - Out of Memory Exception"
TraceException=Trc_RTV_j9rtv_verifyArguments_InaccessibleClass Overhead=1 Level=1 Template="j9rtv_verifyArguments - %.*s %.*s%.*s - Inaccessible class"

TraceException=Trc_RTV_j9rtv_verifyBytecodes_Unreachable Overhead=1 Level=1 Template="j9rtv_verifyBytecodes - %.*s %.*s%.*s Unreachable error %i occurred"
44 changes: 44 additions & 0 deletions runtime/bcverify/rtverify.c
Original file line number Diff line number Diff line change
Expand Up @@ -1172,15 +1172,58 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
break;

case JBreturn1:
case JBreturnB:
case JBreturnC:
case JBreturnS:
case JBreturnZ:
case JBsyncReturn1:
/* Note: for synchronized return{B,C,S,Z}, JBgenericReturn is used */
if (returnChar) {
U_32 returnType = 0;
/* single character return description */
if ((returnChar < 'A') || (returnChar > 'Z')) {
inconsistentStack = TRUE;
goto _illegalPrimitiveReturn;
}
type = (UDATA) oneArgTypeCharConversion[returnChar - 'A'];
POP_TOS(type);

/* check methods that return char, byte, short, or bool use the right opcode */
if (BCV_BASE_TYPE_INT == type){
switch(bc) {
case JBreturnB:
returnType = BCV_BASE_TYPE_BYTE_BIT;
break;

case JBreturnC:
returnType = BCV_BASE_TYPE_CHAR_BIT;
break;

case JBreturnS:
returnType = BCV_BASE_TYPE_SHORT_BIT;
break;

case JBreturnZ:
returnType = BCV_BASE_TYPE_BOOL_BIT;
break;
/* Note: synchronized return of b,c,s,z are handled as a JBgenericReturn */
case JBreturn1:
case JBsyncReturn1:
returnType = BCV_BASE_TYPE_INT_BIT;
break;
default:
Trc_RTV_j9rtv_verifyBytecodes_Unreachable(verifyData->vmStruct,
(UDATA) J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(verifyData->romClass)),
J9UTF8_DATA(J9ROMCLASS_CLASSNAME(verifyData->romClass)),
(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_GET_NAME(verifyData->romClass, verifyData->romMethod)),
J9UTF8_DATA(J9ROMMETHOD_GET_NAME(verifyData->romClass, verifyData->romMethod)),
(UDATA) J9UTF8_LENGTH(J9ROMMETHOD_GET_SIGNATURE(verifyData->romClass, verifyData->romMethod)),
J9UTF8_DATA(J9ROMMETHOD_GET_SIGNATURE(verifyData->romClass, verifyData->romMethod)),
__LINE__);
break;
}
inconsistentStack |= returnType != baseTypeCharConversion[returnChar - 'A'];
}
if (inconsistentStack) {
/* Jazz 82615: Set the expected data type (already in type) and
* the location of wrong data type on stack when the verification error occurs.
Expand All @@ -1189,6 +1232,7 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
errorStackIndex = stackTop - liveStack->stackElements;
goto _inconsistentStack;
}

} else {
IDATA reasonCode = 0;

Expand Down
50 changes: 41 additions & 9 deletions runtime/stackmap/fixreturns.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 @@ -134,25 +134,57 @@ getReturnBytecode(J9ROMClass * romClass, J9ROMMethod * romMethod, UDATA * return
*returnSlots = 0;
sigChar = sigData[sigLength - 1];

/* Update the sig char in the case we are dealing with an array */
if ('[' == sigData[sigLength - 2]) {
sigChar = '[';
}

if (sigChar != 'V') {
*returnSlots = 1;
if (sigChar == 'J' || sigChar == 'D') {
if (sigData[sigLength - 2] != '[') {
*returnSlots = 2;
}
*returnSlots = 2;
}
}

/* Determine the correct return bytecode to insert */

returnBytecode = JBreturn0 + (U_8) *returnSlots;

if ((J9UTF8_DATA(name)[0] == '<') && (J9UTF8_DATA(name)[1] == 'i')) {
returnBytecode = JBreturnFromConstructor;
} else if (romMethod->modifiers & J9AccSynchronized) {
returnBytecode = JBsyncReturn0 + (U_8) *returnSlots;
} else {
/* bool, byte, char, and short need special treatment since they need to be truncated before return */
if (romMethod->modifiers & J9AccSynchronized) {
switch(sigChar){
case 'Z':
case 'B':
case 'C':
case 'S':
returnBytecode = JBgenericReturn;
break;
default:
returnBytecode = JBsyncReturn0 + (U_8) *returnSlots;
break;
}
} else {
switch(sigChar){
case 'Z':
returnBytecode = JBreturnZ;
break;
case 'B':
returnBytecode = JBreturnB;
break;
case 'C':
returnBytecode = JBreturnC;
break;
case 'S':
returnBytecode = JBreturnS;
break;
default:
returnBytecode = JBreturn0 + (U_8) *returnSlots;
break;
}
}
}


return returnBytecode;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,10 @@ const char * const maciek_JavaBCNames[] = {
"JBunimplemented" /* 233 */,
"JBunimplemented" /* 234 */,
"JBunimplemented" /* 235 */,
"JBunimplemented" /* 236 */,
"JBunimplemented" /* 237 */,
"JBunimplemented" /* 238 */,
"JBunimplemented" /* 239 */,
"JBreturnC" /* 236 */,
"JBreturnS" /* 237 */,
"JBreturnB" /* 238 */,
"JBreturnZ" /* 239 */,
"JBunimplemented" /* 240 */,
"JBunimplemented" /* 241 */,
"JBunimplemented" /* 242 */,
Expand Down
4 changes: 4 additions & 0 deletions runtime/verbose/errormessagehelper.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ convertToOracleOpcodeString(U_8 j9Opcode, U_8 returnType)
case JBreturn0: /* FALLTHROUGH */
case JBreturn1: /* FALLTHROUGH */
case JBreturn2: /* FALLTHROUGH */
case JBreturnC: /* FALLTHROUGH */
case JBreturnS: /* FALLTHROUGH */
case JBreturnB: /* FALLTHROUGH */
case JBreturnZ: /* FALLTHROUGH */
case JBsyncReturn0: /* FALLTHROUGH */
case JBsyncReturn1: /* FALLTHROUGH */
case JBsyncReturn2:
Expand Down
47 changes: 35 additions & 12 deletions runtime/vm/BytecodeInterpreter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7564,6 +7564,7 @@ done:;
U_8 *sigData = NULL;
UDATA returnSlots = 0;
UDATA *bp = bpForCurrentBytecodedMethod(REGISTER_ARGS);
U_8 truncatedReturnBytecode = 0;
/* Check for synchronized */
if (romMethod->modifiers & J9AccSynchronized) {
IDATA monitorRC = exitObjectMonitor(REGISTER_ARGS, ((j9object_t*)bp)[1]);
Expand Down Expand Up @@ -7634,18 +7635,22 @@ done:;
case 'B':
returnSlots = 1;
*(I_32*)_sp = (I_8)*(I_32*)_sp;
truncatedReturnBytecode = JBreturnB;
break;
case 'C':
returnSlots = 1;
*(I_32*)_sp = (U_16)*(I_32*)_sp;
truncatedReturnBytecode = JBreturnC;
break;
case 'S':
returnSlots = 1;
*(I_32*)_sp = (I_16)*(I_32*)_sp;
truncatedReturnBytecode = JBreturnS;
break;
case 'Z':
returnSlots = 1;
*(U_32*)_sp = 1 & *(U_32*)_sp;
truncatedReturnBytecode = JBreturnZ;
break;
default:
returnSlots = 1;
Expand All @@ -7663,13 +7668,22 @@ done:;
if ((JBbreakpoint != *_pc) && (FALSE == isObjectConstructor)) {
/* Is this a clean return? */
if (returnSlots == (UDATA)(((UDATA*)j2iFrame) - _sp)) {
U_8 newBytecode = JBreturn0;
if (romMethod->modifiers & J9AccSynchronized) {
newBytecode = JBsyncReturn0;
} else if (isConstructor) {
newBytecode = JBreturnFromConstructor;
/* are we dealing with a case where we should use a truncated return bytecode? */
if (truncatedReturnBytecode != 0) {
/* we only want to update the bytecode for non-synchronized methods */
/* (synchronized returns will fall back to a generic return) */
if (!(romMethod->modifiers & J9AccSynchronized)) {
*_pc = truncatedReturnBytecode;
}
} else {
U_8 newBytecode = JBreturn0;
if (romMethod->modifiers & J9AccSynchronized) {
newBytecode = JBsyncReturn0;
} else if (isConstructor) {
newBytecode = JBreturnFromConstructor;
}
*_pc = (newBytecode + (U_8)returnSlots);
}
*_pc = (newBytecode + (U_8)returnSlots);
}
}
rc = j2iReturn(REGISTER_ARGS);
Expand All @@ -7682,13 +7696,22 @@ done:;
if ((JBbreakpoint != *_pc) && (FALSE == isObjectConstructor)) {
/* Is this a clean return? */
if (returnSlots == (UDATA)(((UDATA*)frame) - _sp)) {
U_8 newBytecode = JBreturn0;
if (romMethod->modifiers & J9AccSynchronized) {
newBytecode = JBsyncReturn0;
} else if (isConstructor) {
newBytecode = JBreturnFromConstructor;
/* are we dealing with a case where we should use a truncated return bytecode? */
if (truncatedReturnBytecode != 0) {
/* we only want to update the bytecode for non-synchronized methods */
/* (synchronized returns will fall back to a generic return) */
if (!(romMethod->modifiers & J9AccSynchronized)) {
*_pc = truncatedReturnBytecode;
}
} else {
U_8 newBytecode = JBreturn0;
if (romMethod->modifiers & J9AccSynchronized) {
newBytecode = JBsyncReturn0;
} else if (isConstructor) {
newBytecode = JBreturnFromConstructor;
}
*_pc = (newBytecode + (U_8)returnSlots);
}
*_pc = (newBytecode + (U_8)returnSlots);
}
}
/* Collapse the frame and copy the return value */
Expand Down
Loading

0 comments on commit 8c6d5e2

Please sign in to comment.