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

8286277: CDS VerifyError when calling clone() on object array #8737

Closed

Conversation

iklam
Copy link
Member

@iklam iklam commented May 16, 2022

Problem:

When verifying an invokevirtual bytecode that calls a protected method in a superclass of the current class, the verifier requires that the object being invoked must be a subtype of the current class. This prevents invocation of protected methods in an unrelated class. For example, the following is disallowed -- the type InvokeCloneInvalid cannot invoke clone() on a String:

super public class InvokeCloneInvalid
    version 52:0
{
  public static Method test:"(Ljava/lang/String;)V"
    stack 1 locals 1
  {
    aload_0;
    invokevirtual Method "java/lang/Object".clone:"()Ljava/lang/Object;";
    return;
  }
}

However, there's a special case where invoking Object.clone() is allowed on all object arrays. Here's an example:

super public class InvokeCloneValid
    version 52:0
{
  public static Method test:"([Ljava/lang/Object;)V"
    stack 1 locals 1
  {
    aload_0;
    invokevirtual Method "java/lang/Object".clone:"()Ljava/lang/Object;";
    return;
  }

Before this PR. the Verifier would first do the assignability check. When a failure is encountered, the Verifier then checks for the special case and ignores the failure accordingly.

In the above case, the assignability check will fail because the object being invoked (an Object array) is not assignable to the current class (InvokeCloneValid)

The problem is that CDS remembers all the assignability checks and tries to replay them at runtime. Therefore, it will re-check the assignability of Object Array to InvokeCloneValid, and throw a VerifyError as a result.

Proposed Fix

In ClassVerifier::verify_invoke_instructions(), check the special case first, before doing the assignability check. This way, such invalid-but-ignored assignability checks are no longer performed and thus won't be remembered by CDS.

Testing

Tiers 1 - 4, plus 3 new test cases.


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed (1 review required, with at least 1 reviewer)

Issue

  • JDK-8286277: CDS VerifyError when calling clone() on object array

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/8737/head:pull/8737
$ git checkout pull/8737

Update a local copy of the PR:
$ git checkout pull/8737
$ git pull https://git.openjdk.java.net/jdk pull/8737/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 8737

View PR using the GUI difftool:
$ git pr show -t 8737

Using diff file

Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/8737.diff

@bridgekeeper
Copy link

bridgekeeper bot commented May 16, 2022

👋 Welcome back iklam! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented May 16, 2022

@iklam The following label will be automatically applied to this pull request:

  • hotspot-runtime

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the hotspot-runtime hotspot-runtime-dev@openjdk.org label May 16, 2022
@iklam iklam marked this pull request as ready for review May 16, 2022 23:07
@openjdk openjdk bot added the rfr Pull request is ready for review label May 16, 2022
@mlbridge
Copy link

mlbridge bot commented May 16, 2022

Webrevs

invokevirtual Method "java/lang/Object".clone:"()Ljava/lang/Object;";
return;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Missing newline at end of line.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Member

@dholmes-ora dholmes-ora left a comment

Choose a reason for hiding this comment

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

Is the component type of the array already loaded and verified at this point? My only concern would be that the is_assignable check might load and verify the class as a side-effect, and we have now skipped that. ??

@hseigel
Copy link
Member

hseigel commented May 17, 2022

The is_assignable_check() may or may not load the array class depending on what it needs to check assignability. But neither the verifier nor the JVM has any dependency on the array class being loaded. Note that if this were not a protected access or if name_in_supers() returned null then the is_assignable_check() would not get called. Also note that the verifier tries to avoid loading classes.

Also, the assignability check may cause the array class to get loaded but would not cause it to get linked or verified.

@dholmes-ora
Copy link
Member

Thanks Harold! @hseigel

@openjdk
Copy link

openjdk bot commented May 18, 2022

@iklam This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8286277: CDS VerifyError when calling clone() on object array

Reviewed-by: dholmes, ccheung

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 105 new commits pushed to the master branch:

  • ef7a9f8: 8279185: Support for IsoFields in JapaneseDate/MinguoDate/ThaiBuddhistDate
  • ac274c4: 8286956: Loom: Define test groups for development/porting use
  • 5d8d6da: 8286972: Support the new loop induction variable related PopulateIndex IR node on x86
  • 8122466: 8287113: JFR: Periodic task thread uses period for method sampling events
  • 940e94f: 8285739: disable EscapeBarrier deopt for virtual threads
  • 110d906: 8287103: java/lang/management/ThreadMXBean/VirtualThreadDeadlocks.java fails with Xcomp
  • 8040aa0: 8286908: ECDSA signature should not return parameters
  • 689f80c: 8287153: Whitespace typos in HeapRegion class
  • c906591: 8286391: Address possibly lossy conversions in jdk.compiler
  • 88018c4: 8287150: Remove HeapRegion::block_start_const declaration without definition
  • ... and 95 more: https://git.openjdk.java.net/jdk/compare/a31130fd4056907edcb420761722c629a33273eb...master

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label May 18, 2022
Comment on lines 31 to 32
* @build sun.hotspot.WhiteBox
* @build InvokeCloneValid InvokeCloneInvalid VerifyObjArrayCloneTestApp
Copy link
Member

Choose a reason for hiding this comment

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

Please align line 32 with line 31.

Copy link
Member

@calvinccheung calvinccheung left a comment

Choose a reason for hiding this comment

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

Looks good. Just one nit.

@iklam
Copy link
Member Author

iklam commented May 23, 2022

Thanks @calvinccheung and @dholmes-ora for the review, and @hseigel for confirming the fix.
/integrate

@openjdk
Copy link

openjdk bot commented May 23, 2022

Going to push as commit 646c8aa.
Since your change was applied there have been 105 commits pushed to the master branch:

  • ef7a9f8: 8279185: Support for IsoFields in JapaneseDate/MinguoDate/ThaiBuddhistDate
  • ac274c4: 8286956: Loom: Define test groups for development/porting use
  • 5d8d6da: 8286972: Support the new loop induction variable related PopulateIndex IR node on x86
  • 8122466: 8287113: JFR: Periodic task thread uses period for method sampling events
  • 940e94f: 8285739: disable EscapeBarrier deopt for virtual threads
  • 110d906: 8287103: java/lang/management/ThreadMXBean/VirtualThreadDeadlocks.java fails with Xcomp
  • 8040aa0: 8286908: ECDSA signature should not return parameters
  • 689f80c: 8287153: Whitespace typos in HeapRegion class
  • c906591: 8286391: Address possibly lossy conversions in jdk.compiler
  • 88018c4: 8287150: Remove HeapRegion::block_start_const declaration without definition
  • ... and 95 more: https://git.openjdk.java.net/jdk/compare/a31130fd4056907edcb420761722c629a33273eb...master

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label May 23, 2022
@openjdk openjdk bot closed this May 23, 2022
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels May 23, 2022
@openjdk
Copy link

openjdk bot commented May 23, 2022

@iklam Pushed as commit 646c8aa.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot-runtime hotspot-runtime-dev@openjdk.org integrated Pull request has been integrated
5 participants