@@ -45,7 +45,7 @@ static IDATA matchStack (J9BytecodeVerificationData * verifyData, J9BranchTarget
4545static IDATA findAndMatchStack (J9BytecodeVerificationData * verifyData , IDATA targetPC , IDATA currentPC );
4646static IDATA verifyExceptions (J9BytecodeVerificationData * verifyData );
4747static J9BranchTargetStack * nextStack (J9BytecodeVerificationData * verifyData , UDATA * nextMapIndex , IDATA * nextStackPC );
48- static IDATA nextExceptionStart (J9BytecodeVerificationData * verifyData , J9ROMMethod * romMethod , IDATA lastPC );
48+ static void nextExceptionPC (J9BytecodeVerificationData * verifyData , J9ROMMethod * romMethod , IDATA * exceptionStartPC , IDATA * exceptionEndPC );
4949static void storeArgumentErrorData (J9BytecodeVerificationData * verifyData , U_32 errorCurrentFramePosition , U_16 errorArgumentIndex );
5050static void storeMethodInfo (J9BytecodeVerificationData * verifyData , J9UTF8 * errorClassString , J9UTF8 * errorMethodString , J9UTF8 * errorSignatureString , IDATA currentPC );
5151
@@ -447,16 +447,16 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
447447 UDATA classIndex , maxStack ;
448448 UDATA wideIndex = FALSE;
449449 IDATA nextStackPC ;
450- IDATA nextExceptionStartPC ;
450+ IDATA exceptionStartPC = -1 ;
451+ IDATA exceptionEndPC = -1 ;
451452 IDATA rc = 0 ;
452453 U_8 returnBytecode ;
453454 UDATA errorModule = J9NLS_BCV_ERR_BYTECODES_INVALID__MODULE ; /* defaults to BCV NLS catalog */
454455 U_16 errorType ;
455456 I_16 offset16 ;
456457 I_32 offset32 ;
457458 UDATA argCount ;
458- UDATA checkIfInsideException = romMethod -> modifiers & J9AccMethodHasExceptionInfo ;
459- UDATA tempStoreChange ;
459+ UDATA tempStoreChange = FALSE;
460460 J9ExceptionInfo * exceptionInfo = J9_EXCEPTION_DATA_FROM_ROM_METHOD (romMethod );
461461 J9ExceptionHandler * handler ;
462462 J9UTF8 * catchName ;
@@ -523,7 +523,7 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
523523 currentMapData = nextStack (verifyData , & nextMapIndex , & nextStackPC );
524524
525525 /* Determine where the first region of bytecodes covered by an exception handler is */
526- nextExceptionStartPC = nextExceptionStart (verifyData , romMethod , -1 );
526+ nextExceptionPC (verifyData , romMethod , & exceptionStartPC , & exceptionEndPC );
527527
528528 /* walk the bytecodes linearly */
529529 while (pc < length ) {
@@ -570,8 +570,19 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
570570 currentMapData = nextStack (verifyData , & nextMapIndex , & nextStackPC );
571571 }
572572
573- /* Check the stack against the exception handler stack */
574- if (pc == (UDATA ) nextExceptionStartPC ) {
573+ /* Check the current state against the exception handlers if:
574+ * - This is the first bytecode of the try/catch block
575+ * - The temps (locals) type state has changed due to a store
576+ * instruction. If it is within the same exception range ensure
577+ * that the types are still compatible.
578+ */
579+ if ((pc == (UDATA ) exceptionStartPC )
580+ || (tempStoreChange && (exceptionStartPC < pc && pc < exceptionEndPC ))
581+ ) {
582+ /* If this is the first pc of an exception tempStoreChange does not apply. */
583+ if ((pc == (UDATA ) exceptionStartPC ) && tempStoreChange ) {
584+ tempStoreChange = FALSE;
585+ }
575586 handler = J9EXCEPTIONINFO_HANDLERS (exceptionInfo );
576587 SAVE_STACKTOP (liveStack , stackTop );
577588
@@ -582,7 +593,9 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
582593
583594 /* Find all exception handlers from here */
584595 for (i = exceptionInfo -> catchCount ; i ; i -- , handler ++ ) {
585- if (handler -> startPC == pc ) {
596+ if ((handler -> startPC == pc )
597+ || (tempStoreChange && ((UDATA ) pc >= handler -> startPC ) && ((UDATA ) pc < handler -> endPC ))
598+ ) {
586599 /* Check the maps at the handler PC */
587600 /* Modify the liveStack temporarily to contain the handler exception */
588601 if (handler -> exceptionClassIndex ) {
@@ -612,8 +625,13 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
612625 liveStack -> stackElements [liveStack -> stackBaseIndex ] = originalStackZeroEntry ;
613626 stackTop = originalStackTop ;
614627
615- /* Get next exception start PC of interest */
616- nextExceptionStartPC = nextExceptionStart (verifyData , romMethod , nextExceptionStartPC );
628+ if (FALSE == tempStoreChange ) {
629+ /* Get next exception start PC of interest */
630+ nextExceptionPC (verifyData , romMethod , & exceptionStartPC , & exceptionEndPC );
631+ }
632+ }
633+ if (tempStoreChange ) {
634+ tempStoreChange = FALSE;
617635 }
618636
619637 bcIndex = code + pc ;
@@ -809,8 +827,6 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
809827 goto _inconsistentStack ;
810828 }
811829
812- tempStoreChange = FALSE;
813-
814830 if (type != type1 ) {
815831 if ((type1 != BCV_GENERIC_OBJECT ) || (type & BCV_TAG_BASE_TYPE_OR_TOP )) {
816832 inconsistentStack = TRUE;
@@ -830,56 +846,6 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
830846 }
831847 tempStoreChange |= (type != temps [index ]);
832848 STORE_TEMP (index , type );
833-
834- if (checkIfInsideException && tempStoreChange ) {
835- /* If we've stored a value into an arg/local, and it's of a different type than was
836- * originally there, we need to ensure that we are still compatible with all our
837- * exception handlers.
838- *
839- * For all exception handlers covering this instruction
840- */
841- handler = J9EXCEPTIONINFO_HANDLERS (exceptionInfo );
842- SAVE_STACKTOP (liveStack , stackTop );
843-
844- /* Save the current liveStack element zero */
845- /* Reset the stack pointer to push the exception on the empty stack */
846- originalStackTop = stackTop ;
847- originalStackZeroEntry = liveStack -> stackElements [liveStack -> stackBaseIndex ];
848-
849- /* Find all exception handlers from here */
850- for (i = exceptionInfo -> catchCount ; i ; i -- , handler ++ ) {
851- if (((UDATA ) start >= handler -> startPC ) && ((UDATA ) start < handler -> endPC )) {
852- #ifdef DEBUG_BCV
853- printf ("exception map change check at startPC: %d\n" , handler -> startPC );
854- #endif
855- /* Check the maps at the handler PC */
856- /* Modify the liveStack temporarily to contain the handler exception */
857- if (handler -> exceptionClassIndex ) {
858- catchName = J9ROMSTRINGREF_UTF8DATA ((J9ROMStringRef * )(& constantPool [handler -> exceptionClassIndex ]));
859- catchClass = convertClassNameToStackMapType (verifyData , J9UTF8_DATA (catchName ), J9UTF8_LENGTH (catchName ), 0 , 0 );
860- } else {
861- catchClass = BCV_JAVA_LANG_THROWABLE_INDEX ;
862- catchClass <<= BCV_CLASS_INDEX_SHIFT ;
863- }
864-
865- stackTop = & (liveStack -> stackElements [liveStack -> stackBaseIndex ]);
866- PUSH (catchClass );
867- SAVE_STACKTOP (liveStack , stackTop );
868-
869- rc = findAndMatchStack (verifyData , handler -> handlerPC , start );
870- if (BCV_SUCCESS != rc ) {
871- if (BCV_ERR_INSUFFICIENT_MEMORY == rc ) {
872- goto _outOfMemoryError ;
873- }
874- goto _mapError ;
875- }
876- }
877- }
878-
879- /* Restore liveStack */
880- liveStack -> stackElements [liveStack -> stackBaseIndex ] = originalStackZeroEntry ;
881- stackTop = originalStackTop ;
882- }
883849 break ;
884850
885851 case RTV_ARRAY_STORE :
@@ -2863,22 +2829,24 @@ nextStack (J9BytecodeVerificationData *verifyData, UDATA *nextMapIndex, IDATA *n
28632829}
28642830
28652831/* Return the next pc in the method that is an exception handler start address */
2866-
2867- static IDATA
2868- nextExceptionStart (J9BytecodeVerificationData * verifyData , J9ROMMethod * romMethod , IDATA lastPC )
2832+ static void
2833+ nextExceptionPC (J9BytecodeVerificationData * verifyData , J9ROMMethod * romMethod , IDATA * exceptionStartPC , IDATA * exceptionEndPC )
28692834{
28702835 /* Method size */
2871- IDATA nextPC = J9_BYTECODE_SIZE_FROM_ROM_METHOD (romMethod );
2836+ IDATA nextStartPC = J9_BYTECODE_SIZE_FROM_ROM_METHOD (romMethod );
2837+ IDATA nextEndPC = nextStartPC ;
28722838
28732839 if (romMethod -> modifiers & CFR_ACC_HAS_EXCEPTION_INFO ) {
28742840 J9ExceptionInfo * exceptionInfo = J9_EXCEPTION_DATA_FROM_ROM_METHOD (romMethod );
28752841 J9ExceptionHandler * handler = J9EXCEPTIONINFO_HANDLERS (exceptionInfo );
28762842 UDATA i ;
28772843
28782844 for (i = exceptionInfo -> catchCount ; i ; i -- , handler ++ ) {
2879- if (((IDATA ) handler -> startPC ) > lastPC ) {
2880- if (handler -> startPC < (UDATA ) nextPC ) {
2881- nextPC = handler -> startPC ;
2845+ /* exceptionStartPC has the last exception start. */
2846+ if (((IDATA ) handler -> startPC ) > * exceptionStartPC ) {
2847+ if (handler -> startPC < (UDATA ) nextStartPC ) {
2848+ nextStartPC = handler -> startPC ;
2849+ nextEndPC = handler -> endPC ;
28822850 }
28832851 }
28842852 }
@@ -2889,10 +2857,12 @@ nextExceptionStart (J9BytecodeVerificationData *verifyData, J9ROMMethod *romMeth
28892857 J9UTF8_DATA (J9ROMMETHOD_NAME (verifyData -> romMethod )),
28902858 (UDATA ) J9UTF8_LENGTH (J9ROMMETHOD_SIGNATURE (verifyData -> romMethod )),
28912859 J9UTF8_DATA (J9ROMMETHOD_SIGNATURE (verifyData -> romMethod )),
2892- exceptionInfo -> catchCount , lastPC , nextPC ,
2860+ exceptionInfo -> catchCount , * exceptionStartPC , nextStartPC ,
28932861 J9_BYTECODE_SIZE_FROM_ROM_METHOD (romMethod ));
28942862 }
2895- return nextPC ;
2863+
2864+ * exceptionStartPC = nextStartPC ;
2865+ * exceptionEndPC = nextEndPC ;
28962866}
28972867
28982868
0 commit comments