Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/jvmci/metadataHandles.hpp
40949 views
1
/*
2
* Copyright (c) 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
#ifndef SHARE_JVMCI_METADATAHANDLES_HPP
25
#define SHARE_JVMCI_METADATAHANDLES_HPP
26
27
#include "oops/constantPool.hpp"
28
#include "oops/metadata.hpp"
29
#include "oops/method.hpp"
30
#include "runtime/handles.hpp"
31
#include "runtime/os.hpp"
32
33
#ifdef ASSERT
34
#define METADATA_TRACK_NAMES
35
#endif
36
37
struct _jmetadata {
38
private:
39
Metadata* _value;
40
#ifdef METADATA_TRACK_NAMES
41
// Debug data for tracking stale metadata
42
const char* _name;
43
#endif
44
45
public:
46
Metadata* value() { return _value; }
47
48
#ifdef METADATA_TRACK_NAMES
49
void initialize() {
50
_value = NULL;
51
_name = NULL;
52
}
53
#endif
54
55
void set_value(Metadata* value) {
56
_value = value;
57
}
58
59
#ifdef METADATA_TRACK_NAMES
60
const char* name() { return _name; }
61
void set_name(const char* name) {
62
if (_name != NULL) {
63
os::free((void*) _name);
64
_name = NULL;
65
}
66
if (name != NULL) {
67
_name = os::strdup(name);
68
}
69
}
70
#endif
71
};
72
73
typedef struct _jmetadata HandleRecord;
74
typedef struct _jmetadata *jmetadata;
75
class MetadataHandles;
76
77
class MetadataHandleBlock : public CHeapObj<mtJVMCI> {
78
friend class MetadataHandles;
79
private:
80
enum SomeConstants {
81
block_size_in_handles = 32 // Number of handles per handle block
82
};
83
84
// Free handles always have their low bit set so those pointers can
85
// be distinguished from handles which are in use. The last handle
86
// on the free list has a NULL pointer with the tag bit set, so it's
87
// clear that the handle has been reclaimed. The _free_list is
88
// always a real pointer to a handle.
89
90
HandleRecord _handles[block_size_in_handles]; // The handles
91
int _top; // Index of next unused handle
92
MetadataHandleBlock* _next; // Link to next block
93
94
MetadataHandleBlock() {
95
_top = 0;
96
_next = NULL;
97
#ifdef METADATA_TRACK_NAMES
98
for (int i = 0; i < block_size_in_handles; i++) {
99
_handles[i].initialize();
100
}
101
#endif
102
}
103
104
const char* get_name(int index) {
105
#ifdef METADATA_TRACK_NAMES
106
return _handles[index].name();
107
#else
108
return "<missing>";
109
#endif
110
}
111
};
112
113
// JVMCI maintains direct references to metadata. To make these references safe in the face of
114
// class redefinition, they are held in handles so they can be scanned during GC. They are
115
// managed in a cooperative way between the Java code and HotSpot. A handle is filled in and
116
// passed back to the Java code which is responsible for setting the handle to NULL when it
117
// is no longer in use. This is done by jdk.vm.ci.hotspot.HandleCleaner. The
118
// rebuild_free_list function notices when the handle is clear and reclaims it for re-use.
119
class MetadataHandles : public CHeapObj<mtJVMCI> {
120
private:
121
enum SomeConstants {
122
ptr_tag = 1,
123
ptr_mask = ~((intptr_t)ptr_tag)
124
};
125
126
MetadataHandleBlock* _head; // First block
127
MetadataHandleBlock* _last; // Last block in use
128
intptr_t _free_list; // Handle free list
129
int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list
130
int _num_blocks; // Number of blocks
131
int _num_handles;
132
int _num_free_handles;
133
134
HandleRecord* get_free_handle() {
135
HandleRecord* handle = (HandleRecord*) (_free_list & ptr_mask);
136
_free_list = (ptr_mask & (intptr_t) (handle->value()));
137
assert(_free_list != ptr_tag, "should be null");
138
_num_free_handles--;
139
return handle;
140
}
141
142
HandleRecord* get_handle() {
143
assert(_last != NULL, "sanity");
144
// Try last block
145
if (_last->_top < MetadataHandleBlock::block_size_in_handles) {
146
_num_handles++;
147
return &(_last->_handles)[_last->_top++];
148
} else if (_free_list != 0) {
149
// Try free list
150
return get_free_handle();
151
}
152
return NULL;
153
}
154
155
void rebuild_free_list();
156
157
jmetadata allocate_metadata_handle(Metadata* metadata);
158
159
public:
160
MetadataHandles() {
161
_head = NULL;
162
_last = NULL;
163
_free_list = 0;
164
_allocate_before_rebuild = 0;
165
_num_blocks = 0;
166
_num_handles = 0;
167
_num_free_handles = 0;
168
}
169
170
int num_handles() const { return _num_handles; }
171
int num_free_handles() const { return _num_free_handles; }
172
int num_blocks() const { return _num_blocks; }
173
174
jmetadata allocate_handle(const methodHandle& handle) { return allocate_metadata_handle(handle()); }
175
jmetadata allocate_handle(const constantPoolHandle& handle) { return allocate_metadata_handle(handle()); }
176
177
// Adds `handle` to the free list
178
void chain_free_list(HandleRecord* handle) {
179
handle->set_value((Metadata*) (ptr_tag | _free_list));
180
#ifdef METADATA_TRACK_NAMES
181
handle->set_name(NULL);
182
#endif
183
_free_list = (intptr_t) handle;
184
_num_free_handles++;
185
}
186
187
// Clears all handles without releasing any handle memory.
188
void clear();
189
190
void metadata_do(void f(Metadata*));
191
192
void do_unloading();
193
};
194
195
#endif // SHARE_JVMCI_METADATAHANDLES_HPP
196
197