1 /* 2 * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. 3 * Copyright 2008, 2009, 2010 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 "precompiled.hpp" 27 #include "ci/ciMethod.hpp" 28 #include "gc/shared/barrierSet.hpp" 29 #include "gc/shared/cardTableModRefBS.hpp" 30 #include "memory/resourceArea.hpp" 31 #include "oops/method.hpp" 32 #include "prims/unsafe.hpp" 33 #include "runtime/os.hpp" 34 #include "runtime/synchronizer.hpp" 35 #include "runtime/thread.hpp" 36 #include "shark/llvmHeaders.hpp" 37 #include "shark/llvmValue.hpp" 38 #include "shark/sharkBuilder.hpp" 39 #include "shark/sharkContext.hpp" 40 #include "shark/sharkRuntime.hpp" 41 #include "utilities/debug.hpp" 42 43 using namespace llvm; 44 45 SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer) 46 : IRBuilder<>(SharkContext::current()), 47 _code_buffer(code_buffer) { 48 } 49 50 // Helpers for accessing structures 51 Value* SharkBuilder::CreateAddressOfStructEntry(Value* base, 52 ByteSize offset, 53 Type* type, 54 const char* name) { 55 return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name); 56 } 57 58 LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base, 59 ByteSize offset, 60 Type* type, 61 const char* name) { 62 return CreateLoad( 63 CreateAddressOfStructEntry( 64 base, offset, PointerType::getUnqual(type)), 65 name); 66 } 67 68 // Helpers for accessing arrays 69 70 LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) { 71 return CreateValueOfStructEntry( 72 arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()), 73 SharkType::jint_type(), "length"); 74 } 75 76 Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, 77 Type* element_type, 78 int element_bytes, 79 ByteSize base_offset, 80 Value* index, 81 const char* name) { 82 Value* offset = CreateIntCast(index, SharkType::intptr_type(), false); 83 if (element_bytes != 1) 84 offset = CreateShl( 85 offset, 86 LLVMValue::intptr_constant(exact_log2(element_bytes))); 87 offset = CreateAdd( 88 LLVMValue::intptr_constant(in_bytes(base_offset)), offset); 89 90 return CreateIntToPtr( 91 CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset), 92 PointerType::getUnqual(element_type), 93 name); 94 } 95 96 Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, 97 BasicType basic_type, 98 ByteSize base_offset, 99 Value* index, 100 const char* name) { 101 return CreateArrayAddress( 102 arrayoop, 103 SharkType::to_arrayType(basic_type), 104 type2aelembytes(basic_type), 105 base_offset, index, name); 106 } 107 108 Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, 109 BasicType basic_type, 110 Value* index, 111 const char* name) { 112 return CreateArrayAddress( 113 arrayoop, basic_type, 114 in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)), 115 index, name); 116 } 117 118 // Helpers for creating intrinsics and external functions. 119 120 Type* SharkBuilder::make_type(char type, bool void_ok) { 121 switch (type) { 122 // Primitive types 123 case 'c': 124 return SharkType::jbyte_type(); 125 case 'i': 126 return SharkType::jint_type(); 127 case 'l': 128 return SharkType::jlong_type(); 129 case 'x': 130 return SharkType::intptr_type(); 131 case 'f': 132 return SharkType::jfloat_type(); 133 case 'd': 134 return SharkType::jdouble_type(); 135 136 // Pointers to primitive types 137 case 'C': 138 case 'I': 139 case 'L': 140 case 'X': 141 case 'F': 142 case 'D': 143 return PointerType::getUnqual(make_type(tolower(type), false)); 144 145 // VM objects 146 case 'T': 147 return SharkType::thread_type(); 148 case 'M': 149 return PointerType::getUnqual(SharkType::monitor_type()); 150 case 'O': 151 return SharkType::oop_type(); 152 case 'K': 153 return SharkType::klass_type(); 154 155 // Miscellaneous 156 case 'v': 157 assert(void_ok, "should be"); 158 return SharkType::void_type(); 159 case '1': 160 return SharkType::bit_type(); 161 162 default: 163 ShouldNotReachHere(); 164 } 165 } 166 167 FunctionType* SharkBuilder::make_ftype(const char* params, 168 const char* ret) { 169 std::vector<Type*> param_types; 170 for (const char* c = params; *c; c++) 171 param_types.push_back(make_type(*c, false)); 172 173 assert(strlen(ret) == 1, "should be"); 174 Type *return_type = make_type(*ret, true); 175 176 return FunctionType::get(return_type, param_types, false); 177 } 178 179 // Create an object representing an intrinsic or external function by 180 // referencing the symbol by name. This is the LLVM-style approach, 181 // but it cannot be used on functions within libjvm.so its symbols 182 // are not exported. Note that you cannot make this work simply by 183 // exporting the symbols, as some symbols have the same names as 184 // symbols in the standard libraries (eg, atan2, fabs) and would 185 // obscure them were they visible. 186 Value* SharkBuilder::make_function(const char* name, 187 const char* params, 188 const char* ret) { 189 return SharkContext::current().get_external(name, make_ftype(params, ret)); 190 } 191 192 // Create an object representing an external function by inlining a 193 // function pointer in the code. This is not the LLVM way, but it's 194 // the only way to access functions in libjvm.so and functions like 195 // __kernel_dmb on ARM which is accessed via an absolute address. 196 Value* SharkBuilder::make_function(address func, 197 const char* params, 198 const char* ret) { 199 return CreateIntToPtr( 200 LLVMValue::intptr_constant((intptr_t) func), 201 PointerType::getUnqual(make_ftype(params, ret))); 202 } 203 204 // VM calls 205 206 Value* SharkBuilder::find_exception_handler() { 207 return make_function( 208 (address) SharkRuntime::find_exception_handler, "TIi", "i"); 209 } 210 211 Value* SharkBuilder::monitorenter() { 212 return make_function((address) SharkRuntime::monitorenter, "TM", "v"); 213 } 214 215 Value* SharkBuilder::monitorexit() { 216 return make_function((address) SharkRuntime::monitorexit, "TM", "v"); 217 } 218 219 Value* SharkBuilder::new_instance() { 220 return make_function((address) SharkRuntime::new_instance, "Ti", "v"); 221 } 222 223 Value* SharkBuilder::newarray() { 224 return make_function((address) SharkRuntime::newarray, "Tii", "v"); 225 } 226 227 Value* SharkBuilder::anewarray() { 228 return make_function((address) SharkRuntime::anewarray, "Tii", "v"); 229 } 230 231 Value* SharkBuilder::multianewarray() { 232 return make_function((address) SharkRuntime::multianewarray, "TiiI", "v"); 233 } 234 235 Value* SharkBuilder::register_finalizer() { 236 return make_function((address) SharkRuntime::register_finalizer, "TO", "v"); 237 } 238 239 Value* SharkBuilder::safepoint() { 240 return make_function((address) SafepointSynchronize::block, "T", "v"); 241 } 242 243 Value* SharkBuilder::throw_ArithmeticException() { 244 return make_function( 245 (address) SharkRuntime::throw_ArithmeticException, "TCi", "v"); 246 } 247 248 Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() { 249 return make_function( 250 (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v"); 251 } 252 253 Value* SharkBuilder::throw_ClassCastException() { 254 return make_function( 255 (address) SharkRuntime::throw_ClassCastException, "TCi", "v"); 256 } 257 258 Value* SharkBuilder::throw_NullPointerException() { 259 return make_function( 260 (address) SharkRuntime::throw_NullPointerException, "TCi", "v"); 261 } 262 263 // High-level non-VM calls 264 265 Value* SharkBuilder::f2i() { 266 return make_function((address) SharedRuntime::f2i, "f", "i"); 267 } 268 269 Value* SharkBuilder::f2l() { 270 return make_function((address) SharedRuntime::f2l, "f", "l"); 271 } 272 273 Value* SharkBuilder::d2i() { 274 return make_function((address) SharedRuntime::d2i, "d", "i"); 275 } 276 277 Value* SharkBuilder::d2l() { 278 return make_function((address) SharedRuntime::d2l, "d", "l"); 279 } 280 281 Value* SharkBuilder::is_subtype_of() { 282 return make_function((address) SharkRuntime::is_subtype_of, "KK", "c"); 283 } 284 285 Value* SharkBuilder::current_time_millis() { 286 return make_function((address) os::javaTimeMillis, "", "l"); 287 } 288 289 Value* SharkBuilder::sin() { 290 return make_function("llvm.sin.f64", "d", "d"); 291 } 292 293 Value* SharkBuilder::cos() { 294 return make_function("llvm.cos.f64", "d", "d"); 295 } 296 297 Value* SharkBuilder::tan() { 298 return make_function((address) ::tan, "d", "d"); 299 } 300 301 Value* SharkBuilder::atan2() { 302 return make_function((address) ::atan2, "dd", "d"); 303 } 304 305 Value* SharkBuilder::sqrt() { 306 return make_function("llvm.sqrt.f64", "d", "d"); 307 } 308 309 Value* SharkBuilder::log() { 310 return make_function("llvm.log.f64", "d", "d"); 311 } 312 313 Value* SharkBuilder::log10() { 314 return make_function("llvm.log10.f64", "d", "d"); 315 } 316 317 Value* SharkBuilder::pow() { 318 return make_function("llvm.pow.f64", "dd", "d"); 319 } 320 321 Value* SharkBuilder::exp() { 322 return make_function("llvm.exp.f64", "d", "d"); 323 } 324 325 Value* SharkBuilder::fabs() { 326 return make_function((address) ::fabs, "d", "d"); 327 } 328 329 Value* SharkBuilder::unsafe_field_offset_to_byte_offset() { 330 return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l"); 331 } 332 333 Value* SharkBuilder::osr_migration_end() { 334 return make_function((address) SharedRuntime::OSR_migration_end, "C", "v"); 335 } 336 337 // Semi-VM calls 338 339 Value* SharkBuilder::throw_StackOverflowError() { 340 return make_function((address) ZeroStack::handle_overflow, "T", "v"); 341 } 342 343 Value* SharkBuilder::uncommon_trap() { 344 return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i"); 345 } 346 347 Value* SharkBuilder::deoptimized_entry_point() { 348 return make_function((address) CppInterpreter::main_loop, "iT", "v"); 349 } 350 351 // Native-Java transition 352 353 Value* SharkBuilder::check_special_condition_for_native_trans() { 354 return make_function( 355 (address) JavaThread::check_special_condition_for_native_trans, 356 "T", "v"); 357 } 358 359 Value* SharkBuilder::frame_address() { 360 return make_function("llvm.frameaddress", "i", "C"); 361 } 362 363 Value* SharkBuilder::memset() { 364 // LLVM 2.8 added a fifth isVolatile field for memset 365 // introduced with LLVM r100304 366 return make_function("llvm.memset.p0i8.i32", "Cciii", "v"); 367 } 368 369 Value* SharkBuilder::unimplemented() { 370 return make_function((address) report_unimplemented, "Ci", "v"); 371 } 372 373 Value* SharkBuilder::should_not_reach_here() { 374 return make_function((address) report_should_not_reach_here, "Ci", "v"); 375 } 376 377 Value* SharkBuilder::dump() { 378 return make_function((address) SharkRuntime::dump, "Cx", "v"); 379 } 380 381 // Public interface to low-level non-VM calls 382 383 CallInst* SharkBuilder::CreateGetFrameAddress() { 384 return CreateCall(frame_address(), LLVMValue::jint_constant(0)); 385 } 386 387 CallInst* SharkBuilder::CreateMemset(Value* dst, 388 Value* value, 389 Value* len, 390 Value* align) { 391 return CreateCall5(memset(), dst, value, len, align, 392 LLVMValue::jint_constant(0)); 393 } 394 395 CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) { 396 return CreateCall2( 397 unimplemented(), 398 CreateIntToPtr( 399 LLVMValue::intptr_constant((intptr_t) file), 400 PointerType::getUnqual(SharkType::jbyte_type())), 401 LLVMValue::jint_constant(line)); 402 } 403 404 CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) { 405 return CreateCall2( 406 should_not_reach_here(), 407 CreateIntToPtr( 408 LLVMValue::intptr_constant((intptr_t) file), 409 PointerType::getUnqual(SharkType::jbyte_type())), 410 LLVMValue::jint_constant(line)); 411 } 412 413 #ifndef PRODUCT 414 CallInst* SharkBuilder::CreateDump(Value* value) { 415 const char *name; 416 if (value->hasName()) 417 // XXX this leaks, but it's only debug code 418 name = os::strdup(value->getName().str().c_str()); 419 else 420 name = "unnamed_value"; 421 422 if (isa<PointerType>(value->getType())) 423 value = CreatePtrToInt(value, SharkType::intptr_type()); 424 else if (value->getType()-> 425 isIntegerTy() 426 ) 427 value = CreateIntCast(value, SharkType::intptr_type(), false); 428 else 429 Unimplemented(); 430 431 return CreateCall2( 432 dump(), 433 CreateIntToPtr( 434 LLVMValue::intptr_constant((intptr_t) name), 435 PointerType::getUnqual(SharkType::jbyte_type())), 436 value); 437 } 438 #endif // PRODUCT 439 440 // HotSpot memory barriers 441 442 void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) { 443 if (bs->kind() != BarrierSet::CardTableForRS && 444 bs->kind() != BarrierSet::CardTableExtension) { 445 Unimplemented(); 446 } 447 448 CreateStore( 449 LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card_val()), 450 CreateIntToPtr( 451 CreateAdd( 452 LLVMValue::intptr_constant( 453 (intptr_t) (barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base)), 454 CreateLShr( 455 CreatePtrToInt(field, SharkType::intptr_type()), 456 LLVMValue::intptr_constant(CardTableModRefBS::card_shift))), 457 PointerType::getUnqual(SharkType::jbyte_type()))); 458 } 459 460 // Helpers for accessing the code buffer 461 462 Value* SharkBuilder::code_buffer_address(int offset) { 463 return CreateAdd( 464 code_buffer()->base_pc(), 465 LLVMValue::intptr_constant(offset)); 466 } 467 468 Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) { 469 return CreateLoad( 470 CreateIntToPtr( 471 code_buffer_address(code_buffer()->inline_oop(object)), 472 PointerType::getUnqual(SharkType::oop_type())), 473 name); 474 } 475 476 Value* SharkBuilder::CreateInlineMetadata(Metadata* metadata, llvm::PointerType* type, const char* name) { 477 assert(metadata != NULL, "inlined metadata must not be NULL"); 478 assert(metadata->is_metaspace_object(), "sanity check"); 479 return CreateLoad( 480 CreateIntToPtr( 481 code_buffer_address(code_buffer()->inline_Metadata(metadata)), 482 PointerType::getUnqual(type)), 483 name); 484 } 485 486 Value* SharkBuilder::CreateInlineData(void* data, 487 size_t size, 488 Type* type, 489 const char* name) { 490 return CreateIntToPtr( 491 code_buffer_address(code_buffer()->inline_data(data, size)), 492 type, 493 name); 494 } 495 496 // Helpers for creating basic blocks. 497 498 BasicBlock* SharkBuilder::GetBlockInsertionPoint() const { 499 BasicBlock *cur = GetInsertBlock(); 500 501 // BasicBlock::Create takes an insertBefore argument, so 502 // we need to find the block _after_ the current block 503 Function::iterator iter = cur->getParent()->begin(); 504 Function::iterator end = cur->getParent()->end(); 505 while (iter != end) { 506 iter++; 507 if (&*iter == cur) { 508 iter++; 509 break; 510 } 511 } 512 513 if (iter == end) 514 return NULL; 515 else 516 return iter; 517 } 518 519 BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const { 520 return BasicBlock::Create( 521 SharkContext::current(), name, GetInsertBlock()->getParent(), ip); 522 } 523 524 LoadInst* SharkBuilder::CreateAtomicLoad(Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) { 525 return Insert(new LoadInst(ptr, name, isVolatile, align, ordering, synchScope), name); 526 } 527 528 StoreInst* SharkBuilder::CreateAtomicStore(Value* val, Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) { 529 return Insert(new StoreInst(val, ptr, isVolatile, align, ordering, synchScope), name); 530 }