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

8253416: [lworld] C1: incorrect nestmate access to flattened field if nest-host is not loaded #198

Closed
wants to merge 1 commit into from

Conversation

@TobiHartmann
Copy link
Member

@TobiHartmann TobiHartmann commented Sep 24, 2020

C1 incorrectly assumes that a nestmate field access is not flat if the nest-host is not loaded.

We are creating the ciField instance for a field in the nest-host via:
ciField::ciField -> Reflection::verify_member_access -> InstanceKlass::has_nestmate_access_to -> InstanceKlass::nest_host
Resolving the nest host then requires class loading which is not possible from the C1 compiler thread and as a result we end up with partial field information (is_flattened is always false). The code in LIRGenerator::flattened_field_load_prolog then assumes that if !field->is_flattened(), the field is indeed not flattened. However, we can only rely on that information if !needs_patching.

I've completely re-wrote and simplified the complex logic in LIRGenerator::flattened_field_load_prolog and added asserts/checks to make sure we are not attempting to patch flattened inline type field accesses (that functionality could be added though but it's not easy).

This patch also includes the following unrelated changes:

  • The "new" bytecode needs to throw an exception on inline klasses (the klass might be unloaded). The fix makes sure we always take the slow path to "new_instance_no_inline" in that case.
  • The "defaultvalue" bytecode needs to throw an exception on non-inline klasses. We simply deoptimize in that case.
  • Load/stores from/to fields of an empty inline type should be removed.
  • Some refactoring and new asserts.

Progress

  • Change must not contain extraneous whitespace

Issue

  • JDK-8253416: [lworld] C1: incorrect nestmate access to flattened field if nest-host is not loaded

Reviewers

Download

$ git fetch https://git.openjdk.java.net/valhalla pull/198/head:pull/198
$ git checkout pull/198

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Sep 24, 2020

👋 Welcome back thartmann! A progress list of the required criteria for merging this PR into lworld 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 openjdk bot commented Sep 24, 2020

@TobiHartmann 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 more details.

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

8253416: [lworld] C1: incorrect nestmate access to flattened field if nest-host is not loaded

Reviewed-by: fparain

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 no new commits pushed to the lworld branch. If another commit should be pushed before you perform the /integrate command, your PR will be automatically rebased. If you prefer to avoid any potential automatic rebasing, please check the documentation for the /integrate command for further details.

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

@mlbridge
Copy link

@mlbridge mlbridge bot commented Sep 24, 2020

Webrevs

@fparain
Copy link
Collaborator

@fparain fparain commented Sep 24, 2020

Tobias,

I'm still reviewing the code, but here are already two comments:

1 - the empty inline type optimization can be applied to load_indexed() and store_indexed() too.
2 - regarding the assert added at the beginning of copy_inline_content() (needs_patching must be false), it seems to me that the method can still be called with a needs_patching argument being true from the GraphBuilder::withfield() method. In the withfield() method, the needs_patching value is computed with this code:
const bool needs_patching = !holder->is_loaded() ||
!field_modify->will_link(method(), Bytecodes::_withfield) ||
PatchALot;
And the value is passed as is to the copy_inline_content() method without consideration if the field being processed is flattened or not.

Regards,

Fred

@TobiHartmann
Copy link
Member Author

@TobiHartmann TobiHartmann commented Sep 25, 2020

Hi Fred,

thanks for the quick review!

1 - the empty inline type optimization can be applied to load_indexed() and store_indexed() too.

Yes, there are even more optimization opportunities and I'll address these with JDK-8248220. I've only added the empty field load/store removal here for correctness because otherwise we miss adding a null check (see re-enabled TestLWorld::test122 and test123). The "Empty inline type access should be removed" assert in GraphBuilder::copy_inline_content would now catch this.

2 - regarding the assert added at the beginning of copy_inline_content() (needs_patching must be false), it seems to me that the method can still be called with a needs_patching argument being true from the GraphBuilder::withfield() method.

If needs_patching is true, we emit a WithField node that triggers deoptimization, see here. That code will be re-visited by JDK-8228634.

Thanks,
Tobias

Copy link
Collaborator

@fparain fparain left a comment

Tobias,

Thank you for the explanation on the needs_patching flag and the Withfield node.
So, did you keep the needs_patching argument in the copy_inline_content() method only for verification purpose?

Overall, changes look good to me.

Fred

@TobiHartmann
Copy link
Member Author

@TobiHartmann TobiHartmann commented Sep 25, 2020

Thanks a lot for the review!

@TobiHartmann
Copy link
Member Author

@TobiHartmann TobiHartmann commented Sep 25, 2020

So, did you keep the needs_patching argument in the copy_inline_content() method only for verification purpose?

Yes, but we could also move the assert into the caller. What do you prefer?

@fparain
Copy link
Collaborator

@fparain fparain commented Sep 25, 2020

I'm fine with both approaches (assert in the caller or in copy_inline_content()), just pick the solution you think is the safest (I don't think it makes a lot of difference from a performance point of view).

Fred

@TobiHartmann
Copy link
Member Author

@TobiHartmann TobiHartmann commented Sep 28, 2020

Thanks. I'll go with the current version and think about refactoring with JDK-8228634.

@TobiHartmann
Copy link
Member Author

@TobiHartmann TobiHartmann commented Sep 28, 2020

/integrate

@openjdk openjdk bot closed this Sep 28, 2020
@openjdk openjdk bot added integrated and removed ready rfr labels Sep 28, 2020
@openjdk
Copy link

@openjdk openjdk bot commented Sep 28, 2020

@TobiHartmann Pushed as commit 268a9ad.

💡 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
2 participants