Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add the check of BCV_SPECIAL in generating stackmaps #9419

Merged

Conversation

ChengJin01
Copy link
Contributor

@ChengJin01 ChengJin01 commented Apr 30, 2020

The change is to add the check of BCV_SPECIAL when
merging & matching stacks to ensure the uninitializedThis
flag is correctly set up during the generation of stackmaps
so as to match the RI's behavior at runtime verification.

Fixes: #9385

Signed-off-by: Cheng Jin jincheng@ca.ibm.com

@ChengJin01
Copy link
Contributor Author

Verified the failing cases at #9385 and #5676, which works good as expected:

$ ../jdk11_openj9_bcv/bin/java  -cp sootOutput/junit-junit:hamcrest-all-1.3.jar org.junit.runner.JUnitCore org.junit.internal.runners.ErrorReportingRunnerTest
JUnit version 4.13

Time: 0.059
There were 2 failures:
1) givenInvalidTestClassErrorAsCause(org.junit.internal.runners.ErrorReportingRunnerTest)
java.lang.VerifyError: JVMVRFY012 stack shape inconsistent; class=org/junit/internal/runners/ErrorReportingRunner, 
method=<init>(Ljava/lang/Class;Ljava/lang/Throwable;)V, pc=22
	at org.junit.internal.runners.ErrorReportingRunnerTest.givenInvalidTestClassErrorAsCause(ErrorReportingRunnerTest.java:50)
...
2) givenInvalidTestClass_integrationTest(org.junit.internal.runners.ErrorReportingRunnerTest)
java.lang.VerifyError: JVMVRFY012 stack shape inconsistent; class=org/junit/internal/runners/ErrorReportingRunner, 
method=<init>(Ljava/lang/Class;Ljava/lang/Throwable;)V, pc=22
	at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:76)
	at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:125)
	at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:111)


$ ../jdk11_openj9_bcv/bin/java  -agentpath:YourKit-JavaProfiler-2019.1/bin/linux-x86-64/libyjpagent.so  -cp .:spring-aop-5.16.jar:spring-core-5.1.6.jar:commons-logging-1.2.jar -Xint  Target
[YourKit Java Profiler 2019.1-b117] Log file: /home/jincheng/.yjp/log/Target-20155.log
$ (PASSED without any exception)

@ChengJin01
Copy link
Contributor Author

Reviewer: @DanHeidinga

@ChengJin01
Copy link
Contributor Author

ChengJin01 commented Apr 30, 2020

@DanHeidinga, please hold off reviewing the code as I detected the VerifyError was still detected by Hotspot after manually changing the class version to 42 in the class file.

@ChengJin01 ChengJin01 changed the title Ignore the check on uninitializedThis for class version < 49 Add the check of BCV_SPECIAL in generating stackmaps May 5, 2020
@ChengJin01 ChengJin01 force-pushed the bcv_ignore_init_flag_check branch 6 times, most recently from d65321b to 657b969 Compare May 7, 2020 23:24
@ChengJin01
Copy link
Contributor Author

@DanHeidinga , the fix is ready for review as all personal builds & Grinder tests passed without any issue specific to verifier.

Comment on lines 962 to 963
if ((*targetStackPtr != (UDATA) (BCV_BASE_TYPE_TOP))
&& !(*targetStackPtr & BCV_SPECIAL)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the local targetItem already initialized to be *targetStackPtr? Can the local be used here?

Also, please use explicit boolean conditions

Suggested change
if ((*targetStackPtr != (UDATA) (BCV_BASE_TYPE_TOP))
&& !(*targetStackPtr & BCV_SPECIAL)
if ((targetItem != (UDATA) (BCV_BASE_TYPE_TOP))
&& ((targetItem & BCV_SPECIAL) == 0)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really checking for (targetItem & BCV_SPECIAL_INIT) != 0 to avoid changing to BCV_BASE_TYPE_TOP in that case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't the local targetItem already initialized to be *targetStackPtr? Can the local be used here? Also, please use explicit boolean conditions

Yes, we should use targetItem instead of *targetStackPtr in this case. Updated as suggested.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really checking for (targetItem & BCV_SPECIAL_INIT) != 0 to avoid changing to BCV_BASE_TYPE_TOP in that case?

Yes, it was based on the thorough debugging with the class files in question. It is obvious that the intention of the original implementation was to reserve the BCV_SPECIAL bits so as to set up uninitializedThis in setInitializedThisStatus but somehow the bits were wipe out here accidentally to deal with other situations. The BCV_SPECIAL bits can't be restored back or reset up later in simulateStack once they are removed here. That's why we need to handle the case on both mergeStack() and matchStack() to ensure the BCV_SPECIAL bits from the generated stackmaps are correctly addressed.

@@ -114,7 +114,7 @@ TraceExit=Trc_RTV_findAndMatchStack_Exit Overhead=1 Level=3 Template="findAndMat
TraceEntry=Trc_RTV_matchStack_Entry Overhead=1 Level=3 Template="matchStack - inlineMatch is %i"
TraceException=Trc_RTV_matchStack_DepthMismatchException Overhead=1 Level=1 Template="matchStack - %.*s %.*s%.*s mismatched stack depths, live = %i, target = %i"
TraceException=Trc_RTV_matchStack_IncompatibleClassException Overhead=1 Level=1 Template="matchStack - %.*s %.*s%.*s incompatible objects at offset %i, live = 0x%X, target = 0x%X"
TraceException=Trc_RTV_matchStack_PrimitiveMismatchException Overhead=1 Level=1 Template="matchStack - %.*s %.*s%.*s incompatible primitives at offset %i, live = 0x%X, target = 0x%X"
TraceException=Trc_RTV_matchStack_PrimitiveOrSpecialMismatchException Overhead=1 Level=1 Template="matchStack - %.*s %.*s%.*s incompatible primitives or special at offset %i, live = 0x%X, target = 0x%X"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracepoints aren't changed. If necessary, the current one is obsoleted and a new one is introduced at the end of the file so the index & format never change

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree and moved the new tracepoint to the end of the file.

Comment on lines 348 to 352
/* Only skip the check on the target slot with BCV_SPECIAL for the generated stackmaps
* as this slot is set up based on the bytecode itself rather than decompressed stackmaps.
*/
} else if ((*targetPtr != BCV_BASE_TYPE_TOP) && !((*targetPtr & BCV_SPECIAL) && verifyData->createdStackMap)) {
Trc_RTV_matchStack_PrimitiveOrSpecialMismatchException(verifyData->vmStruct,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* Only skip the check on the target slot with BCV_SPECIAL for the generated stackmaps
* as this slot is set up based on the bytecode itself rather than decompressed stackmaps.
*/
} else if ((*targetPtr != BCV_BASE_TYPE_TOP) && !((*targetPtr & BCV_SPECIAL) && verifyData->createdStackMap)) {
Trc_RTV_matchStack_PrimitiveOrSpecialMismatchException(verifyData->vmStruct,
} else if (*targetPtr != BCV_BASE_TYPE_TOP) {
if (((*targetPtr & BCV_SPECIAL) != 0) && verifyData->createdStackMap) {
/* Generated stackmaps can skip the check on the target slot with BCV_SPECIAL
* as this slot is set up based on the bytecode itself rather than decompressed stackmaps.
*/
} else {
Trc_RTV_matchStack_PrimitiveOrSpecialMismatchException(verifyData->vmStruct,
.....
rc = BCV_FAIL; /* fail - primitive or special mismatch */
goto _incompatibleType;
}
}

Reorganizing this may be clearer about when the check is being skipped vs not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree and updated against the suggestion above.

@@ -114,7 +114,6 @@ TraceExit=Trc_RTV_findAndMatchStack_Exit Overhead=1 Level=3 Template="findAndMat
TraceEntry=Trc_RTV_matchStack_Entry Overhead=1 Level=3 Template="matchStack - inlineMatch is %i"
TraceException=Trc_RTV_matchStack_DepthMismatchException Overhead=1 Level=1 Template="matchStack - %.*s %.*s%.*s mismatched stack depths, live = %i, target = %i"
TraceException=Trc_RTV_matchStack_IncompatibleClassException Overhead=1 Level=1 Template="matchStack - %.*s %.*s%.*s incompatible objects at offset %i, live = 0x%X, target = 0x%X"
TraceException=Trc_RTV_matchStack_PrimitiveMismatchException Overhead=1 Level=1 Template="matchStack - %.*s %.*s%.*s incompatible primitives at offset %i, live = 0x%X, target = 0x%X"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old tracepoint has to stay here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

The change is to add the check of BCV_SPECIAL when merging & matching
stacks to ensure the uninitializedThis flag is correctly set up during
the generation of stackmaps so as to match the RI's behavior at runtime
verification.[ci skip]

Fixes: eclipse-openj9#9385

Signed-off-by: Cheng Jin <jincheng@ca.ibm.com>
Copy link
Member

@DanHeidinga DanHeidinga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@DanHeidinga
Copy link
Member

Jenkins test sanity plinux,zlinux jdk8

@DanHeidinga
Copy link
Member

Jenkins test sanity win,osx jdk11

@DanHeidinga
Copy link
Member

Jenkins test sanity xlinux jdk14

@DanHeidinga
Copy link
Member

Ported to 0.21 release branch in #9951

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

J9(1.8.0_232) and J9(11.0.5): failed to throw VerifyError?
2 participants