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

8261137: Optimization of Box nodes in uncommon_trap #2401

Closed
wants to merge 13 commits into from

Conversation

@Wanghuang-Huawei
Copy link

@Wanghuang-Huawei Wanghuang-Huawei commented Feb 4, 2021

JDK-8075052 has removed useless autobox. However, in some cases, the box is still saved. For instance:

@Benchmark
public void testMethod(Blackhole bh) {
  int sum = 0;
  for (int i = 0; i < data.length; i++) {
      Integer ii = Integer.valueOf(data[i]);
      if (i < data.length) {
          sum += ii.intValue();
      }
  }
  bh.consume(sum);
}

Although the variable ii is only used at ii.intValue(), it cannot be eliminated as a result of being used by a hidden uncommon_trap.
The uncommon_trap is generated by the optimized "if", because its condition is always true.

We can postpone box in uncommon_trap in this situation. We treat box as a scalarized object by adding a SafePointScalarObjectNode in the uncommon_trap node,
and deleting the use of box:

There is no additional fail/error(s) of jtreg after this patch.

I adjust my codes and add a new benchmark

public class MyBenchmark {

    static int[] data = new int[10000];

    static {
        for(int i = 0; i < data.length; ++i) {
            data[i] = i * 1337 % 7331;
        }
    }

    @Benchmark
    public void testMethod(Blackhole bh) {
      int sum = 0;
      for (int i = 0; i < data.length; i++) {
          Integer ii = Integer.valueOf(data[i]);
          black();
          if (i < 100000) {
              sum += ii.intValue();
          }
      }
      bh.consume(sum);
    }

    public void black(){}
}

aarch64:
base line:

Benchmark                     Mode  Samples   Score  Score error  Units
o.s.MyBenchmark.testMethod    avgt       30  88.513        1.111  us/op

opt:

Benchmark                     Mode  Samples   Score  Score error  Units
o.s.MyBenchmark.testMethod    avgt       30  52.776        0.096  us/op

x86:
base line:

Benchmark                     Mode  Samples   Score  Score error  Units
o.s.MyBenchmark.testMethod    avgt       30  81.066        3.156  us/op

opt:

Benchmark                     Mode  Samples   Score  Score error  Units
o.s.MyBenchmark.testMethod    avgt       30  55.596        0.775  us/op

Progress

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

Issue

  • JDK-8261137: Optimization of Box nodes in uncommon_trap

Reviewers

Contributors

  • Wu Yan <wuyan34@huawei.com>
  • Ai Jiaming <aijiaming1@huawei.com>

Reviewing

Using git

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

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

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 2401

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

Using diff file

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

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Feb 4, 2021

👋 Welcome back whuang! 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.

Loading

@openjdk openjdk bot added the rfr label Feb 4, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Feb 4, 2021

@Wanghuang-Huawei 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.

Loading

@Wanghuang-Huawei
Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei commented Feb 4, 2021

/contributor add Wu Yan wuyan34@huawei.com

Loading

@openjdk
Copy link

@openjdk openjdk bot commented Feb 4, 2021

@Wanghuang-Huawei
Contributor Wu Yan <wuyan34@huawei.com> successfully added.

Loading

@Wanghuang-Huawei
Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei commented Feb 4, 2021

/contributor add Ai Jiaming aijiaming1@huawei.com

Loading

@openjdk
Copy link

@openjdk openjdk bot commented Feb 4, 2021

@Wanghuang-Huawei
Contributor Ai Jiaming <aijiaming1@huawei.com> successfully added.

Loading

@openjdk
Copy link

@openjdk openjdk bot commented Feb 4, 2021

@Wanghuang-Huawei
Contributor Ai Jiaming <aijiaming1@huawei.com> successfully added.

Loading

@mlbridge
Copy link

@mlbridge mlbridge bot commented Feb 4, 2021

Loading

@theRealELiu
Copy link
Contributor

@theRealELiu theRealELiu commented Feb 4, 2021

I was wandering if we can remove the useless if as it's always true in this case. Do you know why this kind of if haven't been eliminated by GVN phase?

Loading

src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
@Wanghuang-Huawei
Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei commented Feb 5, 2021

I was wandering if we can remove the useless if as it's always true in this case. Do you know why this kind of if haven't been eliminated by GVN phase?
It is a good idea . However, C2 might not optimize some if for many reasons:

  • This situation can also be triggered in calling other method. For example :
public class MyBenchmark {

  static int[] data = new int[10000];

  static {
      for(int i = 0; i < data.length; ++i) {
          data[i] = 299;
      }
  }

  @Benchmark
  public void testMethod(Blackhole bh) {
    int sum = 0;
    for (int i = 0; i < data.length; i++) {
      Integer ii = Integer.valueOf(data[i]);
      sum += abs(ii);
    }
    bh.consume(sum);
  }

  public int abs(Integer ii) {
    if (ii.intValue() > 0) {
      return ii.intValue();
    } else {
      return 0 - ii.intValue();
    }
  }
}

The method abs will be inlined when it is hot enough. However, this If can not be eliminated.

  • The case in the JDK-8261137 is just like this case:
public class MyBenchmark {

    static int[] data = new int[10000];

    static {
        for(int i = 0; i < data.length; ++i) {
            data[i] = i * 1337 % 7331;
        }
    }

    @Benchmark
    public void testMethod(Blackhole bh) {
      int sum = 0;
      for (int i = 0; i < data.length; i++) {
          Integer ii = Integer.valueOf(data[i]);
          if (i < 100000) {
              sum += ii.intValue();
          }
      }
      bh.consume(sum);
    }
}

Loading

@theRealELiu
Copy link
Contributor

@theRealELiu theRealELiu commented Feb 7, 2021

I was wandering if we can remove the useless if as it's always true in this case. Do you know why this kind of if haven't been eliminated by GVN phase?

It is a good idea . However, C2 might not optimize some if for many reasons:

  • This situation can also be triggered in calling other method. For example :
public class MyBenchmark {

  static int[] data = new int[10000];

  static {
      for(int i = 0; i < data.length; ++i) {
          data[i] = 299;
      }
  }

  @Benchmark
  public void testMethod(Blackhole bh) {
    int sum = 0;
    for (int i = 0; i < data.length; i++) {
      Integer ii = Integer.valueOf(data[i]);
      sum += abs(ii);
    }
    bh.consume(sum);
  }

  public int abs(Integer ii) {
    if (ii.intValue() > 0) {
      return ii.intValue();
    } else {
      return 0 - ii.intValue();
    }
  }
}

The method abs will be inlined when it is hot enough. However, this If can not be eliminated.

  • The case in the JDK-8261137 is just like this case:
public class MyBenchmark {

    static int[] data = new int[10000];

    static {
        for(int i = 0; i < data.length; ++i) {
            data[i] = i * 1337 % 7331;
        }
    }

    @Benchmark
    public void testMethod(Blackhole bh) {
      int sum = 0;
      for (int i = 0; i < data.length; i++) {
          Integer ii = Integer.valueOf(data[i]);
          if (i < 100000) {
              sum += ii.intValue();
          }
      }
      bh.consume(sum);
    }
}

Thanks for your explanation. This makes more sense to me now.

Loading

Copy link
Contributor

@vnkozlov vnkozlov left a comment

I am a little concern about stretching uses of input value outside scope where it is created (for example, loop's variable or a value depending on it).
This optimization may work only because boxed values are immutable.
I will run our tests with this changes.

Loading

src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Feb 8, 2021

Our tier1-4 testing passed

Loading

@navyxliu
Copy link
Contributor

@navyxliu navyxliu commented Feb 9, 2021

I was wandering if we can remove the useless if as it's always true in this case. Do you know why this kind of if haven't been eliminated by GVN phase?

Eventually, c2 should know that `i < data.length' is true. it should be done by GCP later.

The example is a special case. you can remove this " if (i < data.length)" here. Generally, target code can look like this. c2 speculatively generates an uncommon_trap of "unstable_if".

  for (int i = 0; i < data.length; i++) {
      Integer ii = Integer.valueOf(data[i]);
      if (cond) { //likely
          sum += ii.intValue();
      }
  }

Loading

src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
Copy link

@iwanowww iwanowww left a comment

The improvement you are proposing is not specific to uncommon traps, but can be generalized to any debug usage at safepoints.

The downside is that, in general, rematerialization logic has to use the corresponding pure function in order to materialize the eliminated instance. In this particular case (primitive boxing), it has to take into account the caching effects of primitive box factories. Otherwise, user code can encounter identity paradoxes with rematerialized primitive box instances.

I don't see how the scalarization logic you propose preserves identity constraints imposed by valueOf factories.

Loading

src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Feb 10, 2021

The improvement you are proposing is not specific to uncommon traps, but can be generalized to any debug usage at safepoints.

The downside is that, in general, rematerialization logic has to use the corresponding pure function in order to materialize the eliminated instance. In this particular case (primitive boxing), it has to take into account the caching effects of primitive box factories. Otherwise, user code can encounter identity paradoxes with rematerialized primitive box instances.

I don't see how the scalarization logic you propose preserves identity constraints imposed by valueOf factories.

Yes, it seems this optimization introduces the issue we had with Graal (8223320):
"C2 doesn't model Integer.valueOf() as anything special. It just inlines it. So the check that determines whether to allocate a new Integer or take one from the cache always happens at runtime. Graal models it as a BoxNode. It is correctly lowered, however, if it needs to be present in a JVM state, it is described as an allocation. So the decision whether to allocate or take the cached value has to happen during the deopt."
There is code in deoptimizer for JVMCI which looks for cached Boxed values. We may need to adopt it for C2 EA for this optimization to work.

Loading

@veresov
Copy link
Contributor

@veresov veresov commented Feb 12, 2021

The improvement you are proposing is not specific to uncommon traps, but can be generalized to any debug usage at safepoints.
The downside is that, in general, rematerialization logic has to use the corresponding pure function in order to materialize the eliminated instance. In this particular case (primitive boxing), it has to take into account the caching effects of primitive box factories. Otherwise, user code can encounter identity paradoxes with rematerialized primitive box instances.
I don't see how the scalarization logic you propose preserves identity constraints imposed by valueOf factories.

Yes, it seems this optimization introduces the issue we had with Graal (8223320):
"C2 doesn't model Integer.valueOf() as anything special. It just inlines it. So the check that determines whether to allocate a new Integer or take one from the cache always happens at runtime. Graal models it as a BoxNode. It is correctly lowered, however, if it needs to be present in a JVM state, it is described as an allocation. So the decision whether to allocate or take the cached value has to happen during the deopt."
There is code in deoptimizer for JVMCI which looks for cached Boxed values. We may need to adopt it for C2 EA for this optimization to work.

In addition to using the logic that we already have there for Graal (see Deoptimization::get_cached_box()), you need to track where the box came from. If it comes as a result of valueOf() then it has to come from the caches, if it's something that the user allocates with new Integer(x), then it should be just a normal scalarized object.

Loading

@veresov
Copy link
Contributor

@veresov veresov commented Feb 12, 2021

Also, I don't know if EA can handle a case when an Integer that is coming from an allocation and from a valueOf() are both inputs to a phi.

Integer i = p ? new Integer(i1) : Integer.valueOf(i2);
deopt();
int use = i.intValue();

If it does, then we'd need to force materialization.

Loading

@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Feb 12, 2021

Also, I don't know if EA can handle a case when an Integer that is coming from an allocation and from a valueOf() are both inputs to a phi.

Integer i = p ? new Integer(i1) : Integer.valueOf(i2);
deopt();
int use = i.intValue();

If it does, then we'd need to force materialization.

Currently C2 EA can't scalarize merged allocations. So this is not an issue for now but may be in a future. Also C2 does not replace valueOf() with scalar node - it inlines it. As result you have branches with allocation and load from cache.

Only this patch propose to use scalar node for valueOf() for the first time in C2. But it is replaced only in case it is directly referenced by debug info (no Phi or other nodes in between). So I think it is safe if we use AutoBoxObjectValue for it.

Loading

Copy link
Contributor

@vnkozlov vnkozlov left a comment

Please, add test case which verifies that Box is scalarized by forking process and checking output of run with -XX:+PrintEliminateAllocations flag.
You also need a test which triggers deoptimization and execute code for Box object reallocation/initialization or load from cache.
A test should also verifies that box object identity matches after deoptimization in case when object is loaded from cache.

Loading

@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Mar 10, 2021

@iwanowww Do you think we should add checks for EnableVectorAggressiveReboxing and EliminateAutoBox into deoptimization code or guard Vector API code and this optimization with C->do_escape_analysis()?

The former (additional checks for EnableVectorAggressiveReboxing and EliminateAutoBox).
Vector box elimination is unrelated to escape analysis pass and should work irrespective of whether EA is turned on or off.

Okay. I will do it for 8263125 fix.

Loading

@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Mar 11, 2021

I added both flags checks in deoptimizer in #2924
@Wanghuang-Huawei you don't need to do it here.

But I am lost on the status of these changes. Do you have other updates for them? Or current 05 is final?
You found that the testing failure is not related and addressed other my and @iwanowww questions.
If 05 version is final and I already tested it, we are ready for approval.

Loading

@Wanghuang-Huawei
Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei commented Mar 15, 2021

I added both flags checks in deoptimizer in #2924
@Wanghuang-Huawei you don't need to do it here.

But I am lost on the status of these changes. Do you have other updates for them? Or current 05 is final?
You found that the testing failure is not related and addressed other my and @iwanowww questions.
If 05 version is final and I already tested it, we are ready for approval.

OK. Thank you for your work.
I will update some codes to answer the review of @iwanowww. It will be 06 version.

Loading

@Wanghuang-Huawei
Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei commented Mar 17, 2021

@iwanowww Can you review my new 06 version? I have split is_boxing_call from is_pure_call. :-)

Loading

Copy link

@iwanowww iwanowww left a comment

Overall, looks good.

Some refactoring suggestions.

Loading

src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
src/hotspot/share/opto/callGenerator.cpp Outdated Show resolved Hide resolved
Loading
Copy link

@iwanowww iwanowww left a comment

Looks good.

Some more minor cleanup suggestions follow.

Loading


static void scalarize_debug_usages(CallNode* call, Node* resproj) {
Unique_Node_List safepoints;
for (DUIterator_Fast imax, i = resproj->fast_outs(imax); i < imax; i++) {

Choose a reason for hiding this comment

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

No need to collect safepoints anymore. You can process users while iterating over them.

for (DUIterator_Last imin, i = res->last_outs(imin); i >= imin;) {
  SafePointNode* sfpt = res->last_out(i)->as_SafePoint();
  ...
  int num_edges = sfpt->replace_edges_in_range(res, sobj, start, end);  
  i -= num_edges;
}

Loading

}

#ifndef PRODUCT
if (PrintEliminateAllocations && safepoints.size() > 0) {
Copy link

@iwanowww iwanowww Mar 19, 2021

Choose a reason for hiding this comment

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

safepoints.size() > 0 is redundand.

Also, I'd move the diagnostic logic to the end of the method after all the users are processed.

Loading

ProjNode* res = resproj->as_Proj();
Node* sfpt = safepoints.pop();

ciInstanceKlass* klass = call->as_CallStaticJava()->method()->holder();

Choose a reason for hiding this comment

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

klass is loop invariant and can be moved out of the loop (along with n_fields).

Loading

uint first_ind = sfpt->req() - sfpt->jvms()->scloff();
Node* sobj = new SafePointScalarObjectNode(gvn.type(res)->isa_oopptr(),
#ifdef ASSERT
call->isa_Allocate(),

Choose a reason for hiding this comment

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

It is always NULL since call can't be an Allocate.

Loading

Copy link
Contributor

@vnkozlov vnkozlov Mar 23, 2021

Choose a reason for hiding this comment

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

It was my suggestion to pass call node as allocation so that we could trace back for what node SafePointScalarObject was created because you may have several Box objects for which we create SafePointScalarObject nodes.
I think we can change argument (and field type) to CallNode. And have assert in SafePointScalarObject constructor to check that it is either Allocate node or Boxing Call node.

Loading

Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei Mar 24, 2021

Choose a reason for hiding this comment

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

Thank you for your review. I will change the SafePointScalarObject constructor in next push.

Loading

@openjdk openjdk bot added the ready label Mar 19, 2021
/*
* @test
* @bug 8261137
* @requires vm.debug == true & vm.flavor == "server"
Copy link
Contributor

@vnkozlov vnkozlov Mar 23, 2021

Choose a reason for hiding this comment

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

Exclude Graal because it would not have output you expect. Instead of checking for "server" check for C2:
@requires vm.debug == true & vm.compiler2.enabled

Loading

Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei Mar 24, 2021

Choose a reason for hiding this comment

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

OK. I will do that ASAP.

Loading

@@ -0,0 +1,88 @@
/*
Copy link
Contributor

@vnkozlov vnkozlov Mar 23, 2021

Choose a reason for hiding this comment

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

The test should be in compiler/eliminateAutobox directory. compiler/c2 is collection of old unsorted tests.

Loading

Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei Mar 24, 2021

Choose a reason for hiding this comment

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

OK. I will do that.

Loading

@@ -0,0 +1,113 @@
/*
Copy link
Contributor

@vnkozlov vnkozlov Mar 23, 2021

Choose a reason for hiding this comment

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

The test should be in compiler/eliminateAutobox directory.

Loading

Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei Mar 24, 2021

Choose a reason for hiding this comment

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

OK. Thank you for your review.

Loading

uint first_ind = sfpt->req() - sfpt->jvms()->scloff();
Node* sobj = new SafePointScalarObjectNode(gvn.type(res)->isa_oopptr(),
#ifdef ASSERT
call->isa_Allocate(),
Copy link
Contributor

@vnkozlov vnkozlov Mar 23, 2021

Choose a reason for hiding this comment

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

It was my suggestion to pass call node as allocation so that we could trace back for what node SafePointScalarObject was created because you may have several Box objects for which we create SafePointScalarObject nodes.
I think we can change argument (and field type) to CallNode. And have assert in SafePointScalarObject constructor to check that it is either Allocate node or Boxing Call node.

Loading

#ifdef ASSERT
, _alloc(alloc)
#endif
{
#ifdef ASSERT
if (alloc != nullptr) {
assert(alloc->is_Allocate() || alloc->as_CallStaticJava()->is_boxing_method(), "unexpected alloc");
Copy link
Contributor

@vnkozlov vnkozlov Mar 24, 2021

Choose a reason for hiding this comment

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

Add dumping of alloc before this assert to know it during failure without rerunning test:

if (!alloc->is_Allocate() && !alloc->as_CallStaticJava()->is_boxing_method()) {
  alloc->dump();
}

Loading

Copy link

@iwanowww iwanowww Mar 24, 2021

Choose a reason for hiding this comment

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

It was my suggestion to pass call node as allocation so that we could trace back for what node SafePointScalarObject was created because you may have several Box objects for which we create SafePointScalarObject nodes.

The problem with that is alloc quickly becomes stale since allocations/calls are removed shortly after scalarization takes place. The only usage of alloc() is in PhaseMacroExpand::scalar_replacement:

assert(scobj->alloc() == alloc, "sanity");

Regarding the assert, frankly speaking, it looks repetitive and verbose. I'd prefer to just see it folded into:

assert(alloc == NULL || alloc->is_Allocate() || alloc->as_CallStaticJava()->is_boxing_method(), "unexpected call node");

Or introduce a helper method to dump relevant info about the problematic node:

assert(alloc == NULL || alloc->is_Allocate() || alloc->as_CallStaticJava()->is_boxing_method(), "unexpected call node: %s", dump_node(alloc));

Also, alloc == NULL case can be eliminated by avoiding passing NULL in PhaseVector::scalarize_vbox_node().

Loading

Copy link
Contributor

@vnkozlov vnkozlov Mar 30, 2021

Choose a reason for hiding this comment

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

Okay. Lets do as @iwanowww suggesting.

Loading

Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei Mar 31, 2021

Choose a reason for hiding this comment

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

Okay. Lets do as @iwanowww suggesting.

Should we implement dump_node or should we just use assert(alloc == NULL || alloc->is_Allocate() || alloc->as_CallStaticJava()->is_boxing_method(), "unexpected call node"); without dumping?

Loading

Copy link
Contributor

@vnkozlov vnkozlov Apr 1, 2021

Choose a reason for hiding this comment

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

Creating node's dump string in separate method is complicated.
We can just use false in assert:

#ifdef ASSERT
  if (alloc != nullptr && !alloc->is_Allocate() && !alloc->as_CallStaticJava()->is_boxing_method()) {
    alloc->dump();
    assert(false, "unexpected call node for scalar replacement");
  }
#endif

Loading

Copy link
Contributor

@vnkozlov vnkozlov Apr 1, 2021

Choose a reason for hiding this comment

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

I did not see your latest changes before answering your question. You did exactly as I suggested. Good.

Loading

Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei Apr 2, 2021

Choose a reason for hiding this comment

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

Thank you for your review.

Loading

Copy link
Contributor

@vnkozlov vnkozlov left a comment

Good.

Loading

@Wanghuang-Huawei
Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei commented Apr 2, 2021

Good.

Thank you for your approval. ;-)

Loading

@Wanghuang-Huawei
Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei commented Apr 2, 2021

/integrate

Loading

@openjdk openjdk bot added the sponsor label Apr 2, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Apr 2, 2021

@Wanghuang-Huawei
Your change (at version 31f215b) is now ready to be sponsored by a Committer.

Loading

@Wanghuang-Huawei
Copy link
Author

@Wanghuang-Huawei Wanghuang-Huawei commented Apr 6, 2021

@vnkozlov Can you do me a favor to /sponsor this patch?

Loading

Copy link
Member

@TobiHartmann TobiHartmann left a comment

Looks good to me too.

Loading

@vnkozlov
Copy link
Contributor

@vnkozlov vnkozlov commented Apr 6, 2021

I will wait results of testing Vladimir I. is running.

Loading

@iwanowww
Copy link

@iwanowww iwanowww commented Apr 7, 2021

Test results (hs-tier1 - hs-tier4) are clean.

/sponsor

Loading

@openjdk openjdk bot closed this Apr 7, 2021
@openjdk
Copy link

@openjdk openjdk bot commented Apr 7, 2021

@iwanowww @Wanghuang-Huawei Since your change was applied there have been 217 commits pushed to the master branch:

  • 92fad1b: 8264680: Use the blessed modifier order in java.desktop
  • 17202c8: 8264748: Do not include arguments.hpp from compilerDefinitions.hpp
  • c3abdc9: 8264797: Do not include klassVtable.hpp from instanceKlass.hpp
  • eb5c097: 8262389: Use permitted_enctypes if default_tkt_enctypes or default_tgs_enctypes is not present
  • bfb034a: 8264524: jdk/internal/platform/docker/TestDockerMemoryMetrics.java fails due to swapping not working
  • a756d8d: 8264759: x86_32 Minimal VM build failure after JDK-8262355
  • 0f13e22: 8264791: java/util/Random/RandomTestBsi1999.java failed "java.security.SecureRandom nextFloat consecutive"
  • 4bb80f3: 8262898: com/sun/net/httpserver/bugs/8199849/ParamTest.java times out
  • 2f51699: 8264554: X509KeyManagerImpl calls getProtectionParameter with incorrect alias
  • 114e3c3: 8263856: Github Actions for macos/aarch64 cross-build
  • ... and 207 more: https://git.openjdk.java.net/jdk/compare/fd3a33a85667eec10f5a41dd7ffd7b1e2e410141...master

Your commit was automatically rebased without conflicts.

Pushed as commit eab8455.

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

Loading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment