src/share/vm/shark/sharkIntrinsics.cpp

Tue, 23 Nov 2010 13:22:55 -0800

author
stefank
date
Tue, 23 Nov 2010 13:22:55 -0800
changeset 2314
f95d63e2154a
parent 2047
d2ede61b7a12
child 3391
069ab3f976d3
permissions
-rw-r--r--

6989984: Use standard include model for Hospot
Summary: Replaced MakeDeps and the includeDB files with more standardized solutions.
Reviewed-by: coleenp, kvn, kamg

twisti@2047 1 /*
stefank@2314 2 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
twisti@2047 3 * Copyright 2009 Red Hat, Inc.
twisti@2047 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
twisti@2047 5 *
twisti@2047 6 * This code is free software; you can redistribute it and/or modify it
twisti@2047 7 * under the terms of the GNU General Public License version 2 only, as
twisti@2047 8 * published by the Free Software Foundation.
twisti@2047 9 *
twisti@2047 10 * This code is distributed in the hope that it will be useful, but WITHOUT
twisti@2047 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
twisti@2047 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
twisti@2047 13 * version 2 for more details (a copy is included in the LICENSE file that
twisti@2047 14 * accompanied this code).
twisti@2047 15 *
twisti@2047 16 * You should have received a copy of the GNU General Public License version
twisti@2047 17 * 2 along with this work; if not, write to the Free Software Foundation,
twisti@2047 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
twisti@2047 19 *
twisti@2047 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
twisti@2047 21 * or visit www.oracle.com if you need additional information or have any
twisti@2047 22 * questions.
twisti@2047 23 *
twisti@2047 24 */
twisti@2047 25
stefank@2314 26 #include "precompiled.hpp"
stefank@2314 27 #include "ci/ciMethod.hpp"
stefank@2314 28 #include "shark/llvmHeaders.hpp"
stefank@2314 29 #include "shark/sharkIntrinsics.hpp"
stefank@2314 30 #include "shark/sharkState.hpp"
stefank@2314 31 #include "shark/sharkValue.hpp"
stefank@2314 32 #include "shark/shark_globals.hpp"
twisti@2047 33
twisti@2047 34 using namespace llvm;
twisti@2047 35
twisti@2047 36 bool SharkIntrinsics::is_intrinsic(ciMethod *target) {
twisti@2047 37 switch (target->intrinsic_id()) {
twisti@2047 38 case vmIntrinsics::_none:
twisti@2047 39 return false;
twisti@2047 40
twisti@2047 41 // java.lang.Math
twisti@2047 42 case vmIntrinsics::_min:
twisti@2047 43 case vmIntrinsics::_max:
twisti@2047 44 case vmIntrinsics::_dabs:
twisti@2047 45 case vmIntrinsics::_dsin:
twisti@2047 46 case vmIntrinsics::_dcos:
twisti@2047 47 case vmIntrinsics::_dtan:
twisti@2047 48 case vmIntrinsics::_datan2:
twisti@2047 49 case vmIntrinsics::_dsqrt:
twisti@2047 50 case vmIntrinsics::_dlog:
twisti@2047 51 case vmIntrinsics::_dlog10:
twisti@2047 52 case vmIntrinsics::_dpow:
twisti@2047 53 case vmIntrinsics::_dexp:
twisti@2047 54 return true;
twisti@2047 55
twisti@2047 56 // java.lang.Object
twisti@2047 57 case vmIntrinsics::_getClass:
twisti@2047 58 return true;
twisti@2047 59
twisti@2047 60 // java.lang.System
twisti@2047 61 case vmIntrinsics::_currentTimeMillis:
twisti@2047 62 return true;
twisti@2047 63
twisti@2047 64 // java.lang.Thread
twisti@2047 65 case vmIntrinsics::_currentThread:
twisti@2047 66 return true;
twisti@2047 67
twisti@2047 68 // sun.misc.Unsafe
twisti@2047 69 case vmIntrinsics::_compareAndSwapInt:
twisti@2047 70 return true;
twisti@2047 71
twisti@2047 72 default:
twisti@2047 73 if (SharkPerformanceWarnings) {
twisti@2047 74 warning(
twisti@2047 75 "unhandled intrinsic vmIntrinsic::%s",
twisti@2047 76 vmIntrinsics::name_at(target->intrinsic_id()));
twisti@2047 77 }
twisti@2047 78 }
twisti@2047 79 return false;
twisti@2047 80 }
twisti@2047 81
twisti@2047 82 void SharkIntrinsics::inline_intrinsic(ciMethod *target, SharkState *state) {
twisti@2047 83 SharkIntrinsics intrinsic(state, target);
twisti@2047 84 intrinsic.do_intrinsic();
twisti@2047 85 }
twisti@2047 86
twisti@2047 87 void SharkIntrinsics::do_intrinsic() {
twisti@2047 88 switch (target()->intrinsic_id()) {
twisti@2047 89 // java.lang.Math
twisti@2047 90 case vmIntrinsics::_min:
twisti@2047 91 do_Math_minmax(llvm::ICmpInst::ICMP_SLE);
twisti@2047 92 break;
twisti@2047 93 case vmIntrinsics::_max:
twisti@2047 94 do_Math_minmax(llvm::ICmpInst::ICMP_SGE);
twisti@2047 95 break;
twisti@2047 96 case vmIntrinsics::_dabs:
twisti@2047 97 do_Math_1to1(builder()->fabs());
twisti@2047 98 break;
twisti@2047 99 case vmIntrinsics::_dsin:
twisti@2047 100 do_Math_1to1(builder()->sin());
twisti@2047 101 break;
twisti@2047 102 case vmIntrinsics::_dcos:
twisti@2047 103 do_Math_1to1(builder()->cos());
twisti@2047 104 break;
twisti@2047 105 case vmIntrinsics::_dtan:
twisti@2047 106 do_Math_1to1(builder()->tan());
twisti@2047 107 break;
twisti@2047 108 case vmIntrinsics::_datan2:
twisti@2047 109 do_Math_2to1(builder()->atan2());
twisti@2047 110 break;
twisti@2047 111 case vmIntrinsics::_dsqrt:
twisti@2047 112 do_Math_1to1(builder()->sqrt());
twisti@2047 113 break;
twisti@2047 114 case vmIntrinsics::_dlog:
twisti@2047 115 do_Math_1to1(builder()->log());
twisti@2047 116 break;
twisti@2047 117 case vmIntrinsics::_dlog10:
twisti@2047 118 do_Math_1to1(builder()->log10());
twisti@2047 119 break;
twisti@2047 120 case vmIntrinsics::_dpow:
twisti@2047 121 do_Math_2to1(builder()->pow());
twisti@2047 122 break;
twisti@2047 123 case vmIntrinsics::_dexp:
twisti@2047 124 do_Math_1to1(builder()->exp());
twisti@2047 125 break;
twisti@2047 126
twisti@2047 127 // java.lang.Object
twisti@2047 128 case vmIntrinsics::_getClass:
twisti@2047 129 do_Object_getClass();
twisti@2047 130 break;
twisti@2047 131
twisti@2047 132 // java.lang.System
twisti@2047 133 case vmIntrinsics::_currentTimeMillis:
twisti@2047 134 do_System_currentTimeMillis();
twisti@2047 135 break;
twisti@2047 136
twisti@2047 137 // java.lang.Thread
twisti@2047 138 case vmIntrinsics::_currentThread:
twisti@2047 139 do_Thread_currentThread();
twisti@2047 140 break;
twisti@2047 141
twisti@2047 142 // sun.misc.Unsafe
twisti@2047 143 case vmIntrinsics::_compareAndSwapInt:
twisti@2047 144 do_Unsafe_compareAndSwapInt();
twisti@2047 145 break;
twisti@2047 146
twisti@2047 147 default:
twisti@2047 148 ShouldNotReachHere();
twisti@2047 149 }
twisti@2047 150 }
twisti@2047 151
twisti@2047 152 void SharkIntrinsics::do_Math_minmax(ICmpInst::Predicate p) {
twisti@2047 153 // Pop the arguments
twisti@2047 154 SharkValue *sb = state()->pop();
twisti@2047 155 SharkValue *sa = state()->pop();
twisti@2047 156 Value *a = sa->jint_value();
twisti@2047 157 Value *b = sb->jint_value();
twisti@2047 158
twisti@2047 159 // Perform the test
twisti@2047 160 BasicBlock *ip = builder()->GetBlockInsertionPoint();
twisti@2047 161 BasicBlock *return_a = builder()->CreateBlock(ip, "return_a");
twisti@2047 162 BasicBlock *return_b = builder()->CreateBlock(ip, "return_b");
twisti@2047 163 BasicBlock *done = builder()->CreateBlock(ip, "done");
twisti@2047 164
twisti@2047 165 builder()->CreateCondBr(builder()->CreateICmp(p, a, b), return_a, return_b);
twisti@2047 166
twisti@2047 167 builder()->SetInsertPoint(return_a);
twisti@2047 168 builder()->CreateBr(done);
twisti@2047 169
twisti@2047 170 builder()->SetInsertPoint(return_b);
twisti@2047 171 builder()->CreateBr(done);
twisti@2047 172
twisti@2047 173 builder()->SetInsertPoint(done);
twisti@2047 174 PHINode *phi = builder()->CreatePHI(a->getType(), "result");
twisti@2047 175 phi->addIncoming(a, return_a);
twisti@2047 176 phi->addIncoming(b, return_b);
twisti@2047 177
twisti@2047 178 // Push the result
twisti@2047 179 state()->push(
twisti@2047 180 SharkValue::create_jint(
twisti@2047 181 phi,
twisti@2047 182 sa->zero_checked() && sb->zero_checked()));
twisti@2047 183 }
twisti@2047 184
twisti@2047 185 void SharkIntrinsics::do_Math_1to1(Value *function) {
twisti@2047 186 SharkValue *empty = state()->pop();
twisti@2047 187 assert(empty == NULL, "should be");
twisti@2047 188 state()->push(
twisti@2047 189 SharkValue::create_jdouble(
twisti@2047 190 builder()->CreateCall(
twisti@2047 191 function, state()->pop()->jdouble_value())));
twisti@2047 192 state()->push(NULL);
twisti@2047 193 }
twisti@2047 194
twisti@2047 195 void SharkIntrinsics::do_Math_2to1(Value *function) {
twisti@2047 196 SharkValue *empty = state()->pop();
twisti@2047 197 assert(empty == NULL, "should be");
twisti@2047 198 Value *y = state()->pop()->jdouble_value();
twisti@2047 199 empty = state()->pop();
twisti@2047 200 assert(empty == NULL, "should be");
twisti@2047 201 Value *x = state()->pop()->jdouble_value();
twisti@2047 202
twisti@2047 203 state()->push(
twisti@2047 204 SharkValue::create_jdouble(
twisti@2047 205 builder()->CreateCall2(function, x, y)));
twisti@2047 206 state()->push(NULL);
twisti@2047 207 }
twisti@2047 208
twisti@2047 209 void SharkIntrinsics::do_Object_getClass() {
twisti@2047 210 Value *klass = builder()->CreateValueOfStructEntry(
twisti@2047 211 state()->pop()->jobject_value(),
twisti@2047 212 in_ByteSize(oopDesc::klass_offset_in_bytes()),
twisti@2047 213 SharkType::oop_type(),
twisti@2047 214 "klass");
twisti@2047 215
twisti@2047 216 Value *klass_part = builder()->CreateAddressOfStructEntry(
twisti@2047 217 klass,
twisti@2047 218 in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()),
twisti@2047 219 SharkType::klass_type(),
twisti@2047 220 "klass_part");
twisti@2047 221
twisti@2047 222 state()->push(
twisti@2047 223 SharkValue::create_jobject(
twisti@2047 224 builder()->CreateValueOfStructEntry(
twisti@2047 225 klass_part,
twisti@2047 226 in_ByteSize(Klass::java_mirror_offset_in_bytes()),
twisti@2047 227 SharkType::oop_type(),
twisti@2047 228 "java_mirror"),
twisti@2047 229 true));
twisti@2047 230 }
twisti@2047 231
twisti@2047 232 void SharkIntrinsics::do_System_currentTimeMillis() {
twisti@2047 233 state()->push(
twisti@2047 234 SharkValue::create_jlong(
twisti@2047 235 builder()->CreateCall(builder()->current_time_millis()),
twisti@2047 236 false));
twisti@2047 237 state()->push(NULL);
twisti@2047 238 }
twisti@2047 239
twisti@2047 240 void SharkIntrinsics::do_Thread_currentThread() {
twisti@2047 241 state()->push(
twisti@2047 242 SharkValue::create_jobject(
twisti@2047 243 builder()->CreateValueOfStructEntry(
twisti@2047 244 thread(), JavaThread::threadObj_offset(),
twisti@2047 245 SharkType::oop_type(),
twisti@2047 246 "threadObj"),
twisti@2047 247 true));
twisti@2047 248 }
twisti@2047 249
twisti@2047 250 void SharkIntrinsics::do_Unsafe_compareAndSwapInt() {
twisti@2047 251 // Pop the arguments
twisti@2047 252 Value *x = state()->pop()->jint_value();
twisti@2047 253 Value *e = state()->pop()->jint_value();
twisti@2047 254 SharkValue *empty = state()->pop();
twisti@2047 255 assert(empty == NULL, "should be");
twisti@2047 256 Value *offset = state()->pop()->jlong_value();
twisti@2047 257 Value *object = state()->pop()->jobject_value();
twisti@2047 258 Value *unsafe = state()->pop()->jobject_value();
twisti@2047 259
twisti@2047 260 // Convert the offset
twisti@2047 261 offset = builder()->CreateCall(
twisti@2047 262 builder()->unsafe_field_offset_to_byte_offset(),
twisti@2047 263 offset);
twisti@2047 264
twisti@2047 265 // Locate the field
twisti@2047 266 Value *addr = builder()->CreateIntToPtr(
twisti@2047 267 builder()->CreateAdd(
twisti@2047 268 builder()->CreatePtrToInt(object, SharkType::intptr_type()),
twisti@2047 269 builder()->CreateIntCast(offset, SharkType::intptr_type(), true)),
twisti@2047 270 PointerType::getUnqual(SharkType::jint_type()),
twisti@2047 271 "addr");
twisti@2047 272
twisti@2047 273 // Perform the operation
twisti@2047 274 Value *result = builder()->CreateCmpxchgInt(x, addr, e);
twisti@2047 275
twisti@2047 276 // Push the result
twisti@2047 277 state()->push(
twisti@2047 278 SharkValue::create_jint(
twisti@2047 279 builder()->CreateIntCast(
twisti@2047 280 builder()->CreateICmpEQ(result, e), SharkType::jint_type(), true),
twisti@2047 281 false));
twisti@2047 282 }

mercurial