src/share/vm/shark/sharkIntrinsics.cpp

Wed, 11 Aug 2010 05:51:21 -0700

author
twisti
date
Wed, 11 Aug 2010 05:51:21 -0700
changeset 2047
d2ede61b7a12
child 2314
f95d63e2154a
permissions
-rw-r--r--

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>

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

mercurial