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