@@ -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 ;
@@ -520,7 +520,7 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
520520 currentMapData = nextStack (verifyData , & nextMapIndex , & nextStackPC );
521521
522522 /* Determine where the first region of bytecodes covered by an exception handler is */
523- nextExceptionStartPC = nextExceptionStart (verifyData , romMethod , -1 );
523+ nextExceptionPC (verifyData , romMethod , & exceptionStartPC , & exceptionEndPC );
524524
525525 /* walk the bytecodes linearly */
526526 while (pc < length ) {
@@ -567,8 +567,19 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
567567 currentMapData = nextStack (verifyData , & nextMapIndex , & nextStackPC );
568568 }
569569
570- /* Check the stack against the exception handler stack */
571- if (pc == (UDATA ) nextExceptionStartPC ) {
570+ /* Check the current state against the exception handlers if:
571+ * - This is the first bytecode of the try/catch block
572+ * - The temps (locals) type state has changed due to a store
573+ * instruction. If it is within the same exception range ensure
574+ * that the types are still compatible.
575+ */
576+ if ((pc == (UDATA ) exceptionStartPC )
577+ || (tempStoreChange && (exceptionStartPC < pc && pc < exceptionEndPC ))
578+ ) {
579+ /* If this is the first pc of an exception tempStoreChange does not apply. */
580+ if ((pc == (UDATA ) exceptionStartPC ) && tempStoreChange ) {
581+ tempStoreChange = FALSE;
582+ }
572583 handler = J9EXCEPTIONINFO_HANDLERS (exceptionInfo );
573584 SAVE_STACKTOP (liveStack , stackTop );
574585
@@ -579,7 +590,9 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
579590
580591 /* Find all exception handlers from here */
581592 for (i = exceptionInfo -> catchCount ; i ; i -- , handler ++ ) {
582- if (handler -> startPC == pc ) {
593+ if ((handler -> startPC == pc )
594+ || (tempStoreChange && ((UDATA ) start >= handler -> startPC ) && ((UDATA ) start < handler -> endPC ))
595+ ) {
583596 /* Check the maps at the handler PC */
584597 /* Modify the liveStack temporarily to contain the handler exception */
585598 if (handler -> exceptionClassIndex ) {
@@ -595,7 +608,7 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
595608 PUSH (catchClass );
596609 SAVE_STACKTOP (liveStack , stackTop );
597610
598- rc = findAndMatchStack (verifyData , handler -> handlerPC , start );
611+ rc = findAndMatchStack (verifyData , handler -> handlerPC , ( tempStoreChange ? pc : start ) );
599612 if (BCV_SUCCESS != rc ) {
600613 if (BCV_ERR_INSUFFICIENT_MEMORY == rc ) {
601614 goto _outOfMemoryError ;
@@ -609,8 +622,13 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
609622 liveStack -> stackElements [liveStack -> stackBaseIndex ] = originalStackZeroEntry ;
610623 stackTop = originalStackTop ;
611624
612- /* Get next exception start PC of interest */
613- nextExceptionStartPC = nextExceptionStart (verifyData , romMethod , nextExceptionStartPC );
625+ if (FALSE == tempStoreChange ) {
626+ /* Get next exception start PC of interest */
627+ nextExceptionPC (verifyData , romMethod , & exceptionStartPC , & exceptionEndPC );
628+ }
629+ }
630+ if (tempStoreChange ) {
631+ tempStoreChange = FALSE;
614632 }
615633
616634 bcIndex = code + pc ;
@@ -806,8 +824,6 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
806824 goto _inconsistentStack ;
807825 }
808826
809- tempStoreChange = FALSE;
810-
811827 if (type != type1 ) {
812828 if ((type1 != BCV_GENERIC_OBJECT ) || (type & BCV_TAG_BASE_TYPE_OR_TOP )) {
813829 inconsistentStack = TRUE;
@@ -827,56 +843,6 @@ verifyBytecodes (J9BytecodeVerificationData * verifyData)
827843 }
828844 tempStoreChange |= (type != temps [index ]);
829845 STORE_TEMP (index , type );
830-
831- if (checkIfInsideException && tempStoreChange ) {
832- /* If we've stored a value into an arg/local, and it's of a different type than was
833- * originally there, we need to ensure that we are still compatible with all our
834- * exception handlers.
835- *
836- * For all exception handlers covering this instruction
837- */
838- handler = J9EXCEPTIONINFO_HANDLERS (exceptionInfo );
839- SAVE_STACKTOP (liveStack , stackTop );
840-
841- /* Save the current liveStack element zero */
842- /* Reset the stack pointer to push the exception on the empty stack */
843- originalStackTop = stackTop ;
844- originalStackZeroEntry = liveStack -> stackElements [liveStack -> stackBaseIndex ];
845-
846- /* Find all exception handlers from here */
847- for (i = exceptionInfo -> catchCount ; i ; i -- , handler ++ ) {
848- if (((UDATA ) start >= handler -> startPC ) && ((UDATA ) start < handler -> endPC )) {
849- #ifdef DEBUG_BCV
850- printf ("exception map change check at startPC: %d\n" , handler -> startPC );
851- #endif
852- /* Check the maps at the handler PC */
853- /* Modify the liveStack temporarily to contain the handler exception */
854- if (handler -> exceptionClassIndex ) {
855- catchName = J9ROMSTRINGREF_UTF8DATA ((J9ROMStringRef * )(& constantPool [handler -> exceptionClassIndex ]));
856- catchClass = convertClassNameToStackMapType (verifyData , J9UTF8_DATA (catchName ), J9UTF8_LENGTH (catchName ), 0 , 0 );
857- } else {
858- catchClass = BCV_JAVA_LANG_THROWABLE_INDEX ;
859- catchClass <<= BCV_CLASS_INDEX_SHIFT ;
860- }
861-
862- stackTop = & (liveStack -> stackElements [liveStack -> stackBaseIndex ]);
863- PUSH (catchClass );
864- SAVE_STACKTOP (liveStack , stackTop );
865-
866- rc = findAndMatchStack (verifyData , handler -> handlerPC , start );
867- if (BCV_SUCCESS != rc ) {
868- if (BCV_ERR_INSUFFICIENT_MEMORY == rc ) {
869- goto _outOfMemoryError ;
870- }
871- goto _mapError ;
872- }
873- }
874- }
875-
876- /* Restore liveStack */
877- liveStack -> stackElements [liveStack -> stackBaseIndex ] = originalStackZeroEntry ;
878- stackTop = originalStackTop ;
879- }
880846 break ;
881847
882848 case RTV_ARRAY_STORE :
@@ -2839,22 +2805,24 @@ nextStack (J9BytecodeVerificationData *verifyData, UDATA *nextMapIndex, IDATA *n
28392805}
28402806
28412807/* Return the next pc in the method that is an exception handler start address */
2842-
2843- static IDATA
2844- nextExceptionStart (J9BytecodeVerificationData * verifyData , J9ROMMethod * romMethod , IDATA lastPC )
2808+ static void
2809+ nextExceptionPC (J9BytecodeVerificationData * verifyData , J9ROMMethod * romMethod , IDATA * exceptionStartPC , IDATA * exceptionEndPC )
28452810{
28462811 /* Method size */
2847- IDATA nextPC = J9_BYTECODE_SIZE_FROM_ROM_METHOD (romMethod );
2812+ IDATA nextStartPC = J9_BYTECODE_SIZE_FROM_ROM_METHOD (romMethod );
2813+ IDATA nextEndPC = nextStartPC ;
28482814
28492815 if (romMethod -> modifiers & CFR_ACC_HAS_EXCEPTION_INFO ) {
28502816 J9ExceptionInfo * exceptionInfo = J9_EXCEPTION_DATA_FROM_ROM_METHOD (romMethod );
28512817 J9ExceptionHandler * handler = J9EXCEPTIONINFO_HANDLERS (exceptionInfo );
28522818 UDATA i ;
28532819
28542820 for (i = exceptionInfo -> catchCount ; i ; i -- , handler ++ ) {
2855- if (((IDATA ) handler -> startPC ) > lastPC ) {
2856- if (handler -> startPC < (UDATA ) nextPC ) {
2857- nextPC = handler -> startPC ;
2821+ /* exceptionStartPC has the last exception start. */
2822+ if (((IDATA ) handler -> startPC ) > * exceptionStartPC ) {
2823+ if (handler -> startPC < (UDATA ) nextStartPC ) {
2824+ nextStartPC = handler -> startPC ;
2825+ nextEndPC = handler -> endPC ;
28582826 }
28592827 }
28602828 }
@@ -2865,10 +2833,12 @@ nextExceptionStart (J9BytecodeVerificationData *verifyData, J9ROMMethod *romMeth
28652833 J9UTF8_DATA (J9ROMMETHOD_NAME (verifyData -> romMethod )),
28662834 (UDATA ) J9UTF8_LENGTH (J9ROMMETHOD_SIGNATURE (verifyData -> romMethod )),
28672835 J9UTF8_DATA (J9ROMMETHOD_SIGNATURE (verifyData -> romMethod )),
2868- exceptionInfo -> catchCount , lastPC , nextPC ,
2836+ exceptionInfo -> catchCount , * exceptionStartPC , nextStartPC ,
28692837 J9_BYTECODE_SIZE_FROM_ROM_METHOD (romMethod ));
28702838 }
2871- return nextPC ;
2839+
2840+ * exceptionStartPC = nextStartPC ;
2841+ * exceptionEndPC = nextEndPC ;
28722842}
28732843
28742844
0 commit comments