1 /*
2  * Copyright (c) 2013, 2019, 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  */
24 
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"
35 #if INCLUDE_JVMCI
36 #include "jvmci/jvmci.hpp"
37 #endif
38 
39 MetadataOnStackBuffer* MetadataOnStackMark::_used_buffers = NULL;
40 MetadataOnStackBuffer* MetadataOnStackMark::_free_buffers = NULL;
41 
42 MetadataOnStackBuffer* MetadataOnStackMark::_current_buffer = NULL;
43 NOT_PRODUCT(bool MetadataOnStackMark::_is_active = false;)
44 
45 class MetadataOnStackClosure : public MetadataClosure {
do_metadata(Metadata * m)46   void do_metadata(Metadata* m) { Metadata::mark_on_stack(m); }
47 };
48 
49 // Walk metadata on the stack and mark it so that redefinition doesn't delete
50 // it.  Class unloading only deletes in-error class files, methods created by
51 // the relocator and dummy constant pools.  None of these appear anywhere except
52 // in metadata Handles.
MetadataOnStackMark(bool walk_all_metadata,bool redefinition_walk)53 MetadataOnStackMark::MetadataOnStackMark(bool walk_all_metadata, bool redefinition_walk) {
54   assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
55   assert(_used_buffers == NULL, "sanity check");
56   assert(!_is_active, "MetadataOnStackMarks do not nest");
57   assert(!redefinition_walk || walk_all_metadata,
58          "walk_all_metadata must be true for redefinition_walk");
59   NOT_PRODUCT(_is_active = true;)
60 
61   Threads::metadata_handles_do(Metadata::mark_on_stack);
62 
63   if (walk_all_metadata) {
64     MetadataOnStackClosure md_on_stack;
65     Threads::metadata_do(&md_on_stack);
66     if (redefinition_walk) {
67       // We have to walk the whole code cache during redefinition.
68       CodeCache::metadata_do(&md_on_stack);
69     } else {
70       CodeCache::old_nmethods_do(&md_on_stack);
71     }
72     CompileBroker::mark_on_stack();
73     ThreadService::metadata_do(Metadata::mark_on_stack);
74 #if INCLUDE_JVMCI
75     JVMCI::metadata_do(Metadata::mark_on_stack);
76 #endif
77   }
78 }
79 
~MetadataOnStackMark()80 MetadataOnStackMark::~MetadataOnStackMark() {
81   assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
82   // Unmark everything that was marked.   Can't do the same walk because
83   // redefine classes messes up the code cache so the set of methods
84   // might not be the same.
85   retire_current_buffer();
86 
87   MetadataOnStackBuffer* buffer = _used_buffers;
88   while (buffer != NULL) {
89     // Clear on stack state for all metadata.
90     size_t size = buffer->size();
91     for (size_t i  = 0; i < size; i++) {
92       Metadata* md = buffer->at(i);
93       md->set_on_stack(false);
94     }
95 
96     MetadataOnStackBuffer* next = buffer->next_used();
97 
98     // Move the buffer to the free list.
99     buffer->clear();
100     buffer->set_next_used(NULL);
101     buffer->set_next_free(_free_buffers);
102     _free_buffers = buffer;
103 
104     // Step to next used buffer.
105     buffer = next;
106   }
107 
108   _used_buffers = NULL;
109 
110   NOT_PRODUCT(_is_active = false;)
111 }
112 
retire_buffer(MetadataOnStackBuffer * buffer)113 void MetadataOnStackMark::retire_buffer(MetadataOnStackBuffer* buffer) {
114   if (buffer == NULL) {
115     return;
116   }
117   buffer->set_next_used(_used_buffers);
118   _used_buffers = buffer;
119 }
120 
121 // Current buffer is full or we're ready to walk them, add it to the used list.
retire_current_buffer()122 void MetadataOnStackMark::retire_current_buffer() {
123   retire_buffer(_current_buffer);
124   _current_buffer = NULL;
125 }
126 
127 // Get buffer off free list.
allocate_buffer()128 MetadataOnStackBuffer* MetadataOnStackMark::allocate_buffer() {
129   MetadataOnStackBuffer* allocated = _free_buffers;
130 
131   if (allocated != NULL) {
132     _free_buffers = allocated->next_free();
133   }
134 
135   if (allocated == NULL) {
136     allocated = new MetadataOnStackBuffer();
137   }
138 
139   assert(!allocated->is_full(), "Should not be full: " PTR_FORMAT, p2i(allocated));
140 
141   return allocated;
142 }
143 
144 // Record which objects are marked so we can unmark the same objects.
record(Metadata * m)145 void MetadataOnStackMark::record(Metadata* m) {
146   assert(_is_active, "metadata on stack marking is active");
147 
148   MetadataOnStackBuffer* buffer = _current_buffer;
149 
150   if (buffer != NULL && buffer->is_full()) {
151     retire_buffer(buffer);
152     buffer = NULL;
153   }
154 
155   if (buffer == NULL) {
156     buffer = allocate_buffer();
157     _current_buffer = buffer;
158   }
159 
160   buffer->push(m);
161 }
162