src/share/vm/shark/sharkIntrinsics.cpp

Tue, 08 Aug 2017 15:57:29 +0800

author
aoqi
date
Tue, 08 Aug 2017 15:57:29 +0800
changeset 6876
710a3c8b516e
parent 4314
2cd5e15048e6
parent 0
f90c822e73f8
permissions
-rw-r--r--

merge

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

mercurial