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

8238812: assert(false) failed: bad AD file #2758

Closed
wants to merge 6 commits into from

Conversation

r-v-raghav
Copy link
Member

@r-v-raghav r-v-raghav commented Feb 26, 2021

Found that the earlier PR bug analysis and fix details done is wrong.
Request help to review this revised fix proposal.

Now understood need to fix two types of issues related to the bug-

(i). Crash with only CmpI nodes case.
Sample test case -

public static void test2() {
  for (int i = 5; i > -20; i -= 5) {
    switch (i) {
      case 0:
      case 10:
      case 20:
      case 30:
      case 40:
      case 50:
      case 60:
      case 100:
        res = 42;
        break;
    }
  }
}

// This generates the following subgraph:

/*
// i: -20..0
if (i != 0) {
  // i: -20..-1
  if (i < 0) {   <- /*This is always true but not folded by C2*/
    // Fall through
  } else {
    ...
    CastII(i-1, 0..4) <- /*Replaced by TOP because i-1 range is -21..-1 but still considered reachable by C2 although it is dead code*/
    ...
  }
} else {
  StoreI   <- Due to this additional store on, IfNode::has_shared_region returns false and the fold compares optimization does not kick in
}
*/

Sample IR extracts -

 77  Phi  ===  399  25  389  [[ 658  664  389  80  662  660  659 ]]
 25  ConI  ===  0  [[ 80  77 ]]  #int:0
 80  CmpI  === _  77  25  [[ 81  89 ]]
 81  Bool  === _  80  [[ 82 ]] [ne]
 82  If  ===  399  81  [[ 85  87 ]]
 85  IfFalse  ===  82  [[ 102  336 ]]
 87  IfTrue  ===  82  [[ 90 ]] #1
 89  Bool  === _  80  [[ 90 ]] [lt]
 90  If  ===  87  89  [[ 91  92 ]]
 91  IfTrue  ===  90  [[ 102 ]] #1
 92  IfFalse  ===  90  [[ 156 ]] #0
 336  StoreI  ===  85  359  335  332  [[ 337 ]]
 156  Jump  ===  92  1  [[ 157  160  .......

Fix proposal here includes :

  • Extract the existing non-CmpU related optimization out of old fold_compares_helper(),
  • form new method
    (new fold_dominated_if() added and renamed old fold_compares_helper as fold_to_unsigned()).
  • Call it properly from fold_compares() and related code adjustments.

(ii). fold_compares() not handling CmpU nodes cases.

Sample basic test case -

public static void test3() {
  int local = 0;
  for (int i = 5; i > -20; i -= 5) {
    switch (i) {
    case 0:
    case 10:
    case 20:
    case 30:
    case 40:
    case 50:
    case 100:
      local = 42;
      break;
    }
  }
}
// This generates the following subgraph:
/*
// i: -20..0
if (i != 0) {
  // i: -20..-1
  if (i u< 101) {    <- /*This is always false but not folded by C2 because CmpU is not handled*/
    CastII(i-1, 0..49)  <- /*Replaced by TOP because i-1 range is -21..-1 but still considered reachable by C2 although it is dead code*/
  } else {
    ...
  }
} else {
  ...
}
*/

Sample IR extracts -

 77  Phi  ===  363  20  353  [[ 573  577  572  80  575  353  345  574 ]]
 20  ConI  ===  0  [[ 80  77 ]]  #int:0
 80  CmpI  === _  77  20  [[ 81 ]]
 81  Bool  === _  80  [[ 82 ]] [ne]
 82  If  ===  363  81  [[ 85  87 ]]
 85  IfFalse  ===  82  [[ 102 ]] #0
 87  IfTrue  ===  82  [[ 337 ]] #1
 95  ConI  ===  0  [[ 345 ]]  #int:101
 345  CmpU  === _  77  95  [[ 346 ]]
 346  Bool  === _  345  [[ 337 ]] [lt]
 337  If  ===  87  346  [[ 338  339 ]]
 338  IfFalse  ===  337  [[ 102 ]] #0
 339  IfTrue  ===  337  [[ 135 ]] #1
 135  Jump  ===  339  1  [[ 136  139  142  .....

Proposed fix includes:
Enabling Op_CmpU support in -

  • cmpi_folds(),
  • filtered_int_type() - returns possible restrictive type for input value based on condition control flow for the if (supported CmpU for various condition control types).
  • fold_dominated_if() - checks if dominating if determines the result of current if and above example test case is a basic variant possibility where both CmpNodes compare a common value directly. (Node 77 Phi in above sample). But as mentioned in the comments of new helper function get_base_comparing_value(), there are other possibilities where there might be an AddINode with a constant increment present in between the CmpNodes and the common value compared.
    (Sample IR extract with AddI in between CmpNodes : )
 76  Phi  ===  364  79  354  [[ 576  580  575  80  578  354  344  577 ]]  #int:0..20:www
 79  ConI  ===  0  [[ 80  76 ]]  #int:20
 80  CmpI  === _  76  79  [[ 81 ]]
 81  Bool  === _  80  [[ 82 ]] [ne] 
 82  If  ===  364  81  [[ 85  87 ]]
 85  IfFalse  ===  82  [[ 102 ]] #0
 87  IfTrue  ===  82  [[ 338 ]] #1
 343  ConI  ===  0  [[ 344 ]]  #int:-20
 344  AddI  === _  76  343  [[ 348 ]] 
 347  ConI  ===  0  [[ 348 ]]  #int:281
 348  CmpU  === _  344  347  [[ 349 ]] 
 349  Bool  === _  348  [[ 338 ]] [lt]
 338  If  ===  87  349  [[ 339  340 ]]
 339  IfFalse  ===  338  [[ 102 ]] #0 
 340  IfTrue  ===  338  [[ 136 ]] #1
 136  Jump  ===  340  1  [[ 137  140  143  146 .........

All these variants are handled in get_base_comparing_value() and related test cases added.

  • and related changes in fold_compares().

Found no issues with this proposed fix for various unit tests, reported java_fuzzer case, tier1-7 and pre-integeration tests


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

Download

$ git fetch https://git.openjdk.java.net/jdk pull/2758/head:pull/2758
$ git checkout pull/2758


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

Reviewers

Download

$ git fetch https://git.openjdk.java.net/jdk pull/2758/head:pull/2758
$ git checkout pull/2758

@bridgekeeper
Copy link

bridgekeeper bot commented Feb 26, 2021

👋 Welcome back rraghavan! 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 Feb 26, 2021

@r-v-raghav The following label will be automatically applied to this pull request:

  • hotspot-compiler

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-compiler hotspot-compiler-dev@openjdk.org label Feb 26, 2021
hi = TypeInt::INT->_hi;
break;
default:
assert(false, "should not reach here");
Copy link
Member

Choose a reason for hiding this comment

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

Use ShouldNotReachHere(); instead.

// in-between the CmpNode(s) and the common value we compare.
// Check for the following cases. Then return common value compared
// if present and also save the constant values to be adjusted or
// subtracted due to the possible AddINode in-between.
Copy link
Member

Choose a reason for hiding this comment

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

I would replace adjusted or subtracted and say something like ... and also save the constant value that is added to infer the type of the common value we compare.


Node* res_val = NULL;
this_adj_val = 0;
dom_adj_val = 0;
Copy link
Member

Choose a reason for hiding this comment

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

The caller already initialized these to 0, right?

Node* IfNode::get_base_comparing_value (Node* dom_if, PhaseIterGVN* igvn, jint& this_adj_val, jint& dom_adj_val) {
Node* this_cmp = in(1)->in(1);
Node* dom_cmp = dom_if->in(1)->in(1);
assert(this_cmp->is_Cmp() != false && dom_cmp->is_Cmp() != false, "compare expected");
Copy link
Member

Choose a reason for hiding this comment

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

No need to compare against false. This should be assert(this_cmp->is_Cmp() && dom_cmp->is_Cmp(), ... but instead you could also simply replace declarations above by Node* this_cmp = in(1)->in(1)->as_Cmp() which would include the assert.

Node* dom_val = dom_cmp->in(1);
Node* this_val = this_cmp->in(1);
if (this_val == dom_val) {
res_val = this_val;
Copy link
Member

Choose a reason for hiding this comment

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

Add comments describing that this is Variant 1, same for other if branches below.

res_val = this_val;
} else if (this_val->is_Add() && this_val->in(1) && this_val->in(1) == dom_val) {
const TypeInt* val_t = igvn->type(this_val->in(2))->isa_int();
if (val_t && val_t->is_con()) {
Copy link
Member

Choose a reason for hiding this comment

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

val_t implicitly casts a pointer to a boolean, should be replaced by val_t != NULL. Same below.

jint dom_adj_val = 0;
Node* n = NULL;

n = get_base_comparing_value(dom_if, igvn, this_adj_val, dom_adj_val);
Copy link
Member

Choose a reason for hiding this comment

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

No need to initialize n above. Should be Node* n = get_base_comparing_value(...

Copy link
Member

Choose a reason for hiding this comment

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

Actually, you are not even using n and can therefore just return a boolean from get_base_comparing_value and simplify that method accordingly.


// Check if dominating if determines the result of this if
bool IfNode::fold_dominated_if(ProjNode* proj, PhaseIterGVN* igvn) {
Node* this_cmp = in(1)->in(1);
Copy link
Member

Choose a reason for hiding this comment

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

We only ever use this_cmp->in(1) so you can replace this by Node* this_val = in(1)->in(1)->in(1). Same for dom_cmp below.

failtype = dom_cmp->in(1)->as_Add()->add_ring(failtype, TypeInt::make(-dom_adj_val))->is_int();
}
for (int i = 0; i < 2; ++i) {
const TypeInt* type2 = filtered_int_type(igvn, this_cmp->in(1), proj_out(i));
Copy link
Member

Choose a reason for hiding this comment

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

Why not just name this type?

assert(this_cmp->in(1)->is_Add() != false, "sanity");
type2 = this_cmp->in(1)->as_Add()->add_ring(type2, TypeInt::make(-this_adj_val))->is_int();
}
const TypeInt* res_type = failtype->join(type2)->is_int();
Copy link
Member

Choose a reason for hiding this comment

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

No need to declare res_type, just use type.

@r-v-raghav r-v-raghav marked this pull request as ready for review March 2, 2021 08:15
@openjdk openjdk bot added the rfr Pull request is ready for review label Mar 2, 2021
@mlbridge
Copy link

mlbridge bot commented Mar 2, 2021

Webrevs

Comment on lines 875 to 876
Node* this_cmp = in(1)->in(1)->as_Cmp();
Node* dom_cmp = dom_if->in(1)->in(1)->as_Cmp();
Copy link
Member

Choose a reason for hiding this comment

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

Could be directly turned into an assertion with is_Cmp() instead of using as_Cmp().

if (this_val == dom_val) {
// Variant 1
return true;
} else if (this_val->is_Add() && this_val->in(1) != NULL && this_val->in(1) == dom_val) {
Copy link
Member

Choose a reason for hiding this comment

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

As this_val and dom_val are both non-null: this_val->in(1) != NULL is always true when this_val->in(1) == dom_val holds and thus this_val->in(1) != NULL can be removed. This can also be applied in Variant 3.

dom_adj_val = val_t->get_con();
return true;
}
} else if (this_val->is_Add() && dom_val->is_Add() && this_val->in(1) != NULL && dom_val->in(1) != NULL && this_val->in(1) == dom_val->in(1)) {
Copy link
Member

Choose a reason for hiding this comment

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

Here I think you can just remove one of the non-null checks (in case both are NULL).

@@ -837,8 +857,94 @@ bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNod
return false;
}

// There might be an AddINode (marked with *) with a constant increment
Copy link
Member

Choose a reason for hiding this comment

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

Do we only need to do this for AddNodes? What about SubNodes for example?

Copy link
Member Author

Choose a reason for hiding this comment

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

Never found a SubNode in this case. Always AddI node with integer constant as second input (this constant
can be positive or negative values)

Copy link
Member

Choose a reason for hiding this comment

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

That's because we always convert SubINodes with constant second operand to AddINodes:

// Convert "x-c0" into "x+ -c0".

Copy link
Member

Choose a reason for hiding this comment

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

Okay I see, thanks for the explanation.

Comment on lines 636 to 641
if (is_unsigned && lo >= 0) {
// val u< cmp2 only passes for val >= 0 if cmp2 >= 0
lo = 0;
} else {
lo = TypeInt::INT->_lo;
}
Copy link
Member

Choose a reason for hiding this comment

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

Had some problems following this logic. But I think I got it now. What do you think about reformulating this (and the related comments further down) into

if (is_unsigned && lo >= 0) {
  // cmp2 >= 0: val u<= cmp2 can only pass if val >= 0. Set val->_lo to 0.
} else {
  // The lower bound of val cannot be improved.
  lo = TypeInt::INT->_lo;
}

to make it more clear?


// Original (slightly simplified) fuzzer generated test
public static void test1() {
int i4, i5=99, i6, i9=89;
Copy link
Member

Choose a reason for hiding this comment

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

Minor: Add spaces

@@ -700,16 +720,17 @@ const TypeInt* IfNode::filtered_int_type(PhaseGVN* gvn, Node* val, Node* if_proj
//

// Is the comparison for this If suitable for folding?
bool IfNode::cmpi_folds(PhaseIterGVN* igvn, bool fold_ne) {
bool IfNode::cmpi_folds(PhaseIterGVN* igvn) {
Copy link
Member

Choose a reason for hiding this comment

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

We should probably rename it into cmp_folds now that it is also for unsigned and also update the description above. Shouldn't the description be at fold_compares() anyways? But maybe we want to clean this up in a follow-up RFE.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, will rename cmpi_folds to cmp_folds.

Not changing the fold compares description location for now.
For now maybe it is okay location for description as that is starting of fold_compares implementation (all methods above fold_compares definition seems mainly its helper functions)
.e.g.: See the comment and declarations in [cfgnode.hpp]
........
private:
// Helper methods for fold_compares
bool cmp_folds(PhaseIterGVN* igvn);
bool is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn);
Or yes agree we can change this in a follow-up RFE.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, it's probably best to leave it as it is at the moment and clean it up later in an RFE.

@r-v-raghav
Copy link
Member Author

r-v-raghav commented Mar 3, 2021

Thanks to Tobias and Christian for all help review comments, suggestions.
Please note I could address all the comments suggestions above so far.

Copy link
Member

@TobiHartmann TobiHartmann left a comment

Choose a reason for hiding this comment

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

This looks good to me.

@openjdk
Copy link

openjdk bot commented Mar 3, 2021

@r-v-raghav 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:

8238812: assert(false) failed: bad AD file

Reviewed-by: thartmann, chagedorn, roland

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 134 new commits pushed to the master branch:

  • b7f0b3f: 8252173: Use handles instead of jobjects in modules.cpp
  • a6e34b3: 8262829: Native crash in Win32PrintServiceLookup.getAllPrinterNames()
  • fbe40e8: 8252399: Update mapMulti documentation to use type test pattern instead of instanceof once JEP 375 exits preview
  • 0f2402d: 8263190: Update java.io, java.math, and java.text to use instanceof pattern variable
  • 4f0a12e: 8262323: do not special case JVMCI in tiered compilation policy
  • 3022baa: 8263167: IGV: build fails with "taskdef AutoUpdate cannot be found"
  • 0bc4562: 8263068: Rename safefetch.hpp to safefetch.inline.hpp
  • 5bfc5fd: 8263051: Modernize the code in the java.awt.color package
  • 5b9b170: 8262955: Unify os::fork_and_exec() across Posix platforms
  • 39b1113: 8262161: Refactor manual I/O stream copying in java.desktop to use new convenience APIs
  • ... and 124 more: https://git.openjdk.java.net/jdk/compare/240f2a1bb7c982f7bda15c62abe2313d87654ed5...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 Mar 3, 2021
Copy link
Member

@chhagedorn chhagedorn 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 to me!

@@ -837,8 +857,94 @@ bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNod
return false;
}

// There might be an AddINode (marked with *) with a constant increment
Copy link
Member

Choose a reason for hiding this comment

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

Okay I see, thanks for the explanation.

} else {
// The lower bound of val cannot be improved.
lo = TypeInt::INT->_lo;
}
if (hi != min_jint) {
hi = hi - 1;
}
break;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think there's a bug here (case BoolTest::lt, unsigned comparison) . if cmp2 is [-1, 1] for instance, then lo and hi are unchanged. If the type of val is TypeInt::INT then the resulting type once join is applied is the interval [-1, 1]. But for instance 42 <u -1, 42 is in TypeInt::INT, -1 is in [-1, 1] but 42 is not in the resulting interval. I wonder if other cases in this method has similar issues. Can you fix that one and verify others?

@rwestrel
Copy link
Contributor

rwestrel commented Mar 5, 2021

This fixes the bug when the tests that need to be optimized out are next to one an another and the logic for folding comparisons can be used. It's hard to be certain that it's not possible for the 2 tests be separated by some other control flow. In that case the fix would fail.

A conservative fix would be to not use a narrow type in the CastII that tableswitch/lookupswitch switch introduces. It would be a simpler fix and a more robust one.

@r-v-raghav
Copy link
Member Author

r-v-raghav commented Mar 9, 2021

Thank you @rwestrel for the comments.
Understood your point.
Based on the review comments now planning to -

i. Do proposal by Roland and remove the narrow type from the CastII as fix for this bug task.
As of now found no issues with reported java_fuzzer cases / unit tests, mach5 tier 1-7 & pre-integration tests
for the following changes to avoid use any narrow type in the CastII introduced by lookupswitch.

[src/hotspot/share/opto/parse2.cpp]

   // Clean the 32-bit int into a real 64-bit offset.
   // Otherwise, the jint value 0 might turn into an offset of 0x0800000000.
-  const TypeInt* ikeytype = TypeInt::make(0, num_cases, Type::WidenMin);
   // Make I2L conversion control dependent to prevent it from
   // floating above the range check during loop optimizations.
-  key_val = C->conv_I2X_index(&_gvn, key_val, ikeytype, control());
+  // Do not use a narrow int type here to prevent the data path from dying
+  // while the control path is not removed. This can happen if the type of key_val
+  // is later known to be out of bounds of [0, num_cases] and therefore a narrow cast
+  // would be replaced by TOP while C2 is not able to fold the corresponding range checks.
+#ifdef _LP64
+  key_val = C->constrained_convI2L(&_gvn, key_val, TypeInt::INT, control());
+#endif

ii. Integrate the other proposed fix to improve fold_compares optimizations as a separate enhancement.
(after addressing the comments in filtered_int_type())

@r-v-raghav
Copy link
Member Author

Please note as per the above comments now updated the fix. Request help with review. Thanks.

Copy link
Member

@TobiHartmann TobiHartmann left a comment

Choose a reason for hiding this comment

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

This looks good to me. Please file a follow-up enhancement to integrate the optimization, I think it's still valuable.

Copy link
Member

@TobiHartmann TobiHartmann left a comment

Choose a reason for hiding this comment

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

After quickly discussing this with @rwestrel, it turned out that you need to set CastIINode::_carry_dependency to prevent the CastIINode with TypeInt::INT from being eliminated and re-introducing (JDK-6675699).

@r-v-raghav
Copy link
Member Author

Thanks for the comments @TobiHartmann , @rwestrel .

Please note now revised fix to add a _carry_dependeny argument to constrained_convI2L and set it to true for the CastII introduced by lookupswitch.
(found no issues with reported java_fuzzer cases / unit tests and
tier & pre-integration tests in progress)

Also created followup enhancement task - JDK-8263252.
Please let me know if missed anything.

Copy link
Contributor

@rwestrel rwestrel left a comment

Choose a reason for hiding this comment

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

Thanks for updating the change.

Copy link
Member

@TobiHartmann TobiHartmann 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 to me too.

Copy link
Member

@chhagedorn chhagedorn 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!

@r-v-raghav
Copy link
Member Author

Thanks to @rwestrel @TobiHartmann @chhagedorn for review approvals.

(Now testing done - java_fuzzer cases / unit tests, mach5 tier 1-7 & pre-integration tests)

@r-v-raghav
Copy link
Member Author

/integrate

@openjdk openjdk bot closed this Mar 10, 2021
@openjdk openjdk bot added integrated Pull request has been integrated and removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Mar 10, 2021
@openjdk
Copy link

openjdk bot commented Mar 10, 2021

@r-v-raghav Since your change was applied there have been 149 commits pushed to the master branch:

  • b2a2ddf: 8262438: sun/security/ssl/SSLLogger/LoggingFormatConsistency.java failed with "SocketException: Socket is closed"
  • c8c0234: 8262471: Fix coding style in src/java.base/share/classes/java/lang/CharacterDataPrivateUse.java
  • 4d21a45: 8262913: KlassFactory::create_from_stream should never return NULL
  • fab5676: 8247869: Change NONCOPYABLE to delete the operations
  • c0542ed: 6251901: BasicTextUI: installDefaults method are contrary to the documentation
  • fdd3941: 8263233: Update java.net and java.nio to use instanceof pattern variable
  • 3fe8a46: 8263170: ComboBoxModel documentation refers to a nonexistent type
  • d8a9c3c: 8263002: Remove CDS MiscCode region
  • 67ea3bd: 8263102: Expand documention of Method.isBridge
  • d0c1aec: 8263140: Japanese chars garble in console window in HSDB
  • ... and 139 more: https://git.openjdk.java.net/jdk/compare/240f2a1bb7c982f7bda15c62abe2313d87654ed5...master

Your commit was automatically rebased without conflicts.

Pushed as commit 4b5be40.

💡 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-compiler hotspot-compiler-dev@openjdk.org integrated Pull request has been integrated
Development

Successfully merging this pull request may close these issues.

4 participants