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 43using namespace llvm; 44 45SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer) 46 : IRBuilder<>(SharkContext::current()), 47 _code_buffer(code_buffer) { 48} 49 50// Helpers for accessing structures 51Value* 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 58LoadInst* 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 70LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) { 71 return CreateValueOfStructEntry( 72 arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()), 73 SharkType::jint_type(), "length"); 74} 75 76Value* 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 96Value* 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 108Value* 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 120Type* 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 167FunctionType* 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. 186Value* 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. 196Value* 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 206Value* SharkBuilder::find_exception_handler() { 207 return make_function( 208 (address) SharkRuntime::find_exception_handler, "TIi", "i"); 209} 210 211Value* SharkBuilder::monitorenter() { 212 return make_function((address) SharkRuntime::monitorenter, "TM", "v"); 213} 214 215Value* SharkBuilder::monitorexit() { 216 return make_function((address) SharkRuntime::monitorexit, "TM", "v"); 217} 218 219Value* SharkBuilder::new_instance() { 220 return make_function((address) SharkRuntime::new_instance, "Ti", "v"); 221} 222 223Value* SharkBuilder::newarray() { 224 return make_function((address) SharkRuntime::newarray, "Tii", "v"); 225} 226 227Value* SharkBuilder::anewarray() { 228 return make_function((address) SharkRuntime::anewarray, "Tii", "v"); 229} 230 231Value* SharkBuilder::multianewarray() { 232 return make_function((address) SharkRuntime::multianewarray, "TiiI", "v"); 233} 234 235Value* SharkBuilder::register_finalizer() { 236 return make_function((address) SharkRuntime::register_finalizer, "TO", "v"); 237} 238 239Value* SharkBuilder::safepoint() { 240 return make_function((address) SafepointSynchronize::block, "T", "v"); 241} 242 243Value* SharkBuilder::throw_ArithmeticException() { 244 return make_function( 245 (address) SharkRuntime::throw_ArithmeticException, "TCi", "v"); 246} 247 248Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() { 249 return make_function( 250 (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v"); 251} 252 253Value* SharkBuilder::throw_ClassCastException() { 254 return make_function( 255 (address) SharkRuntime::throw_ClassCastException, "TCi", "v"); 256} 257 258Value* SharkBuilder::throw_NullPointerException() { 259 return make_function( 260 (address) SharkRuntime::throw_NullPointerException, "TCi", "v"); 261} 262 263// High-level non-VM calls 264 265Value* SharkBuilder::f2i() { 266 return make_function((address) SharedRuntime::f2i, "f", "i"); 267} 268 269Value* SharkBuilder::f2l() { 270 return make_function((address) SharedRuntime::f2l, "f", "l"); 271} 272 273Value* SharkBuilder::d2i() { 274 return make_function((address) SharedRuntime::d2i, "d", "i"); 275} 276 277Value* SharkBuilder::d2l() { 278 return make_function((address) SharedRuntime::d2l, "d", "l"); 279} 280 281Value* SharkBuilder::is_subtype_of() { 282 return make_function((address) SharkRuntime::is_subtype_of, "KK", "c"); 283} 284 285Value* SharkBuilder::current_time_millis() { 286 return make_function((address) os::javaTimeMillis, "", "l"); 287} 288 289Value* SharkBuilder::sin() { 290 return make_function("llvm.sin.f64", "d", "d"); 291} 292 293Value* SharkBuilder::cos() { 294 return make_function("llvm.cos.f64", "d", "d"); 295} 296 297Value* SharkBuilder::tan() { 298 return make_function((address) ::tan, "d", "d"); 299} 300 301Value* SharkBuilder::atan2() { 302 return make_function((address) ::atan2, "dd", "d"); 303} 304 305Value* SharkBuilder::sqrt() { 306 return make_function("llvm.sqrt.f64", "d", "d"); 307} 308 309Value* SharkBuilder::log() { 310 return make_function("llvm.log.f64", "d", "d"); 311} 312 313Value* SharkBuilder::log10() { 314 return make_function("llvm.log10.f64", "d", "d"); 315} 316 317Value* SharkBuilder::pow() { 318 return make_function("llvm.pow.f64", "dd", "d"); 319} 320 321Value* SharkBuilder::exp() { 322 return make_function("llvm.exp.f64", "d", "d"); 323} 324 325Value* SharkBuilder::fabs() { 326 return make_function((address) ::fabs, "d", "d"); 327} 328 329Value* SharkBuilder::unsafe_field_offset_to_byte_offset() { 330 return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l"); 331} 332 333Value* SharkBuilder::osr_migration_end() { 334 return make_function((address) SharedRuntime::OSR_migration_end, "C", "v"); 335} 336 337// Semi-VM calls 338 339Value* SharkBuilder::throw_StackOverflowError() { 340 return make_function((address) ZeroStack::handle_overflow, "T", "v"); 341} 342 343Value* SharkBuilder::uncommon_trap() { 344 return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i"); 345} 346 347Value* SharkBuilder::deoptimized_entry_point() { 348 return make_function((address) CppInterpreter::main_loop, "iT", "v"); 349} 350 351// Native-Java transition 352 353Value* 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 359Value* SharkBuilder::frame_address() { 360 return make_function("llvm.frameaddress", "i", "C"); 361} 362 363Value* 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 369Value* SharkBuilder::unimplemented() { 370 return make_function((address) report_unimplemented, "Ci", "v"); 371} 372 373Value* SharkBuilder::should_not_reach_here() { 374 return make_function((address) report_should_not_reach_here, "Ci", "v"); 375} 376 377Value* SharkBuilder::dump() { 378 return make_function((address) SharkRuntime::dump, "Cx", "v"); 379} 380 381// Public interface to low-level non-VM calls 382 383CallInst* SharkBuilder::CreateGetFrameAddress() { 384 return CreateCall(frame_address(), LLVMValue::jint_constant(0)); 385} 386 387CallInst* 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 395CallInst* 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 404CallInst* 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 414CallInst* 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 442void 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 462Value* SharkBuilder::code_buffer_address(int offset) { 463 return CreateAdd( 464 code_buffer()->base_pc(), 465 LLVMValue::intptr_constant(offset)); 466} 467 468Value* 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 476Value* 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 486Value* 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 498BasicBlock* 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 519BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const { 520 return BasicBlock::Create( 521 SharkContext::current(), name, GetInsertBlock()->getParent(), ip); 522} 523 524LoadInst* 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 528StoreInst* 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} 531