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 }