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/sharkIntrinsics.cpp
32285 views
1
/*
2
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3
* Copyright 2009 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 "shark/llvmHeaders.hpp"
29
#include "shark/sharkIntrinsics.hpp"
30
#include "shark/sharkState.hpp"
31
#include "shark/sharkValue.hpp"
32
#include "shark/shark_globals.hpp"
33
34
using namespace llvm;
35
36
bool SharkIntrinsics::is_intrinsic(ciMethod *target) {
37
switch (target->intrinsic_id()) {
38
case vmIntrinsics::_none:
39
return false;
40
41
// java.lang.Math
42
case vmIntrinsics::_min:
43
case vmIntrinsics::_max:
44
case vmIntrinsics::_dabs:
45
case vmIntrinsics::_dsin:
46
case vmIntrinsics::_dcos:
47
case vmIntrinsics::_dtan:
48
case vmIntrinsics::_datan2:
49
case vmIntrinsics::_dsqrt:
50
case vmIntrinsics::_dlog:
51
case vmIntrinsics::_dlog10:
52
case vmIntrinsics::_dpow:
53
case vmIntrinsics::_dexp:
54
return true;
55
56
// java.lang.Object
57
case vmIntrinsics::_getClass:
58
return true;
59
60
// java.lang.System
61
case vmIntrinsics::_currentTimeMillis:
62
return true;
63
64
// java.lang.Thread
65
case vmIntrinsics::_currentThread:
66
return true;
67
68
// sun.misc.Unsafe
69
case vmIntrinsics::_compareAndSwapInt:
70
return true;
71
72
default:
73
if (SharkPerformanceWarnings) {
74
warning(
75
"unhandled intrinsic vmIntrinsic::%s",
76
vmIntrinsics::name_at(target->intrinsic_id()));
77
}
78
}
79
return false;
80
}
81
82
void SharkIntrinsics::inline_intrinsic(ciMethod *target, SharkState *state) {
83
SharkIntrinsics intrinsic(state, target);
84
intrinsic.do_intrinsic();
85
}
86
87
void SharkIntrinsics::do_intrinsic() {
88
switch (target()->intrinsic_id()) {
89
// java.lang.Math
90
case vmIntrinsics::_min:
91
do_Math_minmax(llvm::ICmpInst::ICMP_SLE);
92
break;
93
case vmIntrinsics::_max:
94
do_Math_minmax(llvm::ICmpInst::ICMP_SGE);
95
break;
96
case vmIntrinsics::_dabs:
97
do_Math_1to1(builder()->fabs());
98
break;
99
case vmIntrinsics::_dsin:
100
do_Math_1to1(builder()->sin());
101
break;
102
case vmIntrinsics::_dcos:
103
do_Math_1to1(builder()->cos());
104
break;
105
case vmIntrinsics::_dtan:
106
do_Math_1to1(builder()->tan());
107
break;
108
case vmIntrinsics::_datan2:
109
do_Math_2to1(builder()->atan2());
110
break;
111
case vmIntrinsics::_dsqrt:
112
do_Math_1to1(builder()->sqrt());
113
break;
114
case vmIntrinsics::_dlog:
115
do_Math_1to1(builder()->log());
116
break;
117
case vmIntrinsics::_dlog10:
118
do_Math_1to1(builder()->log10());
119
break;
120
case vmIntrinsics::_dpow:
121
do_Math_2to1(builder()->pow());
122
break;
123
case vmIntrinsics::_dexp:
124
do_Math_1to1(builder()->exp());
125
break;
126
127
// java.lang.Object
128
case vmIntrinsics::_getClass:
129
do_Object_getClass();
130
break;
131
132
// java.lang.System
133
case vmIntrinsics::_currentTimeMillis:
134
do_System_currentTimeMillis();
135
break;
136
137
// java.lang.Thread
138
case vmIntrinsics::_currentThread:
139
do_Thread_currentThread();
140
break;
141
142
// sun.misc.Unsafe
143
case vmIntrinsics::_compareAndSwapInt:
144
do_Unsafe_compareAndSwapInt();
145
break;
146
147
default:
148
ShouldNotReachHere();
149
}
150
}
151
152
void SharkIntrinsics::do_Math_minmax(ICmpInst::Predicate p) {
153
// Pop the arguments
154
SharkValue *sb = state()->pop();
155
SharkValue *sa = state()->pop();
156
Value *a = sa->jint_value();
157
Value *b = sb->jint_value();
158
159
// Perform the test
160
BasicBlock *ip = builder()->GetBlockInsertionPoint();
161
BasicBlock *return_a = builder()->CreateBlock(ip, "return_a");
162
BasicBlock *return_b = builder()->CreateBlock(ip, "return_b");
163
BasicBlock *done = builder()->CreateBlock(ip, "done");
164
165
builder()->CreateCondBr(builder()->CreateICmp(p, a, b), return_a, return_b);
166
167
builder()->SetInsertPoint(return_a);
168
builder()->CreateBr(done);
169
170
builder()->SetInsertPoint(return_b);
171
builder()->CreateBr(done);
172
173
builder()->SetInsertPoint(done);
174
PHINode *phi = builder()->CreatePHI(a->getType(), 0, "result");
175
phi->addIncoming(a, return_a);
176
phi->addIncoming(b, return_b);
177
178
// Push the result
179
state()->push(
180
SharkValue::create_jint(
181
phi,
182
sa->zero_checked() && sb->zero_checked()));
183
}
184
185
void SharkIntrinsics::do_Math_1to1(Value *function) {
186
SharkValue *empty = state()->pop();
187
assert(empty == NULL, "should be");
188
state()->push(
189
SharkValue::create_jdouble(
190
builder()->CreateCall(
191
function, state()->pop()->jdouble_value())));
192
state()->push(NULL);
193
}
194
195
void SharkIntrinsics::do_Math_2to1(Value *function) {
196
SharkValue *empty = state()->pop();
197
assert(empty == NULL, "should be");
198
Value *y = state()->pop()->jdouble_value();
199
empty = state()->pop();
200
assert(empty == NULL, "should be");
201
Value *x = state()->pop()->jdouble_value();
202
203
state()->push(
204
SharkValue::create_jdouble(
205
builder()->CreateCall2(function, x, y)));
206
state()->push(NULL);
207
}
208
209
void SharkIntrinsics::do_Object_getClass() {
210
Value *klass = builder()->CreateValueOfStructEntry(
211
state()->pop()->jobject_value(),
212
in_ByteSize(oopDesc::klass_offset_in_bytes()),
213
SharkType::klass_type(),
214
"klass");
215
216
state()->push(
217
SharkValue::create_jobject(
218
builder()->CreateValueOfStructEntry(
219
klass,
220
Klass::java_mirror_offset(),
221
SharkType::oop_type(),
222
"java_mirror"),
223
true));
224
}
225
226
void SharkIntrinsics::do_System_currentTimeMillis() {
227
state()->push(
228
SharkValue::create_jlong(
229
builder()->CreateCall(builder()->current_time_millis()),
230
false));
231
state()->push(NULL);
232
}
233
234
void SharkIntrinsics::do_Thread_currentThread() {
235
state()->push(
236
SharkValue::create_jobject(
237
builder()->CreateValueOfStructEntry(
238
thread(), JavaThread::threadObj_offset(),
239
SharkType::oop_type(),
240
"threadObj"),
241
true));
242
}
243
244
void SharkIntrinsics::do_Unsafe_compareAndSwapInt() {
245
// Pop the arguments
246
Value *x = state()->pop()->jint_value();
247
Value *e = state()->pop()->jint_value();
248
SharkValue *empty = state()->pop();
249
assert(empty == NULL, "should be");
250
Value *offset = state()->pop()->jlong_value();
251
Value *object = state()->pop()->jobject_value();
252
Value *unsafe = state()->pop()->jobject_value();
253
254
// Convert the offset
255
offset = builder()->CreateCall(
256
builder()->unsafe_field_offset_to_byte_offset(),
257
offset);
258
259
// Locate the field
260
Value *addr = builder()->CreateIntToPtr(
261
builder()->CreateAdd(
262
builder()->CreatePtrToInt(object, SharkType::intptr_type()),
263
builder()->CreateIntCast(offset, SharkType::intptr_type(), true)),
264
PointerType::getUnqual(SharkType::jint_type()),
265
"addr");
266
267
// Perform the operation
268
Value *result = builder()->CreateAtomicCmpXchg(addr, e, x, llvm::SequentiallyConsistent);
269
// Push the result
270
state()->push(
271
SharkValue::create_jint(
272
builder()->CreateIntCast(
273
builder()->CreateICmpEQ(result, e), SharkType::jint_type(), true),
274
false));
275
}
276
277