Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/shark/sharkStack.hpp
32285 views
1
/*
2
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3
* Copyright 2008, 2009, 2010 Red Hat, Inc.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
#ifndef SHARE_VM_SHARK_SHARKSTACK_HPP
27
#define SHARE_VM_SHARK_SHARKSTACK_HPP
28
29
#include "shark/llvmHeaders.hpp"
30
#include "shark/sharkInvariants.hpp"
31
#include "shark/sharkType.hpp"
32
33
class SharkFunction;
34
class SharkNativeWrapper;
35
class SharkStackWithNormalFrame;
36
class SharkStackWithNativeFrame;
37
38
class SharkStack : public SharkCompileInvariants {
39
public:
40
static SharkStack* CreateBuildAndPushFrame(
41
SharkFunction* function, llvm::Value* method);
42
static SharkStack* CreateBuildAndPushFrame(
43
SharkNativeWrapper* wrapper, llvm::Value* method);
44
45
protected:
46
SharkStack(const SharkCompileInvariants* parent)
47
: SharkCompileInvariants(parent) {}
48
49
protected:
50
void initialize(llvm::Value* method);
51
52
protected:
53
void CreateStackOverflowCheck(llvm::Value* sp);
54
55
// Properties of the method being compiled
56
protected:
57
virtual int arg_size() const = 0;
58
virtual int max_locals() const = 0;
59
virtual int max_stack() const = 0;
60
virtual int max_monitors() const = 0;
61
62
// BasicBlock creation
63
protected:
64
virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0;
65
66
// Interpreter entry point for bailouts
67
protected:
68
virtual address interpreter_entry_point() const = 0;
69
70
// Interface with the Zero stack
71
private:
72
llvm::Value* zero_stack() const {
73
return builder()->CreateAddressOfStructEntry(
74
thread(),
75
JavaThread::zero_stack_offset(),
76
SharkType::zeroStack_type(),
77
"zero_stack");
78
}
79
llvm::Value* stack_base() const {
80
return builder()->CreateValueOfStructEntry(
81
zero_stack(),
82
ZeroStack::base_offset(),
83
SharkType::intptr_type(),
84
"stack_base");
85
}
86
llvm::Value* stack_pointer_addr() const {
87
return builder()->CreateAddressOfStructEntry(
88
zero_stack(),
89
ZeroStack::sp_offset(),
90
llvm::PointerType::getUnqual(SharkType::intptr_type()),
91
"stack_pointer_addr");
92
}
93
llvm::Value* frame_pointer_addr() const {
94
return builder()->CreateAddressOfStructEntry(
95
thread(),
96
JavaThread::top_zero_frame_offset(),
97
llvm::PointerType::getUnqual(SharkType::intptr_type()),
98
"frame_pointer_addr");
99
}
100
101
public:
102
llvm::LoadInst* CreateLoadStackPointer(const char *name = "") {
103
return builder()->CreateLoad(stack_pointer_addr(), name);
104
}
105
llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) {
106
return builder()->CreateStore(value, stack_pointer_addr());
107
}
108
llvm::LoadInst* CreateLoadFramePointer(const char *name = "") {
109
return builder()->CreateLoad(frame_pointer_addr(), name);
110
}
111
llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) {
112
return builder()->CreateStore(value, frame_pointer_addr());
113
}
114
llvm::Value* CreatePopFrame(int result_slots);
115
116
// Interface with the frame anchor
117
private:
118
llvm::Value* last_Java_sp_addr() const {
119
return builder()->CreateAddressOfStructEntry(
120
thread(),
121
JavaThread::last_Java_sp_offset(),
122
llvm::PointerType::getUnqual(SharkType::intptr_type()),
123
"last_Java_sp_addr");
124
}
125
llvm::Value* last_Java_fp_addr() const {
126
return builder()->CreateAddressOfStructEntry(
127
thread(),
128
JavaThread::last_Java_fp_offset(),
129
llvm::PointerType::getUnqual(SharkType::intptr_type()),
130
"last_Java_fp_addr");
131
}
132
133
public:
134
void CreateSetLastJavaFrame() {
135
// Note that whenever _last_Java_sp != NULL other anchor fields
136
// must be valid. The profiler apparently depends on this.
137
NOT_PRODUCT(CreateAssertLastJavaSPIsNull());
138
builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());
139
// XXX There's last_Java_pc as well, but I don't think anything uses it
140
// Also XXX: should we fence here? Zero doesn't...
141
builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());
142
// Also also XXX: we could probably cache the sp (and the fp we know??)
143
}
144
void CreateResetLastJavaFrame() {
145
builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());
146
}
147
148
private:
149
void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
150
151
// Our method's frame
152
private:
153
llvm::Value* _frame;
154
int _extended_frame_size;
155
int _stack_slots_offset;
156
157
public:
158
int extended_frame_size() const {
159
return _extended_frame_size;
160
}
161
int oopmap_frame_size() const {
162
return extended_frame_size() - arg_size();
163
}
164
165
// Offsets of things in the frame
166
private:
167
int _monitors_slots_offset;
168
int _oop_tmp_slot_offset;
169
int _method_slot_offset;
170
int _pc_slot_offset;
171
int _locals_slots_offset;
172
173
public:
174
int stack_slots_offset() const {
175
return _stack_slots_offset;
176
}
177
int oop_tmp_slot_offset() const {
178
return _oop_tmp_slot_offset;
179
}
180
int method_slot_offset() const {
181
return _method_slot_offset;
182
}
183
int pc_slot_offset() const {
184
return _pc_slot_offset;
185
}
186
int locals_slots_offset() const {
187
return _locals_slots_offset;
188
}
189
int monitor_offset(int index) const {
190
assert(index >= 0 && index < max_monitors(), "invalid monitor index");
191
return _monitors_slots_offset +
192
(max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size();
193
}
194
int monitor_object_offset(int index) const {
195
return monitor_offset(index) +
196
(BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord);
197
}
198
int monitor_header_offset(int index) const {
199
return monitor_offset(index) +
200
((BasicObjectLock::lock_offset_in_bytes() +
201
BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord);
202
}
203
204
// Addresses of things in the frame
205
public:
206
llvm::Value* slot_addr(int offset,
207
llvm::Type* type = NULL,
208
const char* name = "") const;
209
210
llvm::Value* monitor_addr(int index) const {
211
return slot_addr(
212
monitor_offset(index),
213
SharkType::monitor_type(),
214
"monitor");
215
}
216
llvm::Value* monitor_object_addr(int index) const {
217
return slot_addr(
218
monitor_object_offset(index),
219
SharkType::oop_type(),
220
"object_addr");
221
}
222
llvm::Value* monitor_header_addr(int index) const {
223
return slot_addr(
224
monitor_header_offset(index),
225
SharkType::intptr_type(),
226
"displaced_header_addr");
227
}
228
229
// oopmap helpers
230
public:
231
static int oopmap_slot_munge(int offset) {
232
return offset << (LogBytesPerWord - LogBytesPerInt);
233
}
234
static VMReg slot2reg(int offset) {
235
return VMRegImpl::stack2reg(oopmap_slot_munge(offset));
236
}
237
};
238
239
class SharkStackWithNormalFrame : public SharkStack {
240
friend class SharkStack;
241
242
protected:
243
SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method);
244
245
private:
246
SharkFunction* _function;
247
248
private:
249
SharkFunction* function() const {
250
return _function;
251
}
252
253
// Properties of the method being compiled
254
private:
255
int arg_size() const;
256
int max_locals() const;
257
int max_stack() const;
258
int max_monitors() const;
259
260
// BasicBlock creation
261
private:
262
llvm::BasicBlock* CreateBlock(const char* name = "") const;
263
264
// Interpreter entry point for bailouts
265
private:
266
address interpreter_entry_point() const;
267
};
268
269
class SharkStackWithNativeFrame : public SharkStack {
270
friend class SharkStack;
271
272
protected:
273
SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method);
274
275
private:
276
SharkNativeWrapper* _wrapper;
277
278
private:
279
SharkNativeWrapper* wrapper() const {
280
return _wrapper;
281
}
282
283
// Properties of the method being compiled
284
private:
285
int arg_size() const;
286
int max_locals() const;
287
int max_stack() const;
288
int max_monitors() const;
289
290
// BasicBlock creation
291
private:
292
llvm::BasicBlock* CreateBlock(const char* name = "") const;
293
294
// Interpreter entry point for bailouts
295
private:
296
address interpreter_entry_point() const;
297
};
298
299
#endif // SHARE_VM_SHARK_SHARKSTACK_HPP
300
301