src/share/vm/shark/sharkIntrinsics.cpp

Tue, 18 Jun 2013 12:31:07 -0700

author
johnc
date
Tue, 18 Jun 2013 12:31:07 -0700
changeset 5277
01522ca68fc7
parent 4314
2cd5e15048e6
child 6876
710a3c8b516e
permissions
-rw-r--r--

8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets. Changes were also reviewed by Per Liden <per.liden@oracle.com>.
Reviewed-by: tschatzl, stefank, twisti

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@4314 174 PHINode *phi = builder()->CreatePHI(a->getType(), 0, "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@4314 213 SharkType::klass_type(),
twisti@2047 214 "klass");
twisti@2047 215
twisti@2047 216 state()->push(
twisti@2047 217 SharkValue::create_jobject(
twisti@2047 218 builder()->CreateValueOfStructEntry(
stefank@3391 219 klass,
stefank@3391 220 Klass::java_mirror_offset(),
twisti@2047 221 SharkType::oop_type(),
twisti@2047 222 "java_mirror"),
twisti@2047 223 true));
twisti@2047 224 }
twisti@2047 225
twisti@2047 226 void SharkIntrinsics::do_System_currentTimeMillis() {
twisti@2047 227 state()->push(
twisti@2047 228 SharkValue::create_jlong(
twisti@2047 229 builder()->CreateCall(builder()->current_time_millis()),
twisti@2047 230 false));
twisti@2047 231 state()->push(NULL);
twisti@2047 232 }
twisti@2047 233
twisti@2047 234 void SharkIntrinsics::do_Thread_currentThread() {
twisti@2047 235 state()->push(
twisti@2047 236 SharkValue::create_jobject(
twisti@2047 237 builder()->CreateValueOfStructEntry(
twisti@2047 238 thread(), JavaThread::threadObj_offset(),
twisti@2047 239 SharkType::oop_type(),
twisti@2047 240 "threadObj"),
twisti@2047 241 true));
twisti@2047 242 }
twisti@2047 243
twisti@2047 244 void SharkIntrinsics::do_Unsafe_compareAndSwapInt() {
twisti@2047 245 // Pop the arguments
twisti@2047 246 Value *x = state()->pop()->jint_value();
twisti@2047 247 Value *e = state()->pop()->jint_value();
twisti@2047 248 SharkValue *empty = state()->pop();
twisti@2047 249 assert(empty == NULL, "should be");
twisti@2047 250 Value *offset = state()->pop()->jlong_value();
twisti@2047 251 Value *object = state()->pop()->jobject_value();
twisti@2047 252 Value *unsafe = state()->pop()->jobject_value();
twisti@2047 253
twisti@2047 254 // Convert the offset
twisti@2047 255 offset = builder()->CreateCall(
twisti@2047 256 builder()->unsafe_field_offset_to_byte_offset(),
twisti@2047 257 offset);
twisti@2047 258
twisti@2047 259 // Locate the field
twisti@2047 260 Value *addr = builder()->CreateIntToPtr(
twisti@2047 261 builder()->CreateAdd(
twisti@2047 262 builder()->CreatePtrToInt(object, SharkType::intptr_type()),
twisti@2047 263 builder()->CreateIntCast(offset, SharkType::intptr_type(), true)),
twisti@2047 264 PointerType::getUnqual(SharkType::jint_type()),
twisti@2047 265 "addr");
twisti@2047 266
twisti@2047 267 // Perform the operation
twisti@4314 268 Value *result = builder()->CreateAtomicCmpXchg(addr, e, x, llvm::SequentiallyConsistent);
twisti@2047 269 // Push the result
twisti@2047 270 state()->push(
twisti@2047 271 SharkValue::create_jint(
twisti@2047 272 builder()->CreateIntCast(
twisti@2047 273 builder()->CreateICmpEQ(result, e), SharkType::jint_type(), true),
twisti@2047 274 false));
twisti@2047 275 }

mercurial