src/share/vm/classfile/metadataOnStackMark.cpp

Thu, 12 Oct 2017 21:27:07 +0800

author
aoqi
date
Thu, 12 Oct 2017 21:27:07 +0800
changeset 7535
7ae4e26cb1e0
parent 7333
b12a2a9b05ca
parent 6876
710a3c8b516e
child 9203
53eec13fbaa5
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "classfile/metadataOnStackMark.hpp"
    27 #include "code/codeCache.hpp"
    28 #include "compiler/compileBroker.hpp"
    29 #include "oops/metadata.hpp"
    30 #include "prims/jvmtiImpl.hpp"
    31 #include "runtime/synchronizer.hpp"
    32 #include "runtime/thread.hpp"
    33 #include "services/threadService.hpp"
    34 #include "utilities/chunkedList.hpp"
    36 volatile MetadataOnStackBuffer* MetadataOnStackMark::_used_buffers = NULL;
    37 volatile MetadataOnStackBuffer* MetadataOnStackMark::_free_buffers = NULL;
    39 NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;)
    41 // Walk metadata on the stack and mark it so that redefinition doesn't delete
    42 // it.  Class unloading also walks the previous versions and might try to
    43 // delete it, so this class is used by class unloading also.
    44 MetadataOnStackMark::MetadataOnStackMark(bool visit_code_cache) {
    45   assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
    46   assert(_used_buffers == NULL, "sanity check");
    47   NOT_PRODUCT(_is_active = true;)
    49   Threads::metadata_do(Metadata::mark_on_stack);
    50   if (visit_code_cache) {
    51     CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
    52   }
    53   CompileBroker::mark_on_stack();
    54   JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
    55   ThreadService::metadata_do(Metadata::mark_on_stack);
    56 }
    58 MetadataOnStackMark::~MetadataOnStackMark() {
    59   assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
    60   // Unmark everything that was marked.   Can't do the same walk because
    61   // redefine classes messes up the code cache so the set of methods
    62   // might not be the same.
    64   retire_buffer_for_thread(Thread::current());
    66   MetadataOnStackBuffer* buffer = const_cast<MetadataOnStackBuffer* >(_used_buffers);
    67   while (buffer != NULL) {
    68     // Clear on stack state for all metadata.
    69     size_t size = buffer->size();
    70     for (size_t i  = 0; i < size; i++) {
    71       Metadata* md = buffer->at(i);
    72       md->set_on_stack(false);
    73     }
    75     MetadataOnStackBuffer* next = buffer->next_used();
    77     // Move the buffer to the free list.
    78     buffer->clear();
    79     buffer->set_next_used(NULL);
    80     buffer->set_next_free(const_cast<MetadataOnStackBuffer*>(_free_buffers));
    81     _free_buffers = buffer;
    83     // Step to next used buffer.
    84     buffer = next;
    85   }
    87   _used_buffers = NULL;
    89   NOT_PRODUCT(_is_active = false;)
    90 }
    92 void MetadataOnStackMark::retire_buffer(MetadataOnStackBuffer* buffer) {
    93   if (buffer == NULL) {
    94     return;
    95   }
    97   MetadataOnStackBuffer* old_head;
    99   do {
   100     old_head = const_cast<MetadataOnStackBuffer*>(_used_buffers);
   101     buffer->set_next_used(old_head);
   102   } while (Atomic::cmpxchg_ptr(buffer, &_used_buffers, old_head) != old_head);
   103 }
   105 void MetadataOnStackMark::retire_buffer_for_thread(Thread* thread) {
   106   retire_buffer(thread->metadata_on_stack_buffer());
   107   thread->set_metadata_on_stack_buffer(NULL);
   108 }
   110 bool MetadataOnStackMark::has_buffer_for_thread(Thread* thread) {
   111   return thread->metadata_on_stack_buffer() != NULL;
   112 }
   114 MetadataOnStackBuffer* MetadataOnStackMark::allocate_buffer() {
   115   MetadataOnStackBuffer* allocated;
   116   MetadataOnStackBuffer* new_head;
   118   do {
   119     allocated = const_cast<MetadataOnStackBuffer*>(_free_buffers);
   120     if (allocated == NULL) {
   121       break;
   122     }
   123     new_head = allocated->next_free();
   124   } while (Atomic::cmpxchg_ptr(new_head, &_free_buffers, allocated) != allocated);
   126   if (allocated == NULL) {
   127     allocated = new MetadataOnStackBuffer();
   128   }
   130   assert(!allocated->is_full(), err_msg("Should not be full: " PTR_FORMAT, p2i(allocated)));
   132   return allocated;
   133 }
   135 // Record which objects are marked so we can unmark the same objects.
   136 void MetadataOnStackMark::record(Metadata* m, Thread* thread) {
   137   assert(_is_active, "metadata on stack marking is active");
   139   MetadataOnStackBuffer* buffer =  thread->metadata_on_stack_buffer();
   141   if (buffer != NULL && buffer->is_full()) {
   142     retire_buffer(buffer);
   143     buffer = NULL;
   144   }
   146   if (buffer == NULL) {
   147     buffer = allocate_buffer();
   148     thread->set_metadata_on_stack_buffer(buffer);
   149   }
   151   buffer->push(m);
   152 }

mercurial