- Notifications
You must be signed in to change notification settings - Fork 5.8k
/
Copy pathcompiledIC.hpp
233 lines (188 loc) · 7.76 KB
/
compiledIC.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
* Copyright (c) 1997, 2024, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_CODE_COMPILEDIC_HPP
#defineSHARE_CODE_COMPILEDIC_HPP
#include"code/nativeInst.hpp"
#include"interpreter/linkResolver.hpp"
#include"runtime/safepointVerifiers.hpp"
//-----------------------------------------------------------------------------
// The CompiledIC represents a compiled inline cache.
//
// It's safe to transition from any state to any state. Typically an inline cache starts
// in the clean state, meaning it will resolve the call when called. Then it typically
// transitions to monomorphic, assuming the first dynamic receiver will be the only one
// observed. If that speculation fails, we transition to megamorphic.
//
classCompiledIC;
classCompiledICProtectionBehaviour;
classnmethod;
classCompiledICLocker: publicStackObj {
nmethod* _method;
CompiledICProtectionBehaviour* _behaviour;
bool _locked;
NoSafepointVerifier _nsv;
public:
CompiledICLocker(nmethod* method);
~CompiledICLocker();
staticboolis_safe(nmethod* method);
staticboolis_safe(address code);
};
// A CompiledICData is a helper object for the inline cache implementation.
// It comprises:
// (1) The first receiver klass and its selected method
// (2) Itable call metadata
classCompiledICData : publicCHeapObj<mtCode> {
friendclassVMStructs;
friendclassJVMCIVMStructs;
Method* volatile _speculated_method;
uintptr_tvolatile _speculated_klass;
Klass* _itable_defc_klass;
Klass* _itable_refc_klass;
bool _is_initialized;
boolis_speculated_klass_unloaded() const;
public:
// Constructor
CompiledICData();
// accessors
Klass* speculated_klass() const;
Method* speculated_method() const { return _speculated_method; }
Klass* itable_defc_klass() const { return _itable_defc_klass; }
Klass* itable_refc_klass() const { return _itable_refc_klass; }
static ByteSize speculated_method_offset() { returnbyte_offset_of(CompiledICData, _speculated_method); }
static ByteSize speculated_klass_offset() { returnbyte_offset_of(CompiledICData, _speculated_klass); }
static ByteSize itable_defc_klass_offset() { returnbyte_offset_of(CompiledICData, _itable_defc_klass); }
static ByteSize itable_refc_klass_offset() { returnbyte_offset_of(CompiledICData, _itable_refc_klass); }
voidinitialize(CallInfo* call_info, Klass* receiver_klass);
boolis_initialized() const { return _is_initialized; }
// GC Support
voidclean_metadata();
voidmetadata_do(MetadataClosure* cl);
};
classCompiledIC: publicResourceObj {
private:
nmethod* _method;
CompiledICData* _data;
NativeCall* _call;
CompiledIC(RelocIterator* iter);
// CompiledICData wrappers
voidensure_initialized(CallInfo* call_info, Klass* receiver_klass);
boolis_speculated_klass(Klass* receiver_klass);
// Inline cache states
voidset_to_monomorphic();
voidset_to_megamorphic(CallInfo* call_info);
public:
// conversion (machine PC to CompiledIC*)
friend CompiledIC* CompiledIC_before(nmethod* nm, address return_addr);
friend CompiledIC* CompiledIC_at(nmethod* nm, address call_site);
friend CompiledIC* CompiledIC_at(Relocation* call_site);
friend CompiledIC* CompiledIC_at(RelocIterator* reloc_iter);
CompiledICData* data() const;
// State
boolis_clean() const;
boolis_monomorphic() const;
boolis_megamorphic() const;
address end_of_call() const { return _call->return_address(); }
// MT-safe patching of inline caches. Note: Only safe to call is_xxx when holding the CompiledICLocker
// so you are guaranteed that no patching takes place. The same goes for verify.
voidset_to_clean();
voidupdate(CallInfo* call_info, Klass* receiver_klass);
// GC support
voidclean_metadata();
voidmetadata_do(MetadataClosure* cl);
// Location
address instruction_address() const { return _call->instruction_address(); }
address destination() const { return _call->destination(); }
// Misc
voidprint() PRODUCT_RETURN;
voidverify() PRODUCT_RETURN;
};
CompiledIC* CompiledIC_before(nmethod* nm, address return_addr);
CompiledIC* CompiledIC_at(nmethod* nm, address call_site);
CompiledIC* CompiledIC_at(Relocation* call_site);
CompiledIC* CompiledIC_at(RelocIterator* reloc_iter);
//-----------------------------------------------------------------------------
// The CompiledDirectCall represents a call to a method in the compiled code
//
//
// -----<----- Clean ----->-----
// / \
// / \
// compilled code <------------> interpreted code
//
// Clean: Calls directly to runtime method for fixup
// Compiled code: Calls directly to compiled code
// Interpreted code: Calls to stub that set Method* reference
//
//
classCompiledDirectCall : publicResourceObj {
private:
friendclassCompiledIC;
friendclassDirectNativeCallWrapper;
// Also used by CompiledIC
voidset_to_interpreted(const methodHandle& callee, address entry);
voidverify_mt_safe(const methodHandle& callee, address entry,
NativeMovConstReg* method_holder,
NativeJump* jump) PRODUCT_RETURN;
address instruction_address() const { return _call->instruction_address(); }
voidset_destination_mt_safe(address dest) { _call->set_destination_mt_safe(dest); }
NativeCall* _call;
CompiledDirectCall(NativeCall* call) : _call(call) {}
public:
// Returns null if CodeBuffer::expand fails
static address emit_to_interp_stub(MacroAssembler *masm, address mark = nullptr);
staticintto_interp_stub_size();
staticintto_trampoline_stub_size();
staticintreloc_to_interp_stub();
staticinline CompiledDirectCall* before(address return_addr) {
CompiledDirectCall* st = newCompiledDirectCall(nativeCall_before(return_addr));
st->verify();
return st;
}
staticinline CompiledDirectCall* at(address native_call) {
CompiledDirectCall* st = newCompiledDirectCall(nativeCall_at(native_call));
st->verify();
return st;
}
staticinline CompiledDirectCall* at(Relocation* call_site) {
returnat(call_site->addr());
}
// Delegation
address destination() const { return _call->destination(); }
address end_of_call() const { return _call->return_address(); }
// Clean static call (will force resolving on next use)
voidset_to_clean();
voidset(const methodHandle& callee_method);
// State
boolis_clean() const;
boolis_call_to_interpreted() const;
boolis_call_to_compiled() const;
// Stub support
static address find_stub_for(address instruction);
address find_stub();
staticvoidset_stub_to_clean(static_stub_Relocation* static_stub);
// Misc.
voidprint() PRODUCT_RETURN;
voidverify() PRODUCT_RETURN;
};
#endif// SHARE_CODE_COMPILEDIC_HPP