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

8256020: Shenandoah: Don't resurrect objects during evacuation on AS_NO_KEEPALIVE #1113

Closed
wants to merge 6 commits into from

Conversation

rkennke
Copy link
Contributor

@rkennke rkennke commented Nov 8, 2020

In Shenandoah-testing, we noticed that compiler/jsr292/CallSiteDepContextTest.java fails with the following error:

CONF=linux-x86_64-server-fastdebug make run-test TEST=compiler/jsr292/CallSiteDepContextTest.java TEST_VM_OPTS="-XX:+UseShenandoahGC -XX:+ShenandoahVerify"

#  Internal Error (/home/rkennke/src/openjdk/jdk/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp:92), pid=2318905, tid=2318938
#  Error: Before Updating References, Marked; Must be marked in complete bitmap

Referenced from:
  interior location: 0x00000000fff8514c
  0x00000000fff85140 - klass 0x000000010004ecd8 java.lang.invoke.MutableCallSite
        allocated after mark start
    not after update watermark
        marked strong
        marked weak
    not in collection set
  mark: mark(is_neutral no_hash age=0)
  region: | 2565|R  |BTE     fff80000,     fffc0000,     fffc0000|TAMS     fff80000|UWM     fffc0000|U   256K|T     0B|G   256K|S     0B|L     0B|CP   0

Object:
  0x00000000d80a9210 - klass 0x000000010004cf58 java.lang.invoke.DirectMethodHandle
    not allocated after mark start
    not after update watermark
    not marked strong
    not marked weak
        in collection set
  mark: mark(is_neutral no_hash age=0)
  region: |    9|CS |BTE     d8080000,     d80c0000,     d80c0000|TAMS     d80c0000|UWM     d80c0000|U   256K|T   256K|G     0B|S     0B|L 22464B|CP   0

Forwardee:
  (the object itself)

In other words, a reachable (marked) MutableCallSite references an unreachable DirectMethodHandle. That reference would subsequently become dangling and lead to crashes if accessed.

I narrowed it down to the access in Dependencies::DepStream::recorded_oop_at(int i) which is done as 'strong', which means that it would return the reference even if it is unreachable, e.g. during concurrent class-unloading. This resurrection of the unreachable DMH is potentially fatal: eventually the reference will become dangling (after GC) and lead to crashes when accessed. I believe that access should be 'phantom' instead which causes GCs like Shenandoah and ZGC to return NULL when encountering unreachable objects.

(Notice that the bug only manifested after JDK-8255691, we accidentally applied the resurrection-preventing weak-LRB on strong access too)

Testing:

  • the offending CallSiteDepContextTest.java +UseShenandoah
  • hotspot_gc_shenandoah
  • tier1+UseShenandoahGC+ShenandoahVerify
  • tier2+UseShenandoahGC+ShenandoahVerify

Progress

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

Testing

Linux x64 Linux x86 Windows x64 macOS x64
Build (5/5 running) (2/2 running) (2/2 running) (2/2 running)

Issue

  • JDK-8256020: Shenandoah: Don't resurrect objects during evacuation on AS_NO_KEEPALIVE

Reviewers

Download

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

@bridgekeeper
Copy link

@bridgekeeper bridgekeeper bot commented Nov 8, 2020

👋 Welcome back rkennke! 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 openjdk bot added the rfr label Nov 8, 2020
@openjdk
Copy link

@openjdk openjdk bot commented Nov 8, 2020

@rkennke 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 label Nov 8, 2020
@mlbridge
Copy link

@mlbridge mlbridge bot commented Nov 8, 2020

Webrevs

@fisk
Copy link
Contributor

@fisk fisk commented Nov 10, 2020

So your theory is that someone calls Dependencies::DepStream::recorded_oop_at on an nmethod, after marking terminated, leaking out a dead object. For your theory to be true, you would have acquired a is_unloading() nmethod from somewhere, and called Dependencies::DepStream::recorded_oop_at on it. That immediately excludes e.g. all on-stack nmethods, all nmethods handed out through dependency contexts, and all nmethods handed out through only_alive_and_not_unloading CodeCache iterators, which is almost all of them. There are very few code cache iterations that expose is_unloading() nmethods, and what they have in common is that they are not poking around at oops.

So I suppose I really don't understand what path you could possibly track this to happen, where you have an is_unloading() nmethod, and start poking around at its oops. Would you mind elaborating a bit more, from what context you think Dependencies::DepStream::recorded_oop_at() is being called on an is_unloading() nmethod?

@rkennke
Copy link
Contributor Author

@rkennke rkennke commented Nov 10, 2020

So your theory is that someone calls Dependencies::DepStream::recorded_oop_at on an nmethod, after marking terminated, leaking out a dead object. For your theory to be true, you would have acquired a is_unloading() nmethod from somewhere, and called Dependencies::DepStream::recorded_oop_at on it. That immediately excludes e.g. all on-stack nmethods, all nmethods handed out through dependency contexts, and all nmethods handed out through only_alive_and_not_unloading CodeCache iterators, which is almost all of them. There are very few code cache iterations that expose is_unloading() nmethods, and what they have in common is that they are not poking around at oops.

So I suppose I really don't understand what path you could possibly track this to happen, where you have an is_unloading() nmethod, and start poking around at its oops. Would you mind elaborating a bit more, from what context you think Dependencies::DepStream::recorded_oop_at() is being called on an is_unloading() nmethod?

I am digging a little deeper. Planting an assert in relevant place barrier shows that we are exposing an unmarked object in this code path in nmethod::flush_dependencies():

        oop call_site = deps.argument_oop(0);
        if (delete_immediately) {
          assert_locked_or_safepoint(CodeCache_lock);
          MethodHandles::remove_dependent_nmethod(call_site, this);
        } else {
          MethodHandles::clean_dependency_context(call_site);
        }
#  Internal Error (/home/rkennke/src/openjdk/jdk/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp:112), pid=2396340, tid=2396367
#  assert(obj == __null || !_heap->is_concurrent_weak_root_in_progress() || _heap->marking_context()->is_marked(obj)) failed: only expose marked objects

Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x626fa0]  AccessInternal::PostRuntimeDispatch<ShenandoahBarrierSet::AccessBarrier<544868ul, ShenandoahBarrierSet>, (AccessInternal::BarrierType)2, 544868ul>::oop_access_barrier(void*)+0x290
V  [libjvm.so+0x132b3ea]  nmethod::oop_at(int) const+0x4a
V  [libjvm.so+0x9e862e]  Dependencies::DepStream::argument_oop(int)+0x7e
V  [libjvm.so+0x132fe21]  nmethod::flush_dependencies(bool)+0x1f1
V  [libjvm.so+0x1580e79]  ShenandoahNMethodUnlinkClosure::do_nmethod(nmethod*)+0x3d9
V  [libjvm.so+0x16113fc]  ShenandoahNMethodTableSnapshot::concurrent_nmethods_do(NMethodClosure*)+0x8c
V  [libjvm.so+0x157f19b]  ShenandoahUnlinkTask::work(unsigned int)+0x2b
V  [libjvm.so+0x18faa54]  GangWorker::run_task(WorkData)+0x84
V  [libjvm.so+0x18fabb3]  GangWorker::loop()+0x63
V  [libjvm.so+0x17b6008]  Thread::call_run()+0xf8
V  [libjvm.so+0x13b6d2e]  thread_native_entry(Thread*)+0x10e

In other words, it gets the unmarked call_site, then does access it afterwards. TBH, I am not totally sure that we aren't doing something wrong somewhere. ?

@fisk
Copy link
Contributor

@fisk fisk commented Nov 10, 2020

So your theory is that someone calls Dependencies::DepStream::recorded_oop_at on an nmethod, after marking terminated, leaking out a dead object. For your theory to be true, you would have acquired a is_unloading() nmethod from somewhere, and called Dependencies::DepStream::recorded_oop_at on it. That immediately excludes e.g. all on-stack nmethods, all nmethods handed out through dependency contexts, and all nmethods handed out through only_alive_and_not_unloading CodeCache iterators, which is almost all of them. There are very few code cache iterations that expose is_unloading() nmethods, and what they have in common is that they are not poking around at oops.
So I suppose I really don't understand what path you could possibly track this to happen, where you have an is_unloading() nmethod, and start poking around at its oops. Would you mind elaborating a bit more, from what context you think Dependencies::DepStream::recorded_oop_at() is being called on an is_unloading() nmethod?

I am digging a little deeper. Planting an assert in relevant place barrier shows that we are exposing an unmarked object in this code path in nmethod::flush_dependencies():

        oop call_site = deps.argument_oop(0);
        if (delete_immediately) {
          assert_locked_or_safepoint(CodeCache_lock);
          MethodHandles::remove_dependent_nmethod(call_site, this);
        } else {
          MethodHandles::clean_dependency_context(call_site);
        }
#  Internal Error (/home/rkennke/src/openjdk/jdk/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp:112), pid=2396340, tid=2396367
#  assert(obj == __null || !_heap->is_concurrent_weak_root_in_progress() || _heap->marking_context()->is_marked(obj)) failed: only expose marked objects

Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x626fa0]  AccessInternal::PostRuntimeDispatch<ShenandoahBarrierSet::AccessBarrier<544868ul, ShenandoahBarrierSet>, (AccessInternal::BarrierType)2, 544868ul>::oop_access_barrier(void*)+0x290
V  [libjvm.so+0x132b3ea]  nmethod::oop_at(int) const+0x4a
V  [libjvm.so+0x9e862e]  Dependencies::DepStream::argument_oop(int)+0x7e
V  [libjvm.so+0x132fe21]  nmethod::flush_dependencies(bool)+0x1f1
V  [libjvm.so+0x1580e79]  ShenandoahNMethodUnlinkClosure::do_nmethod(nmethod*)+0x3d9
V  [libjvm.so+0x16113fc]  ShenandoahNMethodTableSnapshot::concurrent_nmethods_do(NMethodClosure*)+0x8c
V  [libjvm.so+0x157f19b]  ShenandoahUnlinkTask::work(unsigned int)+0x2b
V  [libjvm.so+0x18faa54]  GangWorker::run_task(WorkData)+0x84
V  [libjvm.so+0x18fabb3]  GangWorker::loop()+0x63
V  [libjvm.so+0x17b6008]  Thread::call_run()+0xf8
V  [libjvm.so+0x13b6d2e]  thread_native_entry(Thread*)+0x10e

In other words, it gets the unmarked call_site, then does access it afterwards. TBH, I am not totally sure that we aren't doing something wrong somewhere. ?

This is all very intentional. This is called by the class unloading code, and is the very reason why it is strong. The class unloading code, concurrent or STW doesn't matter, peeks and walks a chain of dead objects to find and clean up native dependency contexts of CallSites. This means that we have to expose the dead objects to the class unloading code, so that we can walk the dead objects, find the dependency context, and clean it. So if we would perform your requested change, we would probably crash here with SIGSEGV, trying to dereference NULL, as it is expected that the call_site is not NULL.

@rkennke
Copy link
Contributor Author

@rkennke rkennke commented Nov 10, 2020

So your theory is that someone calls Dependencies::DepStream::recorded_oop_at on an nmethod, after marking terminated, leaking out a dead object. For your theory to be true, you would have acquired a is_unloading() nmethod from somewhere, and called Dependencies::DepStream::recorded_oop_at on it. That immediately excludes e.g. all on-stack nmethods, all nmethods handed out through dependency contexts, and all nmethods handed out through only_alive_and_not_unloading CodeCache iterators, which is almost all of them. There are very few code cache iterations that expose is_unloading() nmethods, and what they have in common is that they are not poking around at oops.
So I suppose I really don't understand what path you could possibly track this to happen, where you have an is_unloading() nmethod, and start poking around at its oops. Would you mind elaborating a bit more, from what context you think Dependencies::DepStream::recorded_oop_at() is being called on an is_unloading() nmethod?

I am digging a little deeper. Planting an assert in relevant place barrier shows that we are exposing an unmarked object in this code path in nmethod::flush_dependencies():

        oop call_site = deps.argument_oop(0);
        if (delete_immediately) {
          assert_locked_or_safepoint(CodeCache_lock);
          MethodHandles::remove_dependent_nmethod(call_site, this);
        } else {
          MethodHandles::clean_dependency_context(call_site);
        }
#  Internal Error (/home/rkennke/src/openjdk/jdk/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp:112), pid=2396340, tid=2396367
#  assert(obj == __null || !_heap->is_concurrent_weak_root_in_progress() || _heap->marking_context()->is_marked(obj)) failed: only expose marked objects

Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x626fa0]  AccessInternal::PostRuntimeDispatch<ShenandoahBarrierSet::AccessBarrier<544868ul, ShenandoahBarrierSet>, (AccessInternal::BarrierType)2, 544868ul>::oop_access_barrier(void*)+0x290
V  [libjvm.so+0x132b3ea]  nmethod::oop_at(int) const+0x4a
V  [libjvm.so+0x9e862e]  Dependencies::DepStream::argument_oop(int)+0x7e
V  [libjvm.so+0x132fe21]  nmethod::flush_dependencies(bool)+0x1f1
V  [libjvm.so+0x1580e79]  ShenandoahNMethodUnlinkClosure::do_nmethod(nmethod*)+0x3d9
V  [libjvm.so+0x16113fc]  ShenandoahNMethodTableSnapshot::concurrent_nmethods_do(NMethodClosure*)+0x8c
V  [libjvm.so+0x157f19b]  ShenandoahUnlinkTask::work(unsigned int)+0x2b
V  [libjvm.so+0x18faa54]  GangWorker::run_task(WorkData)+0x84
V  [libjvm.so+0x18fabb3]  GangWorker::loop()+0x63
V  [libjvm.so+0x17b6008]  Thread::call_run()+0xf8
V  [libjvm.so+0x13b6d2e]  thread_native_entry(Thread*)+0x10e

In other words, it gets the unmarked call_site, then does access it afterwards. TBH, I am not totally sure that we aren't doing something wrong somewhere. ?

This is all very intentional. This is called by the class unloading code, and is the very reason why it is strong. The class unloading code, concurrent or STW doesn't matter, peeks and walks a chain of dead objects to find and clean up native dependency contexts of CallSites. This means that we have to expose the dead objects to the class unloading code, so that we can walk the dead objects, find the dependency context, and clean it. So if we would perform your requested change, we would probably crash here with SIGSEGV, trying to dereference NULL, as it is expected that the call_site is not NULL.

Right. No, it doesn't crash there. It only ever fails our verification.
I see that a couple of IN_NATIVE accesses are also decorated with AS_NO_KEEPALIVE. We interpret that as 'skip SATB barrier' during marking, I wonder if that is even the correct interpretation. The original assert seems to imply that a new MutableCallSite refers to an old but unmarked DirectMethodHandle.

@fisk
Copy link
Contributor

@fisk fisk commented Nov 10, 2020

So your theory is that someone calls Dependencies::DepStream::recorded_oop_at on an nmethod, after marking terminated, leaking out a dead object. For your theory to be true, you would have acquired a is_unloading() nmethod from somewhere, and called Dependencies::DepStream::recorded_oop_at on it. That immediately excludes e.g. all on-stack nmethods, all nmethods handed out through dependency contexts, and all nmethods handed out through only_alive_and_not_unloading CodeCache iterators, which is almost all of them. There are very few code cache iterations that expose is_unloading() nmethods, and what they have in common is that they are not poking around at oops.

So I suppose I really don't understand what path you could possibly track this to happen, where you have an is_unloading() nmethod, and start poking around at its oops. Would you mind elaborating a bit more, from what context you think Dependencies::DepStream::recorded_oop_at() is being called on an is_unloading() nmethod?

I am digging a little deeper. Planting an assert in relevant place barrier shows that we are exposing an unmarked object in this code path in nmethod::flush_dependencies():

    oop call_site = deps.argument_oop(0);
    if (delete_immediately) {
      assert_locked_or_safepoint(CodeCache_lock);
      MethodHandles::remove_dependent_nmethod(call_site, this);
    } else {
      MethodHandles::clean_dependency_context(call_site);
    }

Internal Error (/home/rkennke/src/openjdk/jdk/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.inline.hpp:112), pid=2396340, tid=2396367

assert(obj == __null || !_heap->is_concurrent_weak_root_in_progress() || _heap->marking_context()->is_marked(obj)) failed: only expose marked objects

Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)

V [libjvm.so+0x626fa0] AccessInternal::PostRuntimeDispatch<ShenandoahBarrierSet::AccessBarrier<544868ul, ShenandoahBarrierSet>, (AccessInternal::BarrierType)2, 544868ul>::oop_access_barrier(void*)+0x290

V [libjvm.so+0x132b3ea] nmethod::oop_at(int) const+0x4a

V [libjvm.so+0x9e862e] Dependencies::DepStream::argument_oop(int)+0x7e

V [libjvm.so+0x132fe21] nmethod::flush_dependencies(bool)+0x1f1

V [libjvm.so+0x1580e79] ShenandoahNMethodUnlinkClosure::do_nmethod(nmethod*)+0x3d9

V [libjvm.so+0x16113fc] ShenandoahNMethodTableSnapshot::concurrent_nmethods_do(NMethodClosure*)+0x8c

V [libjvm.so+0x157f19b] ShenandoahUnlinkTask::work(unsigned int)+0x2b

V [libjvm.so+0x18faa54] GangWorker::run_task(WorkData)+0x84

V [libjvm.so+0x18fabb3] GangWorker::loop()+0x63

V [libjvm.so+0x17b6008] Thread::call_run()+0xf8

V [libjvm.so+0x13b6d2e] thread_native_entry(Thread*)+0x10e

In other words, it gets the unmarked call_site, then does access it afterwards. TBH, I am not totally sure that we aren't doing something wrong somewhere. ?

This is all very intentional. This is called by the class unloading code, and is the very reason why it is strong. The class unloading code, concurrent or STW doesn't matter, peeks and walks a chain of dead objects to find and clean up native dependency contexts of CallSites. This means that we have to expose the dead objects to the class unloading code, so that we can walk the dead objects, find the dependency context, and clean it. So if we would perform your requested change, we would probably crash here with SIGSEGV, trying to dereference NULL, as it is expected that the call_site is not NULL.

Right. No, it doesn't crash there. It only ever fails our verification.

Okay.

I see that a couple of IN_NATIVE accesses are also decorated with AS_NO_KEEPALIVE. We interpret that as 'skip SATB barrier' during marking, I wonder if that is even the correct interpretation.

That is the right interpretation.

The original assert seems to imply that a new MutableCallSite refers to an old but unmarked DirectMethodHandle.

Sounds like the old MutableCallSite escaped the snapshot at the beginning somehow. Maybe it is related to your new reference processor?

@rkennke
Copy link
Contributor Author

@rkennke rkennke commented Nov 10, 2020

The original assert seems to imply that a new MutableCallSite refers to an old but unmarked DirectMethodHandle.

Sounds like the old MutableCallSite escaped the snapshot at the beginning somehow. Maybe it is related to your new reference processor?

Hmm I think it is more subtle than that.
I changed all occurances of argument_oop() one-by-one with the 'phantom' variant to narrow it down. It really is the flush_dependencies() method that breaks it. However, as you noted, it cannot accept NULL there, otherwise it would crash. However, we do have a special code-path there that returns the original object instead of NULL when the calling thread is not a Java thread (See https://bugs.openjdk.java.net/browse/JDK-8237874). I believe this is why the fix helps. OTOH, if I don't do this, the remainder of the barrier would evacuate the object, and thus make the unreachable object alive again. :-S I suspect that we must skip evacuating objects when we get AS_NO_KEEPALIVE, but that seems to result in a "memory stomping" error. Grrrr.

@fisk
Copy link
Contributor

@fisk fisk commented Nov 10, 2020

The original assert seems to imply that a new MutableCallSite refers to an old but unmarked DirectMethodHandle.

Sounds like the old MutableCallSite escaped the snapshot at the beginning somehow. Maybe it is related to your new reference processor?

Hmm I think it is more subtle than that.

I changed all occurances of argument_oop() one-by-one with the 'phantom' variant to narrow it down. It really is the flush_dependencies() method that breaks it. However, as you noted, it cannot accept NULL there, otherwise it would crash. However, we do have a special code-path there that returns the original object instead of NULL when the calling thread is not a Java thread (See https://bugs.openjdk.java.net/browse/JDK-8237874). I believe this is why the fix helps. OTOH, if I don't do this, the remainder of the barrier would evacuate the object, and thus make the unreachable object alive again. :-S I suspect that we must skip evacuating objects when we get AS_NO_KEEPALIVE, but that seems to result in a "memory stomping" error. Grrrr.

Any non-raw access load should expose only the to-space object. But that is completely orthogonal to whether it should be marked or not. And obviously, having completely different semantics for accesses depending on whether the access is performed on a Java thread or not, is not a good idea. Sounds like the barrier code needs fixing.

@rkennke
Copy link
Contributor Author

@rkennke rkennke commented Nov 10, 2020

Any non-raw access load should expose only the to-space object. But that is completely orthogonal to whether it should be marked or not. And obviously, having completely different semantics for accesses depending on whether the access is performed on a Java thread or not, is not a good idea. Sounds like the barrier code needs fixing.

Why do these native-accesses be not-raw anyway?

The trouble in Shenandoah is that if an object is unreachable, and we evacuate it, then it becomes 'live' at least in the sense that it is now beyond top-at-mark-start (TAMS), e.g. implicitely-live. I believe this is what the verifier is ultimately complaining about. This is not a marking issue.

I have a fix that I'll push shortly after I did more testing. It does return the naked (from-space) oop when encountering AS_NO_KEEPALIVE on an unmarked object. That seems to fix this particular testcase as seems to be in the spirit of AS_NO_KEEPALIVE, assuming that AS_NO_KEEPALIVE access does not do anything nasty like storing the oop elsewhere.

@openjdk openjdk bot added hotspot-gc shenandoah and removed hotspot-compiler labels Nov 10, 2020
@rkennke rkennke changed the title 8256020: Don't resurrect objects on argument-dependency access 8256020: Shenandoah: Don't resurrect objects during evacuation on AS_NO_KEEPALIVE Nov 10, 2020
// Prevent resurrection of unreachable objects that are visited during
// concurrent class-unloading.
if (HasDecorator<decorators, AS_NO_KEEPALIVE>::value && obj != NULL &&
_heap->has_forwarded_objects() &&
Copy link
Contributor

@shipilev shipilev Nov 11, 2020

Choose a reason for hiding this comment

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

Why has_forwarded_objects() check here? It seems to me that without forwarded objects, the load_reference_barrier below would return the same obj anyway?

Copy link
Contributor Author

@rkennke rkennke Nov 11, 2020

Choose a reason for hiding this comment

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

Mostly because we check if the object is (un-)marked and that would be unreliable outside of has_forwarded. Also, secondarily, because this block is intended to prevent resurrection-by-evacuation, which would not happen outside of has_forwarded. We could, infact, narrow it to is_evacuation_in_progress() I guess.

Copy link
Contributor

@shipilev shipilev left a comment

Yes, that matches the synopsis better too.

@openjdk
Copy link

@openjdk openjdk bot commented Nov 11, 2020

@rkennke 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:

8256020: Shenandoah: Don't resurrect objects during evacuation on AS_NO_KEEPALIVE

Reviewed-by: shade

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

  • 2e19026: 8253064: monitor list simplifications and getting rid of TSM
  • 421a7c3: 8256182: Update qemu-debootstrap cross-compilation recipe
  • 6247736: 8256018: Adler32/CRC32/CRC32C missing reachabilityFence
  • 436019b: 8256166: [C2] Registers get confused on Big Endian after 8221404

Please see this link for an up-to-date comparison between the source branch of this pull request and the master branch.
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 label Nov 11, 2020
@rkennke
Copy link
Contributor Author

@rkennke rkennke commented Nov 11, 2020

/integrate

@openjdk openjdk bot closed this Nov 11, 2020
@openjdk openjdk bot added the integrated label Nov 11, 2020
@openjdk openjdk bot removed ready rfr labels Nov 11, 2020
@openjdk
Copy link

@openjdk openjdk bot commented Nov 11, 2020

@rkennke Since your change was applied there have been 4 commits pushed to the master branch:

  • 2e19026: 8253064: monitor list simplifications and getting rid of TSM
  • 421a7c3: 8256182: Update qemu-debootstrap cross-compilation recipe
  • 6247736: 8256018: Adler32/CRC32/CRC32C missing reachabilityFence
  • 436019b: 8256166: [C2] Registers get confused on Big Endian after 8221404

Your commit was automatically rebased without conflicts.

Pushed as commit 3c3469b.

💡 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-gc integrated shenandoah
3 participants