Mercurial > hg > truffle
annotate src/share/vm/shark/sharkIntrinsics.cpp @ 15177:66e3af78ea96
HSAIL: added safepoint support
Contributed-by: Eric Caspole <eric.caspole@amd.com>
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Thu, 17 Apr 2014 00:44:32 +0200 |
parents | 2cd5e15048e6 |
children |
rev | line source |
---|---|
1692 | 1 /* |
1972 | 2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. |
1692 | 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 | |
1972 | 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" | |
1692 | 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); | |
7195 | 174 PHINode *phi = builder()->CreatePHI(a->getType(), 0, "result"); |
1692 | 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()), | |
7195 | 213 SharkType::klass_type(), |
1692 | 214 "klass"); |
215 | |
216 state()->push( | |
217 SharkValue::create_jobject( | |
218 builder()->CreateValueOfStructEntry( | |
4762
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
1972
diff
changeset
|
219 klass, |
069ab3f976d3
7118863: Move sizeof(klassOopDesc) into the *Klass::*_offset_in_bytes() functions
stefank
parents:
1972
diff
changeset
|
220 Klass::java_mirror_offset(), |
1692 | 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 | |
7195 | 268 Value *result = builder()->CreateAtomicCmpXchg(addr, e, x, llvm::SequentiallyConsistent); |
1692 | 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 } |