# HG changeset patch # User cjplummer # Date 1494019355 25200 # Node ID b093c3f1ab3dc8e249962e24da8441b72ea7fc92 # Parent 755e01cd0b9d85df3fc603cc870b0e190b5dafaf 8164563: Test nsk/jvmti/CompiledMethodUnload/compmethunload001 keeps reporting: PRODUCT BUG: class was not unloaded in 5 Summary: Removed _pending_list Reviewed-by: dholmes, sspitsyn, dcubed, coleenp diff -r 755e01cd0b9d -r b093c3f1ab3d hotspot/src/share/vm/code/nmethod.cpp --- a/hotspot/src/share/vm/code/nmethod.cpp Fri May 05 17:48:45 2017 +0200 +++ b/hotspot/src/share/vm/code/nmethod.cpp Fri May 05 14:22:35 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1459,14 +1459,8 @@ JvmtiDeferredEvent event = JvmtiDeferredEvent::compiled_method_unload_event(this, _jmethod_id, insts_begin()); - if (SafepointSynchronize::is_at_safepoint()) { - // Don't want to take the queueing lock. Add it as pending and - // it will get enqueued later. - JvmtiDeferredEventQueue::add_pending_event(event); - } else { - MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); - JvmtiDeferredEventQueue::enqueue(event); - } + MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); + JvmtiDeferredEventQueue::enqueue(event); } // The JVMTI CompiledMethodUnload event can be enabled or disabled at diff -r 755e01cd0b9d -r b093c3f1ab3d hotspot/src/share/vm/prims/jvmtiImpl.cpp --- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp Fri May 05 17:48:45 2017 +0200 +++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp Fri May 05 14:22:35 2017 -0700 @@ -974,19 +974,14 @@ JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_tail = NULL; JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_head = NULL; -volatile JvmtiDeferredEventQueue::QueueNode* - JvmtiDeferredEventQueue::_pending_list = NULL; - bool JvmtiDeferredEventQueue::has_events() { assert(Service_lock->owned_by_self(), "Must own Service_lock"); - return _queue_head != NULL || _pending_list != NULL; + return _queue_head != NULL; } void JvmtiDeferredEventQueue::enqueue(const JvmtiDeferredEvent& event) { assert(Service_lock->owned_by_self(), "Must own Service_lock"); - process_pending_events(); - // Events get added to the end of the queue (and are pulled off the front). QueueNode* node = new QueueNode(event); if (_queue_tail == NULL) { @@ -1005,8 +1000,6 @@ JvmtiDeferredEvent JvmtiDeferredEventQueue::dequeue() { assert(Service_lock->owned_by_self(), "Must own Service_lock"); - process_pending_events(); - assert(_queue_head != NULL, "Nothing to dequeue"); if (_queue_head == NULL) { @@ -1027,62 +1020,3 @@ delete node; return event; } - -void JvmtiDeferredEventQueue::add_pending_event( - const JvmtiDeferredEvent& event) { - - QueueNode* node = new QueueNode(event); - - bool success = false; - QueueNode* prev_value = (QueueNode*)_pending_list; - do { - node->set_next(prev_value); - prev_value = (QueueNode*)Atomic::cmpxchg_ptr( - (void*)node, (volatile void*)&_pending_list, (void*)node->next()); - } while (prev_value != node->next()); -} - -// This method transfers any events that were added by someone NOT holding -// the lock into the mainline queue. -void JvmtiDeferredEventQueue::process_pending_events() { - assert(Service_lock->owned_by_self(), "Must own Service_lock"); - - if (_pending_list != NULL) { - QueueNode* head = - (QueueNode*)Atomic::xchg_ptr(NULL, (volatile void*)&_pending_list); - - assert((_queue_head == NULL) == (_queue_tail == NULL), - "Inconsistent queue markers"); - - if (head != NULL) { - // Since we've treated the pending list as a stack (with newer - // events at the beginning), we need to join the bottom of the stack - // with the 'tail' of the queue in order to get the events in the - // right order. We do this by reversing the pending list and appending - // it to the queue. - - QueueNode* new_tail = head; - QueueNode* new_head = NULL; - - // This reverses the list - QueueNode* prev = new_tail; - QueueNode* node = new_tail->next(); - new_tail->set_next(NULL); - while (node != NULL) { - QueueNode* next = node->next(); - node->set_next(prev); - prev = node; - node = next; - } - new_head = prev; - - // Now append the new list to the queue - if (_queue_tail != NULL) { - _queue_tail->set_next(new_head); - } else { // _queue_head == NULL - _queue_head = new_head; - } - _queue_tail = new_tail; - } - } -} diff -r 755e01cd0b9d -r b093c3f1ab3d hotspot/src/share/vm/prims/jvmtiImpl.hpp --- a/hotspot/src/share/vm/prims/jvmtiImpl.hpp Fri May 05 17:48:45 2017 +0200 +++ b/hotspot/src/share/vm/prims/jvmtiImpl.hpp Fri May 05 14:22:35 2017 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -497,7 +497,7 @@ /** * Events enqueued on this queue wake up the Service thread which dequeues * and posts the events. The Service_lock is required to be held - * when operating on the queue (except for the "pending" events). + * when operating on the queue. */ class JvmtiDeferredEventQueue : AllStatic { friend class JvmtiDeferredEvent; @@ -519,24 +519,12 @@ static QueueNode* _queue_head; // Hold Service_lock to access static QueueNode* _queue_tail; // Hold Service_lock to access - static volatile QueueNode* _pending_list; // Uses CAS for read/update - - // Transfers events from the _pending_list to the _queue. - static void process_pending_events() NOT_JVMTI_RETURN; public: // Must be holding Service_lock when calling these static bool has_events() NOT_JVMTI_RETURN_(false); static void enqueue(const JvmtiDeferredEvent& event) NOT_JVMTI_RETURN; static JvmtiDeferredEvent dequeue() NOT_JVMTI_RETURN_(JvmtiDeferredEvent()); - - // Used to enqueue events without using a lock, for times (such as during - // safepoint) when we can't or don't want to lock the Service_lock. - // - // Events will be held off to the side until there's a call to - // dequeue(), enqueue(), or process_pending_events() (all of which require - // the holding of the Service_lock), and will be enqueued at that time. - static void add_pending_event(const JvmtiDeferredEvent&) NOT_JVMTI_RETURN; }; // Utility macro that checks for NULL pointers: