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/sharkBuilder.cpp
32285 views
1
/*
2
* Copyright (c) 1999, 2013, 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
#include "precompiled.hpp"
27
#include "ci/ciMethod.hpp"
28
#include "memory/resourceArea.hpp"
29
#include "oops/method.hpp"
30
#include "runtime/os.hpp"
31
#include "runtime/synchronizer.hpp"
32
#include "runtime/thread.hpp"
33
#include "shark/llvmHeaders.hpp"
34
#include "shark/llvmValue.hpp"
35
#include "shark/sharkBuilder.hpp"
36
#include "shark/sharkContext.hpp"
37
#include "shark/sharkRuntime.hpp"
38
#include "utilities/debug.hpp"
39
40
using namespace llvm;
41
42
SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer)
43
: IRBuilder<>(SharkContext::current()),
44
_code_buffer(code_buffer) {
45
}
46
47
// Helpers for accessing structures
48
Value* SharkBuilder::CreateAddressOfStructEntry(Value* base,
49
ByteSize offset,
50
Type* type,
51
const char* name) {
52
return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name);
53
}
54
55
LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base,
56
ByteSize offset,
57
Type* type,
58
const char* name) {
59
return CreateLoad(
60
CreateAddressOfStructEntry(
61
base, offset, PointerType::getUnqual(type)),
62
name);
63
}
64
65
// Helpers for accessing arrays
66
67
LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) {
68
return CreateValueOfStructEntry(
69
arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()),
70
SharkType::jint_type(), "length");
71
}
72
73
Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
74
Type* element_type,
75
int element_bytes,
76
ByteSize base_offset,
77
Value* index,
78
const char* name) {
79
Value* offset = CreateIntCast(index, SharkType::intptr_type(), false);
80
if (element_bytes != 1)
81
offset = CreateShl(
82
offset,
83
LLVMValue::intptr_constant(exact_log2(element_bytes)));
84
offset = CreateAdd(
85
LLVMValue::intptr_constant(in_bytes(base_offset)), offset);
86
87
return CreateIntToPtr(
88
CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
89
PointerType::getUnqual(element_type),
90
name);
91
}
92
93
Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
94
BasicType basic_type,
95
ByteSize base_offset,
96
Value* index,
97
const char* name) {
98
return CreateArrayAddress(
99
arrayoop,
100
SharkType::to_arrayType(basic_type),
101
type2aelembytes(basic_type),
102
base_offset, index, name);
103
}
104
105
Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
106
BasicType basic_type,
107
Value* index,
108
const char* name) {
109
return CreateArrayAddress(
110
arrayoop, basic_type,
111
in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)),
112
index, name);
113
}
114
115
// Helpers for creating intrinsics and external functions.
116
117
Type* SharkBuilder::make_type(char type, bool void_ok) {
118
switch (type) {
119
// Primitive types
120
case 'c':
121
return SharkType::jbyte_type();
122
case 'i':
123
return SharkType::jint_type();
124
case 'l':
125
return SharkType::jlong_type();
126
case 'x':
127
return SharkType::intptr_type();
128
case 'f':
129
return SharkType::jfloat_type();
130
case 'd':
131
return SharkType::jdouble_type();
132
133
// Pointers to primitive types
134
case 'C':
135
case 'I':
136
case 'L':
137
case 'X':
138
case 'F':
139
case 'D':
140
return PointerType::getUnqual(make_type(tolower(type), false));
141
142
// VM objects
143
case 'T':
144
return SharkType::thread_type();
145
case 'M':
146
return PointerType::getUnqual(SharkType::monitor_type());
147
case 'O':
148
return SharkType::oop_type();
149
case 'K':
150
return SharkType::klass_type();
151
152
// Miscellaneous
153
case 'v':
154
assert(void_ok, "should be");
155
return SharkType::void_type();
156
case '1':
157
return SharkType::bit_type();
158
159
default:
160
ShouldNotReachHere();
161
}
162
}
163
164
FunctionType* SharkBuilder::make_ftype(const char* params,
165
const char* ret) {
166
std::vector<Type*> param_types;
167
for (const char* c = params; *c; c++)
168
param_types.push_back(make_type(*c, false));
169
170
assert(strlen(ret) == 1, "should be");
171
Type *return_type = make_type(*ret, true);
172
173
return FunctionType::get(return_type, param_types, false);
174
}
175
176
// Create an object representing an intrinsic or external function by
177
// referencing the symbol by name. This is the LLVM-style approach,
178
// but it cannot be used on functions within libjvm.so its symbols
179
// are not exported. Note that you cannot make this work simply by
180
// exporting the symbols, as some symbols have the same names as
181
// symbols in the standard libraries (eg, atan2, fabs) and would
182
// obscure them were they visible.
183
Value* SharkBuilder::make_function(const char* name,
184
const char* params,
185
const char* ret) {
186
return SharkContext::current().get_external(name, make_ftype(params, ret));
187
}
188
189
// Create an object representing an external function by inlining a
190
// function pointer in the code. This is not the LLVM way, but it's
191
// the only way to access functions in libjvm.so and functions like
192
// __kernel_dmb on ARM which is accessed via an absolute address.
193
Value* SharkBuilder::make_function(address func,
194
const char* params,
195
const char* ret) {
196
return CreateIntToPtr(
197
LLVMValue::intptr_constant((intptr_t) func),
198
PointerType::getUnqual(make_ftype(params, ret)));
199
}
200
201
// VM calls
202
203
Value* SharkBuilder::find_exception_handler() {
204
return make_function(
205
(address) SharkRuntime::find_exception_handler, "TIi", "i");
206
}
207
208
Value* SharkBuilder::monitorenter() {
209
return make_function((address) SharkRuntime::monitorenter, "TM", "v");
210
}
211
212
Value* SharkBuilder::monitorexit() {
213
return make_function((address) SharkRuntime::monitorexit, "TM", "v");
214
}
215
216
Value* SharkBuilder::new_instance() {
217
return make_function((address) SharkRuntime::new_instance, "Ti", "v");
218
}
219
220
Value* SharkBuilder::newarray() {
221
return make_function((address) SharkRuntime::newarray, "Tii", "v");
222
}
223
224
Value* SharkBuilder::anewarray() {
225
return make_function((address) SharkRuntime::anewarray, "Tii", "v");
226
}
227
228
Value* SharkBuilder::multianewarray() {
229
return make_function((address) SharkRuntime::multianewarray, "TiiI", "v");
230
}
231
232
Value* SharkBuilder::register_finalizer() {
233
return make_function((address) SharkRuntime::register_finalizer, "TO", "v");
234
}
235
236
Value* SharkBuilder::safepoint() {
237
return make_function((address) SafepointSynchronize::block, "T", "v");
238
}
239
240
Value* SharkBuilder::throw_ArithmeticException() {
241
return make_function(
242
(address) SharkRuntime::throw_ArithmeticException, "TCi", "v");
243
}
244
245
Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() {
246
return make_function(
247
(address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v");
248
}
249
250
Value* SharkBuilder::throw_ClassCastException() {
251
return make_function(
252
(address) SharkRuntime::throw_ClassCastException, "TCi", "v");
253
}
254
255
Value* SharkBuilder::throw_NullPointerException() {
256
return make_function(
257
(address) SharkRuntime::throw_NullPointerException, "TCi", "v");
258
}
259
260
// High-level non-VM calls
261
262
Value* SharkBuilder::f2i() {
263
return make_function((address) SharedRuntime::f2i, "f", "i");
264
}
265
266
Value* SharkBuilder::f2l() {
267
return make_function((address) SharedRuntime::f2l, "f", "l");
268
}
269
270
Value* SharkBuilder::d2i() {
271
return make_function((address) SharedRuntime::d2i, "d", "i");
272
}
273
274
Value* SharkBuilder::d2l() {
275
return make_function((address) SharedRuntime::d2l, "d", "l");
276
}
277
278
Value* SharkBuilder::is_subtype_of() {
279
return make_function((address) SharkRuntime::is_subtype_of, "KK", "c");
280
}
281
282
Value* SharkBuilder::current_time_millis() {
283
return make_function((address) os::javaTimeMillis, "", "l");
284
}
285
286
Value* SharkBuilder::sin() {
287
return make_function("llvm.sin.f64", "d", "d");
288
}
289
290
Value* SharkBuilder::cos() {
291
return make_function("llvm.cos.f64", "d", "d");
292
}
293
294
Value* SharkBuilder::tan() {
295
return make_function((address) ::tan, "d", "d");
296
}
297
298
Value* SharkBuilder::atan2() {
299
return make_function((address) ::atan2, "dd", "d");
300
}
301
302
Value* SharkBuilder::sqrt() {
303
return make_function("llvm.sqrt.f64", "d", "d");
304
}
305
306
Value* SharkBuilder::log() {
307
return make_function("llvm.log.f64", "d", "d");
308
}
309
310
Value* SharkBuilder::log10() {
311
return make_function("llvm.log10.f64", "d", "d");
312
}
313
314
Value* SharkBuilder::pow() {
315
return make_function("llvm.pow.f64", "dd", "d");
316
}
317
318
Value* SharkBuilder::exp() {
319
return make_function("llvm.exp.f64", "d", "d");
320
}
321
322
Value* SharkBuilder::fabs() {
323
return make_function((address) ::fabs, "d", "d");
324
}
325
326
Value* SharkBuilder::unsafe_field_offset_to_byte_offset() {
327
extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset);
328
return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l");
329
}
330
331
Value* SharkBuilder::osr_migration_end() {
332
return make_function((address) SharedRuntime::OSR_migration_end, "C", "v");
333
}
334
335
// Semi-VM calls
336
337
Value* SharkBuilder::throw_StackOverflowError() {
338
return make_function((address) ZeroStack::handle_overflow, "T", "v");
339
}
340
341
Value* SharkBuilder::uncommon_trap() {
342
return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i");
343
}
344
345
Value* SharkBuilder::deoptimized_entry_point() {
346
return make_function((address) CppInterpreter::main_loop, "iT", "v");
347
}
348
349
// Native-Java transition
350
351
Value* SharkBuilder::check_special_condition_for_native_trans() {
352
return make_function(
353
(address) JavaThread::check_special_condition_for_native_trans,
354
"T", "v");
355
}
356
357
Value* SharkBuilder::frame_address() {
358
return make_function("llvm.frameaddress", "i", "C");
359
}
360
361
Value* SharkBuilder::memset() {
362
// LLVM 2.8 added a fifth isVolatile field for memset
363
// introduced with LLVM r100304
364
return make_function("llvm.memset.p0i8.i32", "Cciii", "v");
365
}
366
367
Value* SharkBuilder::unimplemented() {
368
return make_function((address) report_unimplemented, "Ci", "v");
369
}
370
371
Value* SharkBuilder::should_not_reach_here() {
372
return make_function((address) report_should_not_reach_here, "Ci", "v");
373
}
374
375
Value* SharkBuilder::dump() {
376
return make_function((address) SharkRuntime::dump, "Cx", "v");
377
}
378
379
// Public interface to low-level non-VM calls
380
381
CallInst* SharkBuilder::CreateGetFrameAddress() {
382
return CreateCall(frame_address(), LLVMValue::jint_constant(0));
383
}
384
385
CallInst* SharkBuilder::CreateMemset(Value* dst,
386
Value* value,
387
Value* len,
388
Value* align) {
389
return CreateCall5(memset(), dst, value, len, align,
390
LLVMValue::jint_constant(0));
391
}
392
393
CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) {
394
return CreateCall2(
395
unimplemented(),
396
CreateIntToPtr(
397
LLVMValue::intptr_constant((intptr_t) file),
398
PointerType::getUnqual(SharkType::jbyte_type())),
399
LLVMValue::jint_constant(line));
400
}
401
402
CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) {
403
return CreateCall2(
404
should_not_reach_here(),
405
CreateIntToPtr(
406
LLVMValue::intptr_constant((intptr_t) file),
407
PointerType::getUnqual(SharkType::jbyte_type())),
408
LLVMValue::jint_constant(line));
409
}
410
411
#ifndef PRODUCT
412
CallInst* SharkBuilder::CreateDump(Value* value) {
413
const char *name;
414
if (value->hasName())
415
// XXX this leaks, but it's only debug code
416
name = strdup(value->getName().str().c_str());
417
else
418
name = "unnamed_value";
419
420
if (isa<PointerType>(value->getType()))
421
value = CreatePtrToInt(value, SharkType::intptr_type());
422
else if (value->getType()->
423
isIntegerTy()
424
)
425
value = CreateIntCast(value, SharkType::intptr_type(), false);
426
else
427
Unimplemented();
428
429
return CreateCall2(
430
dump(),
431
CreateIntToPtr(
432
LLVMValue::intptr_constant((intptr_t) name),
433
PointerType::getUnqual(SharkType::jbyte_type())),
434
value);
435
}
436
#endif // PRODUCT
437
438
// HotSpot memory barriers
439
440
void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) {
441
if (bs->kind() != BarrierSet::CardTableModRef)
442
Unimplemented();
443
444
CreateStore(
445
LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card),
446
CreateIntToPtr(
447
CreateAdd(
448
LLVMValue::intptr_constant(
449
(intptr_t) ((CardTableModRefBS *) bs)->byte_map_base),
450
CreateLShr(
451
CreatePtrToInt(field, SharkType::intptr_type()),
452
LLVMValue::intptr_constant(CardTableModRefBS::card_shift))),
453
PointerType::getUnqual(SharkType::jbyte_type())));
454
}
455
456
// Helpers for accessing the code buffer
457
458
Value* SharkBuilder::code_buffer_address(int offset) {
459
return CreateAdd(
460
code_buffer()->base_pc(),
461
LLVMValue::intptr_constant(offset));
462
}
463
464
Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) {
465
return CreateLoad(
466
CreateIntToPtr(
467
code_buffer_address(code_buffer()->inline_oop(object)),
468
PointerType::getUnqual(SharkType::oop_type())),
469
name);
470
}
471
472
Value* SharkBuilder::CreateInlineMetadata(Metadata* metadata, llvm::PointerType* type, const char* name) {
473
assert(metadata != NULL, "inlined metadata must not be NULL");
474
assert(metadata->is_metaspace_object(), "sanity check");
475
return CreateLoad(
476
CreateIntToPtr(
477
code_buffer_address(code_buffer()->inline_Metadata(metadata)),
478
PointerType::getUnqual(type)),
479
name);
480
}
481
482
Value* SharkBuilder::CreateInlineData(void* data,
483
size_t size,
484
Type* type,
485
const char* name) {
486
return CreateIntToPtr(
487
code_buffer_address(code_buffer()->inline_data(data, size)),
488
type,
489
name);
490
}
491
492
// Helpers for creating basic blocks.
493
494
BasicBlock* SharkBuilder::GetBlockInsertionPoint() const {
495
BasicBlock *cur = GetInsertBlock();
496
497
// BasicBlock::Create takes an insertBefore argument, so
498
// we need to find the block _after_ the current block
499
Function::iterator iter = cur->getParent()->begin();
500
Function::iterator end = cur->getParent()->end();
501
while (iter != end) {
502
iter++;
503
if (&*iter == cur) {
504
iter++;
505
break;
506
}
507
}
508
509
if (iter == end)
510
return NULL;
511
else
512
return iter;
513
}
514
515
BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const {
516
return BasicBlock::Create(
517
SharkContext::current(), name, GetInsertBlock()->getParent(), ip);
518
}
519
520
LoadInst* SharkBuilder::CreateAtomicLoad(Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) {
521
return Insert(new LoadInst(ptr, name, isVolatile, align, ordering, synchScope), name);
522
}
523
524
StoreInst* SharkBuilder::CreateAtomicStore(Value* val, Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) {
525
return Insert(new StoreInst(val, ptr, isVolatile, align, ordering, synchScope), name);
526
}
527
528