1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "dex_file-inl.h" 18 #include "driver/compiler_driver.h" 19 #include "driver/dex_compilation_unit.h" 20 #include "intrinsic_helper.h" 21 #include "ir_builder.h" 22 #include "method_reference.h" 23 #include "mirror/art_method.h" 24 #include "mirror/array.h" 25 #include "mirror/string.h" 26 #include "thread.h" 27 #include "utils_llvm.h" 28 #include "verifier/method_verifier.h" 29 30 #include "dex/compiler_ir.h" 31 #include "dex/mir_graph.h" 32 #include "dex/quick/mir_to_lir.h" 33 34 #include <llvm/ADT/STLExtras.h> 35 #include <llvm/IR/Intrinsics.h> 36 #include <llvm/IR/Metadata.h> 37 #include <llvm/Pass.h> 38 #include <llvm/Support/CFG.h> 39 #include <llvm/Support/InstIterator.h> 40 41 #include <vector> 42 #include <map> 43 #include <utility> 44 45 using ::art::kMIRIgnoreNullCheck; 46 using ::art::kMIRIgnoreRangeCheck; 47 using ::art::llvm::IRBuilder; 48 using ::art::llvm::IntrinsicHelper; 49 using ::art::llvm::JType; 50 using ::art::llvm::RuntimeSupportBuilder; 51 using ::art::llvm::kBoolean; 52 using ::art::llvm::kByte; 53 using ::art::llvm::kChar; 54 using ::art::llvm::kDouble; 55 using ::art::llvm::kFloat; 56 using ::art::llvm::kInt; 57 using ::art::llvm::kLikely; 58 using ::art::llvm::kLong; 59 using ::art::llvm::kObject; 60 using ::art::llvm::kShort; 61 using ::art::llvm::kTBAAConstJObject; 62 using ::art::llvm::kTBAAHeapArray; 63 using ::art::llvm::kTBAAHeapInstance; 64 using ::art::llvm::kTBAAHeapStatic; 65 using ::art::llvm::kTBAARegister; 66 using ::art::llvm::kTBAARuntimeInfo; 67 using ::art::llvm::kTBAAShadowFrame; 68 using ::art::llvm::kUnlikely; 69 using ::art::llvm::kVoid; 70 using ::art::llvm::runtime_support::AllocArray; 71 using ::art::llvm::runtime_support::AllocArrayWithAccessCheck; 72 using ::art::llvm::runtime_support::AllocObject; 73 using ::art::llvm::runtime_support::AllocObjectWithAccessCheck; 74 using ::art::llvm::runtime_support::CheckAndAllocArray; 75 using ::art::llvm::runtime_support::CheckAndAllocArrayWithAccessCheck; 76 using ::art::llvm::runtime_support::CheckCast; 77 using ::art::llvm::runtime_support::CheckPutArrayElement; 78 using ::art::llvm::runtime_support::FillArrayData; 79 using ::art::llvm::runtime_support::FindCatchBlock; 80 using ::art::llvm::runtime_support::FindDirectMethodWithAccessCheck; 81 using ::art::llvm::runtime_support::FindInterfaceMethod; 82 using ::art::llvm::runtime_support::FindInterfaceMethodWithAccessCheck; 83 using ::art::llvm::runtime_support::FindStaticMethodWithAccessCheck; 84 using ::art::llvm::runtime_support::FindSuperMethodWithAccessCheck; 85 using ::art::llvm::runtime_support::FindVirtualMethodWithAccessCheck; 86 using ::art::llvm::runtime_support::Get32Instance; 87 using ::art::llvm::runtime_support::Get32Static; 88 using ::art::llvm::runtime_support::Get64Instance; 89 using ::art::llvm::runtime_support::Get64Static; 90 using ::art::llvm::runtime_support::GetObjectInstance; 91 using ::art::llvm::runtime_support::GetObjectStatic; 92 using ::art::llvm::runtime_support::InitializeStaticStorage; 93 using ::art::llvm::runtime_support::InitializeType; 94 using ::art::llvm::runtime_support::InitializeTypeAndVerifyAccess; 95 using ::art::llvm::runtime_support::IsAssignable; 96 using ::art::llvm::runtime_support::ResolveString; 97 using ::art::llvm::runtime_support::RuntimeId; 98 using ::art::llvm::runtime_support::Set32Instance; 99 using ::art::llvm::runtime_support::Set32Static; 100 using ::art::llvm::runtime_support::Set64Instance; 101 using ::art::llvm::runtime_support::Set64Static; 102 using ::art::llvm::runtime_support::SetObjectInstance; 103 using ::art::llvm::runtime_support::SetObjectStatic; 104 using ::art::llvm::runtime_support::ThrowDivZeroException; 105 using ::art::llvm::runtime_support::ThrowException; 106 using ::art::llvm::runtime_support::ThrowIndexOutOfBounds; 107 using ::art::llvm::runtime_support::ThrowNullPointerException; 108 using ::art::llvm::runtime_support::ThrowStackOverflowException; 109 using ::art::llvm::runtime_support::art_d2i; 110 using ::art::llvm::runtime_support::art_d2l; 111 using ::art::llvm::runtime_support::art_f2i; 112 using ::art::llvm::runtime_support::art_f2l; 113 114 namespace art { 115 extern char RemapShorty(char shortyType); 116 } // namespace art 117 118 namespace { 119 120 class GBCExpanderPass : public llvm::FunctionPass { 121 private: 122 const IntrinsicHelper& intrinsic_helper_; 123 IRBuilder& irb_; 124 125 llvm::LLVMContext& context_; 126 RuntimeSupportBuilder& rtb_; 127 128 private: 129 llvm::AllocaInst* shadow_frame_; 130 llvm::Value* old_shadow_frame_; 131 132 private: 133 art::CompilerDriver* const driver_; 134 135 const art::DexCompilationUnit* const dex_compilation_unit_; 136 137 llvm::Function* func_; 138 139 std::vector<llvm::BasicBlock*> basic_blocks_; 140 141 std::vector<llvm::BasicBlock*> basic_block_landing_pads_; 142 llvm::BasicBlock* current_bb_; 143 std::map<llvm::BasicBlock*, std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*> > > 144 landing_pad_phi_mapping_; 145 llvm::BasicBlock* basic_block_unwind_; 146 147 // Maps each vreg to its shadow frame address. 148 std::vector<llvm::Value*> shadow_frame_vreg_addresses_; 149 150 bool changed_; 151 152 private: 153 //---------------------------------------------------------------------------- 154 // Constant for GBC expansion 155 //---------------------------------------------------------------------------- 156 enum IntegerShiftKind { 157 kIntegerSHL, 158 kIntegerSHR, 159 kIntegerUSHR, 160 }; 161 162 private: 163 //---------------------------------------------------------------------------- 164 // Helper function for GBC expansion 165 //---------------------------------------------------------------------------- 166 167 llvm::Value* ExpandToRuntime(RuntimeId rt, llvm::CallInst& inst); 168 169 uint64_t LV2UInt(llvm::Value* lv) { 170 return llvm::cast<llvm::ConstantInt>(lv)->getZExtValue(); 171 } 172 173 int64_t LV2SInt(llvm::Value* lv) { 174 return llvm::cast<llvm::ConstantInt>(lv)->getSExtValue(); 175 } 176 177 private: 178 // TODO: Almost all Emit* are directly copy-n-paste from MethodCompiler. 179 // Refactor these utility functions from MethodCompiler to avoid forking. 180 181 void EmitStackOverflowCheck(llvm::Instruction* first_non_alloca); 182 183 void RewriteFunction(); 184 185 void RewriteBasicBlock(llvm::BasicBlock* original_block); 186 187 void UpdatePhiInstruction(llvm::BasicBlock* old_basic_block, 188 llvm::BasicBlock* new_basic_block); 189 190 191 // Sign or zero extend category 1 types < 32bits in size to 32bits. 192 llvm::Value* SignOrZeroExtendCat1Types(llvm::Value* value, JType jty); 193 194 // Truncate category 1 types from 32bits to the given JType size. 195 llvm::Value* TruncateCat1Types(llvm::Value* value, JType jty); 196 197 //---------------------------------------------------------------------------- 198 // Dex cache code generation helper function 199 //---------------------------------------------------------------------------- 200 llvm::Value* EmitLoadDexCacheAddr(art::MemberOffset dex_cache_offset); 201 202 llvm::Value* EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx); 203 204 llvm::Value* EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx); 205 206 llvm::Value* EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx); 207 208 llvm::Value* EmitLoadDexCacheStringFieldAddr(uint32_t string_idx); 209 210 //---------------------------------------------------------------------------- 211 // Code generation helper function 212 //---------------------------------------------------------------------------- 213 llvm::Value* EmitLoadMethodObjectAddr(); 214 215 llvm::Value* EmitLoadArrayLength(llvm::Value* array); 216 217 llvm::Value* EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx); 218 219 llvm::Value* EmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx, 220 llvm::Value* this_addr); 221 222 llvm::Value* EmitArrayGEP(llvm::Value* array_addr, 223 llvm::Value* index_value, 224 JType elem_jty); 225 226 //---------------------------------------------------------------------------- 227 // Invoke helper function 228 //---------------------------------------------------------------------------- 229 llvm::Value* EmitInvoke(llvm::CallInst& call_inst); 230 231 //---------------------------------------------------------------------------- 232 // Inlining helper functions 233 //---------------------------------------------------------------------------- 234 bool EmitIntrinsic(llvm::CallInst& call_inst, llvm::Value** result); 235 236 bool EmitIntrinsicStringLengthOrIsEmpty(llvm::CallInst& call_inst, 237 llvm::Value** result, bool is_empty); 238 239 private: 240 //---------------------------------------------------------------------------- 241 // Expand Greenland intrinsics 242 //---------------------------------------------------------------------------- 243 void Expand_TestSuspend(llvm::CallInst& call_inst); 244 245 void Expand_MarkGCCard(llvm::CallInst& call_inst); 246 247 llvm::Value* Expand_LoadStringFromDexCache(llvm::Value* string_idx_value); 248 249 llvm::Value* Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value); 250 251 void Expand_LockObject(llvm::Value* obj); 252 253 void Expand_UnlockObject(llvm::Value* obj); 254 255 llvm::Value* Expand_ArrayGet(llvm::Value* array_addr, 256 llvm::Value* index_value, 257 JType elem_jty); 258 259 void Expand_ArrayPut(llvm::Value* new_value, 260 llvm::Value* array_addr, 261 llvm::Value* index_value, 262 JType elem_jty); 263 264 void Expand_FilledNewArray(llvm::CallInst& call_inst); 265 266 llvm::Value* Expand_IGetFast(llvm::Value* field_offset_value, 267 llvm::Value* is_volatile_value, 268 llvm::Value* object_addr, 269 JType field_jty); 270 271 void Expand_IPutFast(llvm::Value* field_offset_value, 272 llvm::Value* is_volatile_value, 273 llvm::Value* object_addr, 274 llvm::Value* new_value, 275 JType field_jty); 276 277 llvm::Value* Expand_SGetFast(llvm::Value* static_storage_addr, 278 llvm::Value* field_offset_value, 279 llvm::Value* is_volatile_value, 280 JType field_jty); 281 282 void Expand_SPutFast(llvm::Value* static_storage_addr, 283 llvm::Value* field_offset_value, 284 llvm::Value* is_volatile_value, 285 llvm::Value* new_value, 286 JType field_jty); 287 288 llvm::Value* Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr); 289 290 llvm::Value* Expand_LoadClassSSBFromDexCache(llvm::Value* type_idx_value); 291 292 llvm::Value* 293 Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value); 294 295 llvm::Value* 296 Expand_GetVirtualCalleeMethodObjAddrFast(llvm::Value* vtable_idx_value, 297 llvm::Value* this_addr); 298 299 llvm::Value* Expand_Invoke(llvm::CallInst& call_inst); 300 301 llvm::Value* Expand_DivRem(llvm::CallInst& call_inst, bool is_div, JType op_jty); 302 303 void Expand_AllocaShadowFrame(llvm::Value* num_vregs_value); 304 305 void Expand_SetVReg(llvm::Value* entry_idx, llvm::Value* obj); 306 307 void Expand_PopShadowFrame(); 308 309 void Expand_UpdateDexPC(llvm::Value* dex_pc_value); 310 311 //---------------------------------------------------------------------------- 312 // Quick 313 //---------------------------------------------------------------------------- 314 315 llvm::Value* Expand_FPCompare(llvm::Value* src1_value, 316 llvm::Value* src2_value, 317 bool gt_bias); 318 319 llvm::Value* Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value); 320 321 llvm::Value* EmitCompareResultSelection(llvm::Value* cmp_eq, 322 llvm::Value* cmp_lt); 323 324 llvm::Value* EmitLoadConstantClass(uint32_t dex_pc, uint32_t type_idx); 325 llvm::Value* EmitLoadStaticStorage(uint32_t dex_pc, uint32_t type_idx); 326 327 llvm::Value* Expand_HLIGet(llvm::CallInst& call_inst, JType field_jty); 328 void Expand_HLIPut(llvm::CallInst& call_inst, JType field_jty); 329 330 llvm::Value* Expand_HLSget(llvm::CallInst& call_inst, JType field_jty); 331 void Expand_HLSput(llvm::CallInst& call_inst, JType field_jty); 332 333 llvm::Value* Expand_HLArrayGet(llvm::CallInst& call_inst, JType field_jty); 334 void Expand_HLArrayPut(llvm::CallInst& call_inst, JType field_jty); 335 336 llvm::Value* Expand_ConstString(llvm::CallInst& call_inst); 337 llvm::Value* Expand_ConstClass(llvm::CallInst& call_inst); 338 339 void Expand_MonitorEnter(llvm::CallInst& call_inst); 340 void Expand_MonitorExit(llvm::CallInst& call_inst); 341 342 void Expand_HLCheckCast(llvm::CallInst& call_inst); 343 llvm::Value* Expand_InstanceOf(llvm::CallInst& call_inst); 344 345 llvm::Value* Expand_NewInstance(llvm::CallInst& call_inst); 346 347 llvm::Value* Expand_HLInvoke(llvm::CallInst& call_inst); 348 349 llvm::Value* Expand_OptArrayLength(llvm::CallInst& call_inst); 350 llvm::Value* Expand_NewArray(llvm::CallInst& call_inst); 351 llvm::Value* Expand_HLFilledNewArray(llvm::CallInst& call_inst); 352 void Expand_HLFillArrayData(llvm::CallInst& call_inst); 353 354 llvm::Value* EmitAllocNewArray(uint32_t dex_pc, 355 llvm::Value* array_length_value, 356 uint32_t type_idx, 357 bool is_filled_new_array); 358 359 llvm::Value* EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx, 360 art::InvokeType invoke_type, 361 llvm::Value* this_addr, 362 uint32_t dex_pc, 363 bool is_fast_path); 364 365 void EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr); 366 367 void EmitUpdateDexPC(uint32_t dex_pc); 368 369 void EmitGuard_DivZeroException(uint32_t dex_pc, 370 llvm::Value* denominator, 371 JType op_jty); 372 373 void EmitGuard_NullPointerException(uint32_t dex_pc, llvm::Value* object, 374 int opt_flags); 375 376 void EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc, 377 llvm::Value* array, 378 llvm::Value* index, 379 int opt_flags); 380 381 llvm::FunctionType* GetFunctionType(llvm::Type* ret_type, uint32_t method_idx, bool is_static); 382 383 llvm::BasicBlock* GetBasicBlock(uint32_t dex_pc); 384 385 llvm::BasicBlock* CreateBasicBlockWithDexPC(uint32_t dex_pc, 386 const char* postfix); 387 388 int32_t GetTryItemOffset(uint32_t dex_pc); 389 390 llvm::BasicBlock* GetLandingPadBasicBlock(uint32_t dex_pc); 391 392 llvm::BasicBlock* GetUnwindBasicBlock(); 393 394 void EmitGuard_ExceptionLandingPad(uint32_t dex_pc); 395 396 void EmitBranchExceptionLandingPad(uint32_t dex_pc); 397 398 //---------------------------------------------------------------------------- 399 // Expand Arithmetic Helper Intrinsics 400 //---------------------------------------------------------------------------- 401 402 llvm::Value* Expand_IntegerShift(llvm::Value* src1_value, 403 llvm::Value* src2_value, 404 IntegerShiftKind kind, 405 JType op_jty); 406 407 public: 408 static char ID; 409 410 GBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb, 411 art::CompilerDriver* driver, const art::DexCompilationUnit* dex_compilation_unit) 412 : llvm::FunctionPass(ID), intrinsic_helper_(intrinsic_helper), irb_(irb), 413 context_(irb.getContext()), rtb_(irb.Runtime()), 414 shadow_frame_(NULL), old_shadow_frame_(NULL), 415 driver_(driver), 416 dex_compilation_unit_(dex_compilation_unit), 417 func_(NULL), current_bb_(NULL), basic_block_unwind_(NULL), changed_(false) {} 418 419 bool runOnFunction(llvm::Function& func); 420 421 private: 422 void InsertStackOverflowCheck(llvm::Function& func); 423 424 llvm::Value* ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id, 425 llvm::CallInst& call_inst); 426 }; 427 428 char GBCExpanderPass::ID = 0; 429 430 bool GBCExpanderPass::runOnFunction(llvm::Function& func) { 431 VLOG(compiler) << "GBC expansion on " << func.getName().str(); 432 433 // Runtime support or stub 434 if (dex_compilation_unit_ == NULL) { 435 return false; 436 } 437 438 // Setup rewrite context 439 shadow_frame_ = NULL; 440 old_shadow_frame_ = NULL; 441 func_ = &func; 442 changed_ = false; // Assume unchanged 443 444 shadow_frame_vreg_addresses_.resize(dex_compilation_unit_->GetCodeItem()->registers_size_, NULL); 445 basic_blocks_.resize(dex_compilation_unit_->GetCodeItem()->insns_size_in_code_units_); 446 basic_block_landing_pads_.resize(dex_compilation_unit_->GetCodeItem()->tries_size_, NULL); 447 basic_block_unwind_ = NULL; 448 for (llvm::Function::iterator bb_iter = func_->begin(), bb_end = func_->end(); 449 bb_iter != bb_end; 450 ++bb_iter) { 451 if (bb_iter->begin()->getMetadata("DexOff") == NULL) { 452 continue; 453 } 454 uint32_t dex_pc = LV2UInt(bb_iter->begin()->getMetadata("DexOff")->getOperand(0)); 455 basic_blocks_[dex_pc] = bb_iter; 456 } 457 458 // Insert stack overflow check 459 InsertStackOverflowCheck(func); // TODO: Use intrinsic. 460 461 // Rewrite the intrinsics 462 RewriteFunction(); 463 464 VERIFY_LLVM_FUNCTION(func); 465 466 return changed_; 467 } 468 469 void GBCExpanderPass::RewriteBasicBlock(llvm::BasicBlock* original_block) { 470 llvm::BasicBlock* curr_basic_block = original_block; 471 472 llvm::BasicBlock::iterator inst_iter = original_block->begin(); 473 llvm::BasicBlock::iterator inst_end = original_block->end(); 474 475 while (inst_iter != inst_end) { 476 llvm::CallInst* call_inst = llvm::dyn_cast<llvm::CallInst>(inst_iter); 477 IntrinsicHelper::IntrinsicId intr_id = IntrinsicHelper::UnknownId; 478 479 if (call_inst) { 480 llvm::Function* callee_func = call_inst->getCalledFunction(); 481 intr_id = intrinsic_helper_.GetIntrinsicId(callee_func); 482 } 483 484 if (intr_id == IntrinsicHelper::UnknownId) { 485 // This is not intrinsic call. Skip this instruction. 486 ++inst_iter; 487 continue; 488 } 489 490 // Rewrite the intrinsic and change the function 491 changed_ = true; 492 irb_.SetInsertPoint(inst_iter); 493 494 // Expand the intrinsic 495 if (llvm::Value* new_value = ExpandIntrinsic(intr_id, *call_inst)) { 496 inst_iter->replaceAllUsesWith(new_value); 497 } 498 499 // Remove the old intrinsic call instruction 500 llvm::BasicBlock::iterator old_inst = inst_iter++; 501 old_inst->eraseFromParent(); 502 503 // Splice the instruction to the new basic block 504 llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock(); 505 if (next_basic_block != curr_basic_block) { 506 next_basic_block->getInstList().splice( 507 irb_.GetInsertPoint(), curr_basic_block->getInstList(), 508 inst_iter, inst_end); 509 curr_basic_block = next_basic_block; 510 inst_end = curr_basic_block->end(); 511 } 512 } 513 } 514 515 516 void GBCExpanderPass::RewriteFunction() { 517 size_t num_basic_blocks = func_->getBasicBlockList().size(); 518 // NOTE: We are not using (bb_iter != bb_end) as the for-loop condition, 519 // because we will create new basic block while expanding the intrinsics. 520 // We only want to iterate through the input basic blocks. 521 522 landing_pad_phi_mapping_.clear(); 523 524 for (llvm::Function::iterator bb_iter = func_->begin(); 525 num_basic_blocks > 0; ++bb_iter, --num_basic_blocks) { 526 // Set insert point to current basic block. 527 irb_.SetInsertPoint(bb_iter); 528 529 current_bb_ = bb_iter; 530 531 // Rewrite the basic block 532 RewriteBasicBlock(bb_iter); 533 534 // Update the phi-instructions in the successor basic block 535 llvm::BasicBlock* last_block = irb_.GetInsertBlock(); 536 if (last_block != bb_iter) { 537 UpdatePhiInstruction(bb_iter, last_block); 538 } 539 } 540 541 typedef std::map<llvm::PHINode*, llvm::PHINode*> HandlerPHIMap; 542 HandlerPHIMap handler_phi; 543 // Iterate every used landing pad basic block 544 for (size_t i = 0, ei = basic_block_landing_pads_.size(); i != ei; ++i) { 545 llvm::BasicBlock* lbb = basic_block_landing_pads_[i]; 546 if (lbb == NULL) { 547 continue; 548 } 549 550 llvm::TerminatorInst* term_inst = lbb->getTerminator(); 551 std::vector<std::pair<llvm::BasicBlock*, llvm::BasicBlock*> >& rewrite_pair 552 = landing_pad_phi_mapping_[lbb]; 553 irb_.SetInsertPoint(lbb->begin()); 554 555 // Iterate every succeeding basic block (catch block) 556 for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors(); 557 succ_iter != succ_end; ++succ_iter) { 558 llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter); 559 560 // Iterate every phi instructions in the succeeding basic block 561 for (llvm::BasicBlock::iterator 562 inst_iter = succ_basic_block->begin(), 563 inst_end = succ_basic_block->end(); 564 inst_iter != inst_end; ++inst_iter) { 565 llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter); 566 567 if (!phi) { 568 break; // Meet non-phi instruction. Done. 569 } 570 571 if (handler_phi[phi] == NULL) { 572 handler_phi[phi] = llvm::PHINode::Create(phi->getType(), 1); 573 } 574 575 // Create new_phi in landing pad 576 llvm::PHINode* new_phi = irb_.CreatePHI(phi->getType(), rewrite_pair.size()); 577 // Insert all incoming value into new_phi by rewrite_pair 578 for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) { 579 llvm::BasicBlock* old_bb = rewrite_pair[j].first; 580 llvm::BasicBlock* new_bb = rewrite_pair[j].second; 581 new_phi->addIncoming(phi->getIncomingValueForBlock(old_bb), new_bb); 582 } 583 // Delete all incoming value from phi by rewrite_pair 584 for (size_t j = 0, ej = rewrite_pair.size(); j != ej; ++j) { 585 llvm::BasicBlock* old_bb = rewrite_pair[j].first; 586 int old_bb_idx = phi->getBasicBlockIndex(old_bb); 587 if (old_bb_idx >= 0) { 588 phi->removeIncomingValue(old_bb_idx, false); 589 } 590 } 591 // Insert new_phi into new handler phi 592 handler_phi[phi]->addIncoming(new_phi, lbb); 593 } 594 } 595 } 596 597 // Replace all handler phi 598 // We can't just use the old handler phi, because some exception edges will disappear after we 599 // compute fast-path. 600 for (HandlerPHIMap::iterator it = handler_phi.begin(); it != handler_phi.end(); ++it) { 601 llvm::PHINode* old_phi = it->first; 602 llvm::PHINode* new_phi = it->second; 603 new_phi->insertBefore(old_phi); 604 old_phi->replaceAllUsesWith(new_phi); 605 old_phi->eraseFromParent(); 606 } 607 } 608 609 void GBCExpanderPass::UpdatePhiInstruction(llvm::BasicBlock* old_basic_block, 610 llvm::BasicBlock* new_basic_block) { 611 llvm::TerminatorInst* term_inst = new_basic_block->getTerminator(); 612 613 if (!term_inst) { 614 return; // No terminating instruction in new_basic_block. Nothing to do. 615 } 616 617 // Iterate every succeeding basic block 618 for (unsigned succ_iter = 0, succ_end = term_inst->getNumSuccessors(); 619 succ_iter != succ_end; ++succ_iter) { 620 llvm::BasicBlock* succ_basic_block = term_inst->getSuccessor(succ_iter); 621 622 // Iterate every phi instructions in the succeeding basic block 623 for (llvm::BasicBlock::iterator 624 inst_iter = succ_basic_block->begin(), 625 inst_end = succ_basic_block->end(); 626 inst_iter != inst_end; ++inst_iter) { 627 llvm::PHINode *phi = llvm::dyn_cast<llvm::PHINode>(inst_iter); 628 629 if (!phi) { 630 break; // Meet non-phi instruction. Done. 631 } 632 633 // Update the incoming block of this phi instruction 634 for (llvm::PHINode::block_iterator 635 ibb_iter = phi->block_begin(), ibb_end = phi->block_end(); 636 ibb_iter != ibb_end; ++ibb_iter) { 637 if (*ibb_iter == old_basic_block) { 638 *ibb_iter = new_basic_block; 639 } 640 } 641 } 642 } 643 } 644 645 llvm::Value* GBCExpanderPass::ExpandToRuntime(RuntimeId rt, llvm::CallInst& inst) { 646 // Some GBC intrinsic can directly replace with IBC runtime. "Directly" means 647 // the arguments passed to the GBC intrinsic are as the same as IBC runtime 648 // function, therefore only called function is needed to change. 649 unsigned num_args = inst.getNumArgOperands(); 650 651 if (num_args <= 0) { 652 return irb_.CreateCall(irb_.GetRuntime(rt)); 653 } else { 654 std::vector<llvm::Value*> args; 655 for (unsigned i = 0; i < num_args; i++) { 656 args.push_back(inst.getArgOperand(i)); 657 } 658 659 return irb_.CreateCall(irb_.GetRuntime(rt), args); 660 } 661 } 662 663 void 664 GBCExpanderPass::EmitStackOverflowCheck(llvm::Instruction* first_non_alloca) { 665 llvm::Function* func = first_non_alloca->getParent()->getParent(); 666 llvm::Module* module = func->getParent(); 667 668 // Call llvm intrinsic function to get frame address. 669 llvm::Function* frameaddress = 670 llvm::Intrinsic::getDeclaration(module, llvm::Intrinsic::frameaddress); 671 672 // The type of llvm::frameaddress is: i8* @llvm.frameaddress(i32) 673 llvm::Value* frame_address = irb_.CreateCall(frameaddress, irb_.getInt32(0)); 674 675 // Cast i8* to int 676 frame_address = irb_.CreatePtrToInt(frame_address, irb_.getPtrEquivIntTy()); 677 678 // Get thread.stack_end_ 679 llvm::Value* stack_end = 680 irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::StackEndOffset().Int32Value(), 681 irb_.getPtrEquivIntTy(), 682 kTBAARuntimeInfo); 683 684 // Check the frame address < thread.stack_end_ ? 685 llvm::Value* is_stack_overflow = irb_.CreateICmpULT(frame_address, stack_end); 686 687 llvm::BasicBlock* block_exception = 688 llvm::BasicBlock::Create(context_, "stack_overflow", func); 689 690 llvm::BasicBlock* block_continue = 691 llvm::BasicBlock::Create(context_, "stack_overflow_cont", func); 692 693 irb_.CreateCondBr(is_stack_overflow, block_exception, block_continue, kUnlikely); 694 695 // If stack overflow, throw exception. 696 irb_.SetInsertPoint(block_exception); 697 irb_.CreateCall(irb_.GetRuntime(ThrowStackOverflowException)); 698 699 // Unwind. 700 llvm::Type* ret_type = func->getReturnType(); 701 if (ret_type->isVoidTy()) { 702 irb_.CreateRetVoid(); 703 } else { 704 // The return value is ignored when there's an exception. MethodCompiler 705 // returns zero value under the the corresponding return type in this case. 706 // GBCExpander returns LLVM undef value here for brevity 707 irb_.CreateRet(llvm::UndefValue::get(ret_type)); 708 } 709 710 irb_.SetInsertPoint(block_continue); 711 } 712 713 llvm::Value* GBCExpanderPass::EmitLoadDexCacheAddr(art::MemberOffset offset) { 714 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 715 716 return irb_.LoadFromObjectOffset(method_object_addr, 717 offset.Int32Value(), 718 irb_.getJObjectTy(), 719 kTBAAConstJObject); 720 } 721 722 llvm::Value* 723 GBCExpanderPass::EmitLoadDexCacheStaticStorageFieldAddr(uint32_t type_idx) { 724 llvm::Value* static_storage_dex_cache_addr = 725 EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheInitializedStaticStorageOffset()); 726 727 llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx); 728 729 return EmitArrayGEP(static_storage_dex_cache_addr, type_idx_value, kObject); 730 } 731 732 llvm::Value* 733 GBCExpanderPass::EmitLoadDexCacheResolvedTypeFieldAddr(uint32_t type_idx) { 734 llvm::Value* resolved_type_dex_cache_addr = 735 EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheResolvedTypesOffset()); 736 737 llvm::Value* type_idx_value = irb_.getPtrEquivInt(type_idx); 738 739 return EmitArrayGEP(resolved_type_dex_cache_addr, type_idx_value, kObject); 740 } 741 742 llvm::Value* GBCExpanderPass:: 743 EmitLoadDexCacheResolvedMethodFieldAddr(uint32_t method_idx) { 744 llvm::Value* resolved_method_dex_cache_addr = 745 EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheResolvedMethodsOffset()); 746 747 llvm::Value* method_idx_value = irb_.getPtrEquivInt(method_idx); 748 749 return EmitArrayGEP(resolved_method_dex_cache_addr, method_idx_value, kObject); 750 } 751 752 llvm::Value* GBCExpanderPass:: 753 EmitLoadDexCacheStringFieldAddr(uint32_t string_idx) { 754 llvm::Value* string_dex_cache_addr = 755 EmitLoadDexCacheAddr(art::mirror::ArtMethod::DexCacheStringsOffset()); 756 757 llvm::Value* string_idx_value = irb_.getPtrEquivInt(string_idx); 758 759 return EmitArrayGEP(string_dex_cache_addr, string_idx_value, kObject); 760 } 761 762 llvm::Value* GBCExpanderPass::EmitLoadMethodObjectAddr() { 763 llvm::Function* parent_func = irb_.GetInsertBlock()->getParent(); 764 return parent_func->arg_begin(); 765 } 766 767 llvm::Value* GBCExpanderPass::EmitLoadArrayLength(llvm::Value* array) { 768 // Load array length 769 return irb_.LoadFromObjectOffset(array, 770 art::mirror::Array::LengthOffset().Int32Value(), 771 irb_.getJIntTy(), 772 kTBAAConstJObject); 773 } 774 775 llvm::Value* 776 GBCExpanderPass::EmitLoadSDCalleeMethodObjectAddr(uint32_t callee_method_idx) { 777 llvm::Value* callee_method_object_field_addr = 778 EmitLoadDexCacheResolvedMethodFieldAddr(callee_method_idx); 779 780 return irb_.CreateLoad(callee_method_object_field_addr, kTBAARuntimeInfo); 781 } 782 783 llvm::Value* GBCExpanderPass:: 784 EmitLoadVirtualCalleeMethodObjectAddr(int vtable_idx, llvm::Value* this_addr) { 785 // Load class object of *this* pointer 786 llvm::Value* class_object_addr = 787 irb_.LoadFromObjectOffset(this_addr, 788 art::mirror::Object::ClassOffset().Int32Value(), 789 irb_.getJObjectTy(), 790 kTBAAConstJObject); 791 792 // Load vtable address 793 llvm::Value* vtable_addr = 794 irb_.LoadFromObjectOffset(class_object_addr, 795 art::mirror::Class::VTableOffset().Int32Value(), 796 irb_.getJObjectTy(), 797 kTBAAConstJObject); 798 799 // Load callee method object 800 llvm::Value* vtable_idx_value = 801 irb_.getPtrEquivInt(static_cast<uint64_t>(vtable_idx)); 802 803 llvm::Value* method_field_addr = 804 EmitArrayGEP(vtable_addr, vtable_idx_value, kObject); 805 806 return irb_.CreateLoad(method_field_addr, kTBAAConstJObject); 807 } 808 809 // Emit Array GetElementPtr 810 llvm::Value* GBCExpanderPass::EmitArrayGEP(llvm::Value* array_addr, 811 llvm::Value* index_value, 812 JType elem_jty) { 813 int data_offset; 814 if (elem_jty == kLong || elem_jty == kDouble || 815 (elem_jty == kObject && sizeof(uint64_t) == sizeof(art::mirror::Object*))) { 816 data_offset = art::mirror::Array::DataOffset(sizeof(int64_t)).Int32Value(); 817 } else { 818 data_offset = art::mirror::Array::DataOffset(sizeof(int32_t)).Int32Value(); 819 } 820 821 llvm::Constant* data_offset_value = 822 irb_.getPtrEquivInt(data_offset); 823 824 llvm::Type* elem_type = irb_.getJType(elem_jty); 825 826 llvm::Value* array_data_addr = 827 irb_.CreatePtrDisp(array_addr, data_offset_value, 828 elem_type->getPointerTo()); 829 830 return irb_.CreateGEP(array_data_addr, index_value); 831 } 832 833 llvm::Value* GBCExpanderPass::EmitInvoke(llvm::CallInst& call_inst) { 834 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 835 art::InvokeType invoke_type = 836 static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0))); 837 bool is_static = (invoke_type == art::kStatic); 838 art::MethodReference target_method(dex_compilation_unit_->GetDexFile(), 839 LV2UInt(call_inst.getArgOperand(1))); 840 841 // Load *this* actual parameter 842 llvm::Value* this_addr = (!is_static) ? call_inst.getArgOperand(3) : NULL; 843 844 // Compute invoke related information for compiler decision 845 int vtable_idx = -1; 846 uintptr_t direct_code = 0; 847 uintptr_t direct_method = 0; 848 bool is_fast_path = driver_->ComputeInvokeInfo(dex_compilation_unit_, dex_pc, 849 invoke_type, target_method, 850 vtable_idx, 851 direct_code, direct_method, 852 true); 853 // Load the method object 854 llvm::Value* callee_method_object_addr = NULL; 855 856 if (!is_fast_path) { 857 callee_method_object_addr = 858 EmitCallRuntimeForCalleeMethodObjectAddr(target_method.dex_method_index, invoke_type, 859 this_addr, dex_pc, is_fast_path); 860 } else { 861 switch (invoke_type) { 862 case art::kStatic: 863 case art::kDirect: 864 if (direct_method != 0u && 865 direct_method != static_cast<uintptr_t>(-1)) { 866 callee_method_object_addr = 867 irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_method), 868 irb_.getJObjectTy()); 869 } else { 870 callee_method_object_addr = 871 EmitLoadSDCalleeMethodObjectAddr(target_method.dex_method_index); 872 } 873 break; 874 875 case art::kVirtual: 876 DCHECK_NE(vtable_idx, -1); 877 callee_method_object_addr = 878 EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr); 879 break; 880 881 case art::kSuper: 882 LOG(FATAL) << "invoke-super should be promoted to invoke-direct in " 883 "the fast path."; 884 break; 885 886 case art::kInterface: 887 callee_method_object_addr = 888 EmitCallRuntimeForCalleeMethodObjectAddr(target_method.dex_method_index, 889 invoke_type, this_addr, 890 dex_pc, is_fast_path); 891 break; 892 } 893 } 894 895 // Load the actual parameter 896 std::vector<llvm::Value*> args; 897 898 args.push_back(callee_method_object_addr); // method object for callee 899 900 for (uint32_t i = 3; i < call_inst.getNumArgOperands(); ++i) { 901 args.push_back(call_inst.getArgOperand(i)); 902 } 903 904 llvm::Value* code_addr; 905 llvm::Type* func_type = GetFunctionType(call_inst.getType(), 906 target_method.dex_method_index, is_static); 907 if (direct_code != 0u && direct_code != static_cast<uintptr_t>(-1)) { 908 code_addr = 909 irb_.CreateIntToPtr(irb_.getPtrEquivInt(direct_code), 910 func_type->getPointerTo()); 911 } else { 912 code_addr = 913 irb_.LoadFromObjectOffset(callee_method_object_addr, 914 art::mirror::ArtMethod::GetEntryPointFromCompiledCodeOffset().Int32Value(), 915 func_type->getPointerTo(), kTBAARuntimeInfo); 916 } 917 918 // Invoke callee 919 EmitUpdateDexPC(dex_pc); 920 llvm::Value* retval = irb_.CreateCall(code_addr, args); 921 EmitGuard_ExceptionLandingPad(dex_pc); 922 923 return retval; 924 } 925 926 bool GBCExpanderPass::EmitIntrinsic(llvm::CallInst& call_inst, 927 llvm::Value** result) { 928 DCHECK(result != NULL); 929 930 uint32_t callee_method_idx = LV2UInt(call_inst.getArgOperand(1)); 931 std::string callee_method_name( 932 PrettyMethod(callee_method_idx, *dex_compilation_unit_->GetDexFile())); 933 934 if (callee_method_name == "int java.lang.String.length()") { 935 return EmitIntrinsicStringLengthOrIsEmpty(call_inst, result, 936 false /* is_empty */); 937 } 938 if (callee_method_name == "boolean java.lang.String.isEmpty()") { 939 return EmitIntrinsicStringLengthOrIsEmpty(call_inst, result, 940 true /* is_empty */); 941 } 942 943 *result = NULL; 944 return false; 945 } 946 947 bool GBCExpanderPass::EmitIntrinsicStringLengthOrIsEmpty(llvm::CallInst& call_inst, 948 llvm::Value** result, 949 bool is_empty) { 950 art::InvokeType invoke_type = 951 static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0))); 952 DCHECK_NE(invoke_type, art::kStatic); 953 DCHECK_EQ(call_inst.getNumArgOperands(), 4U); 954 955 llvm::Value* this_object = call_inst.getArgOperand(3); 956 llvm::Value* string_count = 957 irb_.LoadFromObjectOffset(this_object, 958 art::mirror::String::CountOffset().Int32Value(), 959 irb_.getJIntTy(), 960 kTBAAConstJObject); 961 if (is_empty) { 962 llvm::Value* count_equals_zero = irb_.CreateICmpEQ(string_count, 963 irb_.getJInt(0)); 964 llvm::Value* is_empty = irb_.CreateSelect(count_equals_zero, 965 irb_.getJBoolean(true), 966 irb_.getJBoolean(false)); 967 is_empty = SignOrZeroExtendCat1Types(is_empty, kBoolean); 968 *result = is_empty; 969 } else { 970 *result = string_count; 971 } 972 return true; 973 } 974 975 void GBCExpanderPass::Expand_TestSuspend(llvm::CallInst& call_inst) { 976 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 977 978 llvm::Value* suspend_count = 979 irb_.Runtime().EmitLoadFromThreadOffset(art::Thread::ThreadFlagsOffset().Int32Value(), 980 irb_.getInt16Ty(), 981 kTBAARuntimeInfo); 982 llvm::Value* is_suspend = irb_.CreateICmpNE(suspend_count, irb_.getInt16(0)); 983 984 llvm::BasicBlock* basic_block_suspend = CreateBasicBlockWithDexPC(dex_pc, "suspend"); 985 llvm::BasicBlock* basic_block_cont = CreateBasicBlockWithDexPC(dex_pc, "suspend_cont"); 986 987 irb_.CreateCondBr(is_suspend, basic_block_suspend, basic_block_cont, kUnlikely); 988 989 irb_.SetInsertPoint(basic_block_suspend); 990 if (dex_pc != art::DexFile::kDexNoIndex) { 991 EmitUpdateDexPC(dex_pc); 992 } 993 irb_.Runtime().EmitTestSuspend(); 994 995 llvm::BasicBlock* basic_block_exception = CreateBasicBlockWithDexPC(dex_pc, "exception"); 996 llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending(); 997 irb_.CreateCondBr(exception_pending, basic_block_exception, basic_block_cont, kUnlikely); 998 999 irb_.SetInsertPoint(basic_block_exception); 1000 llvm::Type* ret_type = call_inst.getParent()->getParent()->getReturnType(); 1001 if (ret_type->isVoidTy()) { 1002 irb_.CreateRetVoid(); 1003 } else { 1004 // The return value is ignored when there's an exception. 1005 irb_.CreateRet(llvm::UndefValue::get(ret_type)); 1006 } 1007 1008 irb_.SetInsertPoint(basic_block_cont); 1009 return; 1010 } 1011 1012 void GBCExpanderPass::Expand_MarkGCCard(llvm::CallInst& call_inst) { 1013 irb_.Runtime().EmitMarkGCCard(call_inst.getArgOperand(0), call_inst.getArgOperand(1)); 1014 return; 1015 } 1016 1017 llvm::Value* 1018 GBCExpanderPass::Expand_LoadStringFromDexCache(llvm::Value* string_idx_value) { 1019 uint32_t string_idx = 1020 llvm::cast<llvm::ConstantInt>(string_idx_value)->getZExtValue(); 1021 1022 llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx); 1023 1024 return irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo); 1025 } 1026 1027 llvm::Value* 1028 GBCExpanderPass::Expand_LoadTypeFromDexCache(llvm::Value* type_idx_value) { 1029 uint32_t type_idx = 1030 llvm::cast<llvm::ConstantInt>(type_idx_value)->getZExtValue(); 1031 1032 llvm::Value* type_field_addr = 1033 EmitLoadDexCacheResolvedTypeFieldAddr(type_idx); 1034 1035 return irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo); 1036 } 1037 1038 void GBCExpanderPass::Expand_LockObject(llvm::Value* obj) { 1039 rtb_.EmitLockObject(obj); 1040 return; 1041 } 1042 1043 void GBCExpanderPass::Expand_UnlockObject(llvm::Value* obj) { 1044 rtb_.EmitUnlockObject(obj); 1045 return; 1046 } 1047 1048 llvm::Value* GBCExpanderPass::Expand_ArrayGet(llvm::Value* array_addr, 1049 llvm::Value* index_value, 1050 JType elem_jty) { 1051 llvm::Value* array_elem_addr = 1052 EmitArrayGEP(array_addr, index_value, elem_jty); 1053 1054 return irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty); 1055 } 1056 1057 void GBCExpanderPass::Expand_ArrayPut(llvm::Value* new_value, 1058 llvm::Value* array_addr, 1059 llvm::Value* index_value, 1060 JType elem_jty) { 1061 llvm::Value* array_elem_addr = 1062 EmitArrayGEP(array_addr, index_value, elem_jty); 1063 1064 irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty); 1065 1066 return; 1067 } 1068 1069 void GBCExpanderPass::Expand_FilledNewArray(llvm::CallInst& call_inst) { 1070 // Most of the codes refer to MethodCompiler::EmitInsn_FilledNewArray 1071 llvm::Value* array = call_inst.getArgOperand(0); 1072 1073 uint32_t element_jty = 1074 llvm::cast<llvm::ConstantInt>(call_inst.getArgOperand(1))->getZExtValue(); 1075 1076 DCHECK_GT(call_inst.getNumArgOperands(), 2U); 1077 unsigned num_elements = (call_inst.getNumArgOperands() - 2); 1078 1079 bool is_elem_int_ty = (static_cast<JType>(element_jty) == kInt); 1080 1081 uint32_t alignment; 1082 llvm::Constant* elem_size; 1083 llvm::PointerType* field_type; 1084 1085 // NOTE: Currently filled-new-array only supports 'L', '[', and 'I' 1086 // as the element, thus we are only checking 2 cases: primitive int and 1087 // non-primitive type. 1088 if (is_elem_int_ty) { 1089 alignment = sizeof(int32_t); 1090 elem_size = irb_.getPtrEquivInt(sizeof(int32_t)); 1091 field_type = irb_.getJIntTy()->getPointerTo(); 1092 } else { 1093 alignment = irb_.getSizeOfPtrEquivInt(); 1094 elem_size = irb_.getSizeOfPtrEquivIntValue(); 1095 field_type = irb_.getJObjectTy()->getPointerTo(); 1096 } 1097 1098 llvm::Value* data_field_offset = 1099 irb_.getPtrEquivInt(art::mirror::Array::DataOffset(alignment).Int32Value()); 1100 1101 llvm::Value* data_field_addr = 1102 irb_.CreatePtrDisp(array, data_field_offset, field_type); 1103 1104 for (unsigned i = 0; i < num_elements; ++i) { 1105 // Values to fill the array begin at the 3rd argument 1106 llvm::Value* reg_value = call_inst.getArgOperand(2 + i); 1107 1108 irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray); 1109 1110 data_field_addr = 1111 irb_.CreatePtrDisp(data_field_addr, elem_size, field_type); 1112 } 1113 1114 return; 1115 } 1116 1117 llvm::Value* GBCExpanderPass::Expand_IGetFast(llvm::Value* field_offset_value, 1118 llvm::Value* /*is_volatile_value*/, 1119 llvm::Value* object_addr, 1120 JType field_jty) { 1121 int field_offset = 1122 llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 1123 1124 DCHECK_GE(field_offset, 0); 1125 1126 llvm::PointerType* field_type = 1127 irb_.getJType(field_jty)->getPointerTo(); 1128 1129 field_offset_value = irb_.getPtrEquivInt(field_offset); 1130 1131 llvm::Value* field_addr = 1132 irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 1133 1134 // TODO: Check is_volatile. We need to generate atomic load instruction 1135 // when is_volatile is true. 1136 return irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty); 1137 } 1138 1139 void GBCExpanderPass::Expand_IPutFast(llvm::Value* field_offset_value, 1140 llvm::Value* /* is_volatile_value */, 1141 llvm::Value* object_addr, 1142 llvm::Value* new_value, 1143 JType field_jty) { 1144 int field_offset = 1145 llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 1146 1147 DCHECK_GE(field_offset, 0); 1148 1149 llvm::PointerType* field_type = 1150 irb_.getJType(field_jty)->getPointerTo(); 1151 1152 field_offset_value = irb_.getPtrEquivInt(field_offset); 1153 1154 llvm::Value* field_addr = 1155 irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 1156 1157 // TODO: Check is_volatile. We need to generate atomic store instruction 1158 // when is_volatile is true. 1159 irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty); 1160 1161 return; 1162 } 1163 1164 llvm::Value* GBCExpanderPass::Expand_SGetFast(llvm::Value* static_storage_addr, 1165 llvm::Value* field_offset_value, 1166 llvm::Value* /*is_volatile_value*/, 1167 JType field_jty) { 1168 int field_offset = 1169 llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 1170 1171 DCHECK_GE(field_offset, 0); 1172 1173 llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 1174 1175 llvm::Value* static_field_addr = 1176 irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 1177 irb_.getJType(field_jty)->getPointerTo()); 1178 1179 // TODO: Check is_volatile. We need to generate atomic store instruction 1180 // when is_volatile is true. 1181 return irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty); 1182 } 1183 1184 void GBCExpanderPass::Expand_SPutFast(llvm::Value* static_storage_addr, 1185 llvm::Value* field_offset_value, 1186 llvm::Value* /* is_volatile_value */, 1187 llvm::Value* new_value, 1188 JType field_jty) { 1189 int field_offset = 1190 llvm::cast<llvm::ConstantInt>(field_offset_value)->getSExtValue(); 1191 1192 DCHECK_GE(field_offset, 0); 1193 1194 llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 1195 1196 llvm::Value* static_field_addr = 1197 irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 1198 irb_.getJType(field_jty)->getPointerTo()); 1199 1200 // TODO: Check is_volatile. We need to generate atomic store instruction 1201 // when is_volatile is true. 1202 irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty); 1203 1204 return; 1205 } 1206 1207 llvm::Value* 1208 GBCExpanderPass::Expand_LoadDeclaringClassSSB(llvm::Value* method_object_addr) { 1209 return irb_.LoadFromObjectOffset(method_object_addr, 1210 art::mirror::ArtMethod::DeclaringClassOffset().Int32Value(), 1211 irb_.getJObjectTy(), 1212 kTBAAConstJObject); 1213 } 1214 1215 llvm::Value* 1216 GBCExpanderPass::Expand_LoadClassSSBFromDexCache(llvm::Value* type_idx_value) { 1217 uint32_t type_idx = 1218 llvm::cast<llvm::ConstantInt>(type_idx_value)->getZExtValue(); 1219 1220 llvm::Value* storage_field_addr = 1221 EmitLoadDexCacheStaticStorageFieldAddr(type_idx); 1222 1223 return irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo); 1224 } 1225 1226 llvm::Value* 1227 GBCExpanderPass::Expand_GetSDCalleeMethodObjAddrFast(llvm::Value* callee_method_idx_value) { 1228 uint32_t callee_method_idx = 1229 llvm::cast<llvm::ConstantInt>(callee_method_idx_value)->getZExtValue(); 1230 1231 return EmitLoadSDCalleeMethodObjectAddr(callee_method_idx); 1232 } 1233 1234 llvm::Value* GBCExpanderPass::Expand_GetVirtualCalleeMethodObjAddrFast( 1235 llvm::Value* vtable_idx_value, 1236 llvm::Value* this_addr) { 1237 int vtable_idx = 1238 llvm::cast<llvm::ConstantInt>(vtable_idx_value)->getSExtValue(); 1239 1240 return EmitLoadVirtualCalleeMethodObjectAddr(vtable_idx, this_addr); 1241 } 1242 1243 llvm::Value* GBCExpanderPass::Expand_Invoke(llvm::CallInst& call_inst) { 1244 // Most of the codes refer to MethodCompiler::EmitInsn_Invoke 1245 llvm::Value* callee_method_object_addr = call_inst.getArgOperand(0); 1246 unsigned num_args = call_inst.getNumArgOperands(); 1247 llvm::Type* ret_type = call_inst.getType(); 1248 1249 // Determine the function type of the callee method 1250 std::vector<llvm::Type*> args_type; 1251 std::vector<llvm::Value*> args; 1252 for (unsigned i = 0; i < num_args; i++) { 1253 args.push_back(call_inst.getArgOperand(i)); 1254 args_type.push_back(args[i]->getType()); 1255 } 1256 1257 llvm::FunctionType* callee_method_type = 1258 llvm::FunctionType::get(ret_type, args_type, false); 1259 1260 llvm::Value* code_addr = 1261 irb_.LoadFromObjectOffset(callee_method_object_addr, 1262 art::mirror::ArtMethod::GetEntryPointFromCompiledCodeOffset().Int32Value(), 1263 callee_method_type->getPointerTo(), 1264 kTBAARuntimeInfo); 1265 1266 // Invoke callee 1267 llvm::Value* retval = irb_.CreateCall(code_addr, args); 1268 1269 return retval; 1270 } 1271 1272 llvm::Value* GBCExpanderPass::Expand_DivRem(llvm::CallInst& call_inst, 1273 bool is_div, JType op_jty) { 1274 llvm::Value* dividend = call_inst.getArgOperand(0); 1275 llvm::Value* divisor = call_inst.getArgOperand(1); 1276 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1277 EmitGuard_DivZeroException(dex_pc, divisor, op_jty); 1278 // Most of the codes refer to MethodCompiler::EmitIntDivRemResultComputation 1279 1280 // Check the special case: MININT / -1 = MININT 1281 // That case will cause overflow, which is undefined behavior in llvm. 1282 // So we check the divisor is -1 or not, if the divisor is -1, we do 1283 // the special path to avoid undefined behavior. 1284 llvm::Type* op_type = irb_.getJType(op_jty); 1285 llvm::Value* zero = irb_.getJZero(op_jty); 1286 llvm::Value* neg_one = llvm::ConstantInt::getSigned(op_type, -1); 1287 1288 llvm::Function* parent = irb_.GetInsertBlock()->getParent(); 1289 llvm::BasicBlock* eq_neg_one = llvm::BasicBlock::Create(context_, "", parent); 1290 llvm::BasicBlock* ne_neg_one = llvm::BasicBlock::Create(context_, "", parent); 1291 llvm::BasicBlock* neg_one_cont = 1292 llvm::BasicBlock::Create(context_, "", parent); 1293 1294 llvm::Value* is_equal_neg_one = irb_.CreateICmpEQ(divisor, neg_one); 1295 irb_.CreateCondBr(is_equal_neg_one, eq_neg_one, ne_neg_one, kUnlikely); 1296 1297 // If divisor == -1 1298 irb_.SetInsertPoint(eq_neg_one); 1299 llvm::Value* eq_result; 1300 if (is_div) { 1301 // We can just change from "dividend div -1" to "neg dividend". The sub 1302 // don't care the sign/unsigned because of two's complement representation. 1303 // And the behavior is what we want: 1304 // -(2^n) (2^n)-1 1305 // MININT < k <= MAXINT -> mul k -1 = -k 1306 // MININT == k -> mul k -1 = k 1307 // 1308 // LLVM use sub to represent 'neg' 1309 eq_result = irb_.CreateSub(zero, dividend); 1310 } else { 1311 // Everything modulo -1 will be 0. 1312 eq_result = zero; 1313 } 1314 irb_.CreateBr(neg_one_cont); 1315 1316 // If divisor != -1, just do the division. 1317 irb_.SetInsertPoint(ne_neg_one); 1318 llvm::Value* ne_result; 1319 if (is_div) { 1320 ne_result = irb_.CreateSDiv(dividend, divisor); 1321 } else { 1322 ne_result = irb_.CreateSRem(dividend, divisor); 1323 } 1324 irb_.CreateBr(neg_one_cont); 1325 1326 irb_.SetInsertPoint(neg_one_cont); 1327 llvm::PHINode* result = irb_.CreatePHI(op_type, 2); 1328 result->addIncoming(eq_result, eq_neg_one); 1329 result->addIncoming(ne_result, ne_neg_one); 1330 1331 return result; 1332 } 1333 1334 void GBCExpanderPass::Expand_AllocaShadowFrame(llvm::Value* num_vregs_value) { 1335 // Most of the codes refer to MethodCompiler::EmitPrologueAllocShadowFrame and 1336 // MethodCompiler::EmitPushShadowFrame 1337 uint16_t num_vregs = 1338 llvm::cast<llvm::ConstantInt>(num_vregs_value)->getZExtValue(); 1339 1340 llvm::StructType* shadow_frame_type = 1341 irb_.getShadowFrameTy(num_vregs); 1342 1343 // Create allocas at the start of entry block. 1344 llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP(); 1345 llvm::BasicBlock* entry_block = &func_->front(); 1346 irb_.SetInsertPoint(&entry_block->front()); 1347 1348 shadow_frame_ = irb_.CreateAlloca(shadow_frame_type); 1349 1350 // Alloca a pointer to old shadow frame 1351 old_shadow_frame_ = 1352 irb_.CreateAlloca(shadow_frame_type->getElementType(0)->getPointerTo()); 1353 1354 irb_.restoreIP(irb_ip_original); 1355 1356 // Push the shadow frame 1357 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1358 1359 llvm::Value* shadow_frame_upcast = 1360 irb_.CreateConstGEP2_32(shadow_frame_, 0, 0); 1361 1362 llvm::Value* result = rtb_.EmitPushShadowFrame(shadow_frame_upcast, 1363 method_object_addr, 1364 num_vregs); 1365 1366 irb_.CreateStore(result, old_shadow_frame_, kTBAARegister); 1367 1368 return; 1369 } 1370 1371 void GBCExpanderPass::Expand_SetVReg(llvm::Value* entry_idx, 1372 llvm::Value* value) { 1373 unsigned vreg_idx = LV2UInt(entry_idx); 1374 DCHECK_LT(vreg_idx, dex_compilation_unit_->GetCodeItem()->registers_size_); 1375 1376 llvm::Value* vreg_addr = shadow_frame_vreg_addresses_[vreg_idx]; 1377 if (UNLIKELY(vreg_addr == NULL)) { 1378 DCHECK(shadow_frame_ != NULL); 1379 1380 llvm::Value* gep_index[] = { 1381 irb_.getInt32(0), // No pointer displacement 1382 irb_.getInt32(1), // VRegs 1383 entry_idx // Pointer field 1384 }; 1385 1386 // A shadow frame address must dominate every use in the function so we 1387 // place it in the entry block right after the allocas. 1388 llvm::BasicBlock::iterator first_non_alloca = func_->getEntryBlock().begin(); 1389 while (llvm::isa<llvm::AllocaInst>(first_non_alloca)) { 1390 ++first_non_alloca; 1391 } 1392 1393 llvm::IRBuilderBase::InsertPoint ip = irb_.saveIP(); 1394 irb_.SetInsertPoint(static_cast<llvm::Instruction*>(first_non_alloca)); 1395 vreg_addr = irb_.CreateGEP(shadow_frame_, gep_index); 1396 shadow_frame_vreg_addresses_[vreg_idx] = vreg_addr; 1397 irb_.restoreIP(ip); 1398 } 1399 1400 irb_.CreateStore(value, 1401 irb_.CreateBitCast(vreg_addr, value->getType()->getPointerTo()), 1402 kTBAAShadowFrame); 1403 return; 1404 } 1405 1406 void GBCExpanderPass::Expand_PopShadowFrame() { 1407 if (old_shadow_frame_ == NULL) { 1408 return; 1409 } 1410 rtb_.EmitPopShadowFrame(irb_.CreateLoad(old_shadow_frame_, kTBAARegister)); 1411 return; 1412 } 1413 1414 void GBCExpanderPass::Expand_UpdateDexPC(llvm::Value* dex_pc_value) { 1415 irb_.StoreToObjectOffset(shadow_frame_, 1416 art::ShadowFrame::DexPCOffset(), 1417 dex_pc_value, 1418 kTBAAShadowFrame); 1419 return; 1420 } 1421 1422 void GBCExpanderPass::InsertStackOverflowCheck(llvm::Function& func) { 1423 // All alloca instructions are generated in the first basic block of the 1424 // function, and there are no alloca instructions after the first non-alloca 1425 // instruction. 1426 1427 llvm::BasicBlock* first_basic_block = &func.front(); 1428 1429 // Look for first non-alloca instruction 1430 llvm::BasicBlock::iterator first_non_alloca = first_basic_block->begin(); 1431 while (llvm::isa<llvm::AllocaInst>(first_non_alloca)) { 1432 ++first_non_alloca; 1433 } 1434 1435 irb_.SetInsertPoint(first_non_alloca); 1436 1437 // Insert stack overflow check codes before first_non_alloca (i.e., after all 1438 // alloca instructions) 1439 EmitStackOverflowCheck(&*first_non_alloca); 1440 1441 irb_.Runtime().EmitTestSuspend(); 1442 1443 llvm::BasicBlock* next_basic_block = irb_.GetInsertBlock(); 1444 if (next_basic_block != first_basic_block) { 1445 // Splice the rest of the instruction to the continuing basic block 1446 next_basic_block->getInstList().splice( 1447 irb_.GetInsertPoint(), first_basic_block->getInstList(), 1448 first_non_alloca, first_basic_block->end()); 1449 1450 // Rewrite the basic block 1451 RewriteBasicBlock(next_basic_block); 1452 1453 // Update the phi-instructions in the successor basic block 1454 UpdatePhiInstruction(first_basic_block, irb_.GetInsertBlock()); 1455 } 1456 1457 // We have changed the basic block 1458 changed_ = true; 1459 } 1460 1461 // ==== High-level intrinsic expander ========================================== 1462 1463 llvm::Value* GBCExpanderPass::Expand_FPCompare(llvm::Value* src1_value, 1464 llvm::Value* src2_value, 1465 bool gt_bias) { 1466 llvm::Value* cmp_eq = irb_.CreateFCmpOEQ(src1_value, src2_value); 1467 llvm::Value* cmp_lt; 1468 1469 if (gt_bias) { 1470 cmp_lt = irb_.CreateFCmpOLT(src1_value, src2_value); 1471 } else { 1472 cmp_lt = irb_.CreateFCmpULT(src1_value, src2_value); 1473 } 1474 1475 return EmitCompareResultSelection(cmp_eq, cmp_lt); 1476 } 1477 1478 llvm::Value* GBCExpanderPass::Expand_LongCompare(llvm::Value* src1_value, llvm::Value* src2_value) { 1479 llvm::Value* cmp_eq = irb_.CreateICmpEQ(src1_value, src2_value); 1480 llvm::Value* cmp_lt = irb_.CreateICmpSLT(src1_value, src2_value); 1481 1482 return EmitCompareResultSelection(cmp_eq, cmp_lt); 1483 } 1484 1485 llvm::Value* GBCExpanderPass::EmitCompareResultSelection(llvm::Value* cmp_eq, 1486 llvm::Value* cmp_lt) { 1487 llvm::Constant* zero = irb_.getJInt(0); 1488 llvm::Constant* pos1 = irb_.getJInt(1); 1489 llvm::Constant* neg1 = irb_.getJInt(-1); 1490 1491 llvm::Value* result_lt = irb_.CreateSelect(cmp_lt, neg1, pos1); 1492 llvm::Value* result_eq = irb_.CreateSelect(cmp_eq, zero, result_lt); 1493 1494 return result_eq; 1495 } 1496 1497 llvm::Value* GBCExpanderPass::Expand_IntegerShift(llvm::Value* src1_value, 1498 llvm::Value* src2_value, 1499 IntegerShiftKind kind, 1500 JType op_jty) { 1501 DCHECK(op_jty == kInt || op_jty == kLong); 1502 1503 // Mask and zero-extend RHS properly 1504 if (op_jty == kInt) { 1505 src2_value = irb_.CreateAnd(src2_value, 0x1f); 1506 } else { 1507 llvm::Value* masked_src2_value = irb_.CreateAnd(src2_value, 0x3f); 1508 src2_value = irb_.CreateZExt(masked_src2_value, irb_.getJLongTy()); 1509 } 1510 1511 // Create integer shift llvm instruction 1512 switch (kind) { 1513 case kIntegerSHL: 1514 return irb_.CreateShl(src1_value, src2_value); 1515 1516 case kIntegerSHR: 1517 return irb_.CreateAShr(src1_value, src2_value); 1518 1519 case kIntegerUSHR: 1520 return irb_.CreateLShr(src1_value, src2_value); 1521 1522 default: 1523 LOG(FATAL) << "Unknown integer shift kind: " << kind; 1524 return NULL; 1525 } 1526 } 1527 1528 llvm::Value* GBCExpanderPass::SignOrZeroExtendCat1Types(llvm::Value* value, JType jty) { 1529 switch (jty) { 1530 case kBoolean: 1531 case kChar: 1532 return irb_.CreateZExt(value, irb_.getJType(kInt)); 1533 case kByte: 1534 case kShort: 1535 return irb_.CreateSExt(value, irb_.getJType(kInt)); 1536 case kVoid: 1537 case kInt: 1538 case kLong: 1539 case kFloat: 1540 case kDouble: 1541 case kObject: 1542 return value; // Nothing to do. 1543 default: 1544 LOG(FATAL) << "Unknown java type: " << jty; 1545 return NULL; 1546 } 1547 } 1548 1549 llvm::Value* GBCExpanderPass::TruncateCat1Types(llvm::Value* value, JType jty) { 1550 switch (jty) { 1551 case kBoolean: 1552 case kChar: 1553 case kByte: 1554 case kShort: 1555 return irb_.CreateTrunc(value, irb_.getJType(jty)); 1556 case kVoid: 1557 case kInt: 1558 case kLong: 1559 case kFloat: 1560 case kDouble: 1561 case kObject: 1562 return value; // Nothing to do. 1563 default: 1564 LOG(FATAL) << "Unknown java type: " << jty; 1565 return NULL; 1566 } 1567 } 1568 1569 llvm::Value* GBCExpanderPass::Expand_HLArrayGet(llvm::CallInst& call_inst, 1570 JType elem_jty) { 1571 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1572 llvm::Value* array_addr = call_inst.getArgOperand(1); 1573 llvm::Value* index_value = call_inst.getArgOperand(2); 1574 int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 1575 1576 EmitGuard_NullPointerException(dex_pc, array_addr, opt_flags); 1577 EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value, 1578 opt_flags); 1579 1580 llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty); 1581 1582 llvm::Value* array_elem_value = irb_.CreateLoad(array_elem_addr, kTBAAHeapArray, elem_jty); 1583 1584 return SignOrZeroExtendCat1Types(array_elem_value, elem_jty); 1585 } 1586 1587 1588 void GBCExpanderPass::Expand_HLArrayPut(llvm::CallInst& call_inst, 1589 JType elem_jty) { 1590 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1591 llvm::Value* new_value = call_inst.getArgOperand(1); 1592 llvm::Value* array_addr = call_inst.getArgOperand(2); 1593 llvm::Value* index_value = call_inst.getArgOperand(3); 1594 int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 1595 1596 EmitGuard_NullPointerException(dex_pc, array_addr, opt_flags); 1597 EmitGuard_ArrayIndexOutOfBoundsException(dex_pc, array_addr, index_value, 1598 opt_flags); 1599 1600 new_value = TruncateCat1Types(new_value, elem_jty); 1601 1602 llvm::Value* array_elem_addr = EmitArrayGEP(array_addr, index_value, elem_jty); 1603 1604 if (elem_jty == kObject) { // If put an object, check the type, and mark GC card table. 1605 llvm::Function* runtime_func = irb_.GetRuntime(CheckPutArrayElement); 1606 1607 irb_.CreateCall2(runtime_func, new_value, array_addr); 1608 1609 EmitGuard_ExceptionLandingPad(dex_pc); 1610 1611 EmitMarkGCCard(new_value, array_addr); 1612 } 1613 1614 irb_.CreateStore(new_value, array_elem_addr, kTBAAHeapArray, elem_jty); 1615 1616 return; 1617 } 1618 1619 llvm::Value* GBCExpanderPass::Expand_HLIGet(llvm::CallInst& call_inst, 1620 JType field_jty) { 1621 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1622 llvm::Value* object_addr = call_inst.getArgOperand(1); 1623 uint32_t field_idx = LV2UInt(call_inst.getArgOperand(2)); 1624 int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 1625 1626 EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags); 1627 1628 llvm::Value* field_value; 1629 1630 int field_offset; 1631 bool is_volatile; 1632 bool is_fast_path = driver_->ComputeInstanceFieldInfo( 1633 field_idx, dex_compilation_unit_, field_offset, is_volatile, false); 1634 1635 if (!is_fast_path) { 1636 llvm::Function* runtime_func; 1637 1638 if (field_jty == kObject) { 1639 runtime_func = irb_.GetRuntime(GetObjectInstance); 1640 } else if (field_jty == kLong || field_jty == kDouble) { 1641 runtime_func = irb_.GetRuntime(Get64Instance); 1642 } else { 1643 runtime_func = irb_.GetRuntime(Get32Instance); 1644 } 1645 1646 llvm::ConstantInt* field_idx_value = irb_.getInt32(field_idx); 1647 1648 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1649 1650 EmitUpdateDexPC(dex_pc); 1651 1652 field_value = irb_.CreateCall3(runtime_func, field_idx_value, 1653 method_object_addr, object_addr); 1654 1655 EmitGuard_ExceptionLandingPad(dex_pc); 1656 1657 if (field_jty == kFloat || field_jty == kDouble) { 1658 field_value = irb_.CreateBitCast(field_value, irb_.getJType(field_jty)); 1659 } 1660 } else { 1661 DCHECK_GE(field_offset, 0); 1662 1663 llvm::PointerType* field_type = 1664 irb_.getJType(field_jty)->getPointerTo(); 1665 1666 llvm::ConstantInt* field_offset_value = irb_.getPtrEquivInt(field_offset); 1667 1668 llvm::Value* field_addr = 1669 irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 1670 1671 field_value = irb_.CreateLoad(field_addr, kTBAAHeapInstance, field_jty); 1672 field_value = SignOrZeroExtendCat1Types(field_value, field_jty); 1673 1674 if (is_volatile) { 1675 irb_.CreateMemoryBarrier(art::kLoadLoad); 1676 } 1677 } 1678 1679 return field_value; 1680 } 1681 1682 void GBCExpanderPass::Expand_HLIPut(llvm::CallInst& call_inst, 1683 JType field_jty) { 1684 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1685 llvm::Value* new_value = call_inst.getArgOperand(1); 1686 llvm::Value* object_addr = call_inst.getArgOperand(2); 1687 uint32_t field_idx = LV2UInt(call_inst.getArgOperand(3)); 1688 int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 1689 1690 EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags); 1691 1692 int field_offset; 1693 bool is_volatile; 1694 bool is_fast_path = driver_->ComputeInstanceFieldInfo( 1695 field_idx, dex_compilation_unit_, field_offset, is_volatile, true); 1696 1697 if (!is_fast_path) { 1698 llvm::Function* runtime_func; 1699 1700 if (field_jty == kFloat) { 1701 new_value = irb_.CreateBitCast(new_value, irb_.getJType(kInt)); 1702 } else if (field_jty == kDouble) { 1703 new_value = irb_.CreateBitCast(new_value, irb_.getJType(kLong)); 1704 } 1705 1706 if (field_jty == kObject) { 1707 runtime_func = irb_.GetRuntime(SetObjectInstance); 1708 } else if (field_jty == kLong || field_jty == kDouble) { 1709 runtime_func = irb_.GetRuntime(Set64Instance); 1710 } else { 1711 runtime_func = irb_.GetRuntime(Set32Instance); 1712 } 1713 1714 llvm::Value* field_idx_value = irb_.getInt32(field_idx); 1715 1716 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1717 1718 EmitUpdateDexPC(dex_pc); 1719 1720 irb_.CreateCall4(runtime_func, field_idx_value, 1721 method_object_addr, object_addr, new_value); 1722 1723 EmitGuard_ExceptionLandingPad(dex_pc); 1724 1725 } else { 1726 DCHECK_GE(field_offset, 0); 1727 1728 if (is_volatile) { 1729 irb_.CreateMemoryBarrier(art::kStoreStore); 1730 } 1731 1732 llvm::PointerType* field_type = 1733 irb_.getJType(field_jty)->getPointerTo(); 1734 1735 llvm::Value* field_offset_value = irb_.getPtrEquivInt(field_offset); 1736 1737 llvm::Value* field_addr = 1738 irb_.CreatePtrDisp(object_addr, field_offset_value, field_type); 1739 1740 new_value = TruncateCat1Types(new_value, field_jty); 1741 irb_.CreateStore(new_value, field_addr, kTBAAHeapInstance, field_jty); 1742 1743 if (is_volatile) { 1744 irb_.CreateMemoryBarrier(art::kLoadLoad); 1745 } 1746 1747 if (field_jty == kObject) { // If put an object, mark the GC card table. 1748 EmitMarkGCCard(new_value, object_addr); 1749 } 1750 } 1751 1752 return; 1753 } 1754 1755 llvm::Value* GBCExpanderPass::EmitLoadConstantClass(uint32_t dex_pc, 1756 uint32_t type_idx) { 1757 if (!driver_->CanAccessTypeWithoutChecks(dex_compilation_unit_->GetDexMethodIndex(), 1758 *dex_compilation_unit_->GetDexFile(), type_idx)) { 1759 llvm::Value* type_idx_value = irb_.getInt32(type_idx); 1760 1761 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1762 1763 llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 1764 1765 llvm::Function* runtime_func = irb_.GetRuntime(InitializeTypeAndVerifyAccess); 1766 1767 EmitUpdateDexPC(dex_pc); 1768 1769 llvm::Value* type_object_addr = 1770 irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr); 1771 1772 EmitGuard_ExceptionLandingPad(dex_pc); 1773 1774 return type_object_addr; 1775 1776 } else { 1777 // Try to load the class (type) object from the test cache. 1778 llvm::Value* type_field_addr = 1779 EmitLoadDexCacheResolvedTypeFieldAddr(type_idx); 1780 1781 llvm::Value* type_object_addr = irb_.CreateLoad(type_field_addr, kTBAARuntimeInfo); 1782 1783 if (driver_->CanAssumeTypeIsPresentInDexCache(*dex_compilation_unit_->GetDexFile(), type_idx)) { 1784 return type_object_addr; 1785 } 1786 1787 llvm::BasicBlock* block_original = irb_.GetInsertBlock(); 1788 1789 // Test whether class (type) object is in the dex cache or not 1790 llvm::Value* equal_null = 1791 irb_.CreateICmpEQ(type_object_addr, irb_.getJNull()); 1792 1793 llvm::BasicBlock* block_cont = 1794 CreateBasicBlockWithDexPC(dex_pc, "cont"); 1795 1796 llvm::BasicBlock* block_load_class = 1797 CreateBasicBlockWithDexPC(dex_pc, "load_class"); 1798 1799 irb_.CreateCondBr(equal_null, block_load_class, block_cont, kUnlikely); 1800 1801 // Failback routine to load the class object 1802 irb_.SetInsertPoint(block_load_class); 1803 1804 llvm::Function* runtime_func = irb_.GetRuntime(InitializeType); 1805 1806 llvm::Constant* type_idx_value = irb_.getInt32(type_idx); 1807 1808 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1809 1810 llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 1811 1812 EmitUpdateDexPC(dex_pc); 1813 1814 llvm::Value* loaded_type_object_addr = 1815 irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr); 1816 1817 EmitGuard_ExceptionLandingPad(dex_pc); 1818 1819 llvm::BasicBlock* block_after_load_class = irb_.GetInsertBlock(); 1820 1821 irb_.CreateBr(block_cont); 1822 1823 // Now the class object must be loaded 1824 irb_.SetInsertPoint(block_cont); 1825 1826 llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2); 1827 1828 phi->addIncoming(type_object_addr, block_original); 1829 phi->addIncoming(loaded_type_object_addr, block_after_load_class); 1830 1831 return phi; 1832 } 1833 } 1834 1835 llvm::Value* GBCExpanderPass::EmitLoadStaticStorage(uint32_t dex_pc, 1836 uint32_t type_idx) { 1837 llvm::BasicBlock* block_load_static = 1838 CreateBasicBlockWithDexPC(dex_pc, "load_static"); 1839 1840 llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont"); 1841 1842 // Load static storage from dex cache 1843 llvm::Value* storage_field_addr = 1844 EmitLoadDexCacheStaticStorageFieldAddr(type_idx); 1845 1846 llvm::Value* storage_object_addr = irb_.CreateLoad(storage_field_addr, kTBAARuntimeInfo); 1847 1848 llvm::BasicBlock* block_original = irb_.GetInsertBlock(); 1849 1850 // Test: Is the static storage of this class initialized? 1851 llvm::Value* equal_null = 1852 irb_.CreateICmpEQ(storage_object_addr, irb_.getJNull()); 1853 1854 irb_.CreateCondBr(equal_null, block_load_static, block_cont, kUnlikely); 1855 1856 // Failback routine to load the class object 1857 irb_.SetInsertPoint(block_load_static); 1858 1859 llvm::Function* runtime_func = irb_.GetRuntime(InitializeStaticStorage); 1860 1861 llvm::Constant* type_idx_value = irb_.getInt32(type_idx); 1862 1863 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1864 1865 llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 1866 1867 EmitUpdateDexPC(dex_pc); 1868 1869 llvm::Value* loaded_storage_object_addr = 1870 irb_.CreateCall3(runtime_func, type_idx_value, method_object_addr, thread_object_addr); 1871 1872 EmitGuard_ExceptionLandingPad(dex_pc); 1873 1874 llvm::BasicBlock* block_after_load_static = irb_.GetInsertBlock(); 1875 1876 irb_.CreateBr(block_cont); 1877 1878 // Now the class object must be loaded 1879 irb_.SetInsertPoint(block_cont); 1880 1881 llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2); 1882 1883 phi->addIncoming(storage_object_addr, block_original); 1884 phi->addIncoming(loaded_storage_object_addr, block_after_load_static); 1885 1886 return phi; 1887 } 1888 1889 llvm::Value* GBCExpanderPass::Expand_HLSget(llvm::CallInst& call_inst, 1890 JType field_jty) { 1891 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1892 uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0)); 1893 1894 int field_offset; 1895 int ssb_index; 1896 bool is_referrers_class; 1897 bool is_volatile; 1898 1899 bool is_fast_path = driver_->ComputeStaticFieldInfo( 1900 field_idx, dex_compilation_unit_, field_offset, ssb_index, 1901 is_referrers_class, is_volatile, false); 1902 1903 llvm::Value* static_field_value; 1904 1905 if (!is_fast_path) { 1906 llvm::Function* runtime_func; 1907 1908 if (field_jty == kObject) { 1909 runtime_func = irb_.GetRuntime(GetObjectStatic); 1910 } else if (field_jty == kLong || field_jty == kDouble) { 1911 runtime_func = irb_.GetRuntime(Get64Static); 1912 } else { 1913 runtime_func = irb_.GetRuntime(Get32Static); 1914 } 1915 1916 llvm::Constant* field_idx_value = irb_.getInt32(field_idx); 1917 1918 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1919 1920 EmitUpdateDexPC(dex_pc); 1921 1922 static_field_value = 1923 irb_.CreateCall2(runtime_func, field_idx_value, method_object_addr); 1924 1925 EmitGuard_ExceptionLandingPad(dex_pc); 1926 1927 if (field_jty == kFloat || field_jty == kDouble) { 1928 static_field_value = irb_.CreateBitCast(static_field_value, irb_.getJType(field_jty)); 1929 } 1930 } else { 1931 DCHECK_GE(field_offset, 0); 1932 1933 llvm::Value* static_storage_addr = NULL; 1934 1935 if (is_referrers_class) { 1936 // Fast path, static storage base is this method's class 1937 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 1938 1939 static_storage_addr = 1940 irb_.LoadFromObjectOffset(method_object_addr, 1941 art::mirror::ArtMethod::DeclaringClassOffset().Int32Value(), 1942 irb_.getJObjectTy(), 1943 kTBAAConstJObject); 1944 } else { 1945 // Medium path, static storage base in a different class which 1946 // requires checks that the other class is initialized 1947 DCHECK_GE(ssb_index, 0); 1948 static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index); 1949 } 1950 1951 llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 1952 1953 llvm::Value* static_field_addr = 1954 irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 1955 irb_.getJType(field_jty)->getPointerTo()); 1956 1957 static_field_value = irb_.CreateLoad(static_field_addr, kTBAAHeapStatic, field_jty); 1958 static_field_value = SignOrZeroExtendCat1Types(static_field_value, field_jty); 1959 1960 if (is_volatile) { 1961 irb_.CreateMemoryBarrier(art::kLoadLoad); 1962 } 1963 } 1964 1965 return static_field_value; 1966 } 1967 1968 void GBCExpanderPass::Expand_HLSput(llvm::CallInst& call_inst, 1969 JType field_jty) { 1970 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 1971 uint32_t field_idx = LV2UInt(call_inst.getArgOperand(0)); 1972 llvm::Value* new_value = call_inst.getArgOperand(1); 1973 1974 if (field_jty == kFloat || field_jty == kDouble) { 1975 new_value = irb_.CreateBitCast(new_value, irb_.getJType(field_jty)); 1976 } 1977 1978 int field_offset; 1979 int ssb_index; 1980 bool is_referrers_class; 1981 bool is_volatile; 1982 1983 bool is_fast_path = driver_->ComputeStaticFieldInfo( 1984 field_idx, dex_compilation_unit_, field_offset, ssb_index, 1985 is_referrers_class, is_volatile, true); 1986 1987 if (!is_fast_path) { 1988 llvm::Function* runtime_func; 1989 1990 if (field_jty == kObject) { 1991 runtime_func = irb_.GetRuntime(SetObjectStatic); 1992 } else if (field_jty == kLong || field_jty == kDouble) { 1993 runtime_func = irb_.GetRuntime(Set64Static); 1994 } else { 1995 runtime_func = irb_.GetRuntime(Set32Static); 1996 } 1997 1998 if (field_jty == kFloat) { 1999 new_value = irb_.CreateBitCast(new_value, irb_.getJType(kInt)); 2000 } else if (field_jty == kDouble) { 2001 new_value = irb_.CreateBitCast(new_value, irb_.getJType(kLong)); 2002 } 2003 2004 llvm::Constant* field_idx_value = irb_.getInt32(field_idx); 2005 2006 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2007 2008 EmitUpdateDexPC(dex_pc); 2009 2010 irb_.CreateCall3(runtime_func, field_idx_value, 2011 method_object_addr, new_value); 2012 2013 EmitGuard_ExceptionLandingPad(dex_pc); 2014 2015 } else { 2016 DCHECK_GE(field_offset, 0); 2017 2018 llvm::Value* static_storage_addr = NULL; 2019 2020 if (is_referrers_class) { 2021 // Fast path, static storage base is this method's class 2022 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2023 2024 static_storage_addr = 2025 irb_.LoadFromObjectOffset(method_object_addr, 2026 art::mirror::ArtMethod::DeclaringClassOffset().Int32Value(), 2027 irb_.getJObjectTy(), 2028 kTBAAConstJObject); 2029 } else { 2030 // Medium path, static storage base in a different class which 2031 // requires checks that the other class is initialized 2032 DCHECK_GE(ssb_index, 0); 2033 static_storage_addr = EmitLoadStaticStorage(dex_pc, ssb_index); 2034 } 2035 2036 if (is_volatile) { 2037 irb_.CreateMemoryBarrier(art::kStoreStore); 2038 } 2039 2040 llvm::Value* static_field_offset_value = irb_.getPtrEquivInt(field_offset); 2041 2042 llvm::Value* static_field_addr = 2043 irb_.CreatePtrDisp(static_storage_addr, static_field_offset_value, 2044 irb_.getJType(field_jty)->getPointerTo()); 2045 2046 new_value = TruncateCat1Types(new_value, field_jty); 2047 irb_.CreateStore(new_value, static_field_addr, kTBAAHeapStatic, field_jty); 2048 2049 if (is_volatile) { 2050 irb_.CreateMemoryBarrier(art::kStoreLoad); 2051 } 2052 2053 if (field_jty == kObject) { // If put an object, mark the GC card table. 2054 EmitMarkGCCard(new_value, static_storage_addr); 2055 } 2056 } 2057 2058 return; 2059 } 2060 2061 llvm::Value* GBCExpanderPass::Expand_ConstString(llvm::CallInst& call_inst) { 2062 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2063 uint32_t string_idx = LV2UInt(call_inst.getArgOperand(0)); 2064 2065 llvm::Value* string_field_addr = EmitLoadDexCacheStringFieldAddr(string_idx); 2066 2067 llvm::Value* string_addr = irb_.CreateLoad(string_field_addr, kTBAARuntimeInfo); 2068 2069 if (!driver_->CanAssumeStringIsPresentInDexCache(*dex_compilation_unit_->GetDexFile(), 2070 string_idx)) { 2071 llvm::BasicBlock* block_str_exist = 2072 CreateBasicBlockWithDexPC(dex_pc, "str_exist"); 2073 2074 llvm::BasicBlock* block_str_resolve = 2075 CreateBasicBlockWithDexPC(dex_pc, "str_resolve"); 2076 2077 llvm::BasicBlock* block_cont = 2078 CreateBasicBlockWithDexPC(dex_pc, "str_cont"); 2079 2080 // Test: Is the string resolved and in the dex cache? 2081 llvm::Value* equal_null = irb_.CreateICmpEQ(string_addr, irb_.getJNull()); 2082 2083 irb_.CreateCondBr(equal_null, block_str_resolve, block_str_exist, kUnlikely); 2084 2085 // String is resolved, go to next basic block. 2086 irb_.SetInsertPoint(block_str_exist); 2087 irb_.CreateBr(block_cont); 2088 2089 // String is not resolved yet, resolve it now. 2090 irb_.SetInsertPoint(block_str_resolve); 2091 2092 llvm::Function* runtime_func = irb_.GetRuntime(ResolveString); 2093 2094 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2095 2096 llvm::Value* string_idx_value = irb_.getInt32(string_idx); 2097 2098 EmitUpdateDexPC(dex_pc); 2099 2100 llvm::Value* result = irb_.CreateCall2(runtime_func, method_object_addr, 2101 string_idx_value); 2102 2103 EmitGuard_ExceptionLandingPad(dex_pc); 2104 2105 irb_.CreateBr(block_cont); 2106 2107 2108 llvm::BasicBlock* block_pre_cont = irb_.GetInsertBlock(); 2109 2110 irb_.SetInsertPoint(block_cont); 2111 2112 llvm::PHINode* phi = irb_.CreatePHI(irb_.getJObjectTy(), 2); 2113 2114 phi->addIncoming(string_addr, block_str_exist); 2115 phi->addIncoming(result, block_pre_cont); 2116 2117 string_addr = phi; 2118 } 2119 2120 return string_addr; 2121 } 2122 2123 llvm::Value* GBCExpanderPass::Expand_ConstClass(llvm::CallInst& call_inst) { 2124 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2125 uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2126 2127 llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx); 2128 2129 return type_object_addr; 2130 } 2131 2132 void GBCExpanderPass::Expand_MonitorEnter(llvm::CallInst& call_inst) { 2133 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2134 llvm::Value* object_addr = call_inst.getArgOperand(1); 2135 int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 2136 2137 EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags); 2138 2139 EmitUpdateDexPC(dex_pc); 2140 2141 irb_.Runtime().EmitLockObject(object_addr); 2142 2143 return; 2144 } 2145 2146 void GBCExpanderPass::Expand_MonitorExit(llvm::CallInst& call_inst) { 2147 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2148 llvm::Value* object_addr = call_inst.getArgOperand(1); 2149 int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 2150 2151 EmitGuard_NullPointerException(dex_pc, object_addr, opt_flags); 2152 2153 EmitUpdateDexPC(dex_pc); 2154 2155 irb_.Runtime().EmitUnlockObject(object_addr); 2156 2157 EmitGuard_ExceptionLandingPad(dex_pc); 2158 2159 return; 2160 } 2161 2162 void GBCExpanderPass::Expand_HLCheckCast(llvm::CallInst& call_inst) { 2163 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2164 uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2165 llvm::Value* object_addr = call_inst.getArgOperand(1); 2166 2167 llvm::BasicBlock* block_test_class = 2168 CreateBasicBlockWithDexPC(dex_pc, "test_class"); 2169 2170 llvm::BasicBlock* block_test_sub_class = 2171 CreateBasicBlockWithDexPC(dex_pc, "test_sub_class"); 2172 2173 llvm::BasicBlock* block_cont = 2174 CreateBasicBlockWithDexPC(dex_pc, "checkcast_cont"); 2175 2176 // Test: Is the reference equal to null? Act as no-op when it is null. 2177 llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull()); 2178 2179 irb_.CreateCondBr(equal_null, block_cont, block_test_class, kUnlikely); 2180 2181 // Test: Is the object instantiated from the given class? 2182 irb_.SetInsertPoint(block_test_class); 2183 llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx); 2184 DCHECK_EQ(art::mirror::Object::ClassOffset().Int32Value(), 0); 2185 2186 llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy(); 2187 2188 llvm::Value* object_type_field_addr = 2189 irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo()); 2190 2191 llvm::Value* object_type_object_addr = 2192 irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject); 2193 2194 llvm::Value* equal_class = 2195 irb_.CreateICmpEQ(type_object_addr, object_type_object_addr); 2196 2197 irb_.CreateCondBr(equal_class, block_cont, block_test_sub_class, kLikely); 2198 2199 // Test: Is the object instantiated from the subclass of the given class? 2200 irb_.SetInsertPoint(block_test_sub_class); 2201 2202 EmitUpdateDexPC(dex_pc); 2203 2204 irb_.CreateCall2(irb_.GetRuntime(CheckCast), 2205 type_object_addr, object_type_object_addr); 2206 2207 EmitGuard_ExceptionLandingPad(dex_pc); 2208 2209 irb_.CreateBr(block_cont); 2210 2211 irb_.SetInsertPoint(block_cont); 2212 2213 return; 2214 } 2215 2216 llvm::Value* GBCExpanderPass::Expand_InstanceOf(llvm::CallInst& call_inst) { 2217 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2218 uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2219 llvm::Value* object_addr = call_inst.getArgOperand(1); 2220 2221 llvm::BasicBlock* block_nullp = 2222 CreateBasicBlockWithDexPC(dex_pc, "nullp"); 2223 2224 llvm::BasicBlock* block_test_class = 2225 CreateBasicBlockWithDexPC(dex_pc, "test_class"); 2226 2227 llvm::BasicBlock* block_class_equals = 2228 CreateBasicBlockWithDexPC(dex_pc, "class_eq"); 2229 2230 llvm::BasicBlock* block_test_sub_class = 2231 CreateBasicBlockWithDexPC(dex_pc, "test_sub_class"); 2232 2233 llvm::BasicBlock* block_cont = 2234 CreateBasicBlockWithDexPC(dex_pc, "instance_of_cont"); 2235 2236 // Overview of the following code : 2237 // We check for null, if so, then false, otherwise check for class == . If so 2238 // then true, otherwise do callout slowpath. 2239 // 2240 // Test: Is the reference equal to null? Set 0 when it is null. 2241 llvm::Value* equal_null = irb_.CreateICmpEQ(object_addr, irb_.getJNull()); 2242 2243 irb_.CreateCondBr(equal_null, block_nullp, block_test_class, kUnlikely); 2244 2245 irb_.SetInsertPoint(block_nullp); 2246 irb_.CreateBr(block_cont); 2247 2248 // Test: Is the object instantiated from the given class? 2249 irb_.SetInsertPoint(block_test_class); 2250 llvm::Value* type_object_addr = EmitLoadConstantClass(dex_pc, type_idx); 2251 DCHECK_EQ(art::mirror::Object::ClassOffset().Int32Value(), 0); 2252 2253 llvm::PointerType* jobject_ptr_ty = irb_.getJObjectTy(); 2254 2255 llvm::Value* object_type_field_addr = 2256 irb_.CreateBitCast(object_addr, jobject_ptr_ty->getPointerTo()); 2257 2258 llvm::Value* object_type_object_addr = 2259 irb_.CreateLoad(object_type_field_addr, kTBAAConstJObject); 2260 2261 llvm::Value* equal_class = 2262 irb_.CreateICmpEQ(type_object_addr, object_type_object_addr); 2263 2264 irb_.CreateCondBr(equal_class, block_class_equals, block_test_sub_class, kLikely); 2265 2266 irb_.SetInsertPoint(block_class_equals); 2267 irb_.CreateBr(block_cont); 2268 2269 // Test: Is the object instantiated from the subclass of the given class? 2270 irb_.SetInsertPoint(block_test_sub_class); 2271 llvm::Value* result = 2272 irb_.CreateCall2(irb_.GetRuntime(IsAssignable), 2273 type_object_addr, object_type_object_addr); 2274 irb_.CreateBr(block_cont); 2275 2276 irb_.SetInsertPoint(block_cont); 2277 2278 llvm::PHINode* phi = irb_.CreatePHI(irb_.getJIntTy(), 3); 2279 2280 phi->addIncoming(irb_.getJInt(0), block_nullp); 2281 phi->addIncoming(irb_.getJInt(1), block_class_equals); 2282 phi->addIncoming(result, block_test_sub_class); 2283 2284 return phi; 2285 } 2286 2287 llvm::Value* GBCExpanderPass::Expand_NewInstance(llvm::CallInst& call_inst) { 2288 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2289 uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2290 2291 llvm::Function* runtime_func; 2292 if (driver_->CanAccessInstantiableTypeWithoutChecks(dex_compilation_unit_->GetDexMethodIndex(), 2293 *dex_compilation_unit_->GetDexFile(), 2294 type_idx)) { 2295 runtime_func = irb_.GetRuntime(AllocObject); 2296 } else { 2297 runtime_func = irb_.GetRuntime(AllocObjectWithAccessCheck); 2298 } 2299 2300 llvm::Constant* type_index_value = irb_.getInt32(type_idx); 2301 2302 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2303 2304 llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 2305 2306 EmitUpdateDexPC(dex_pc); 2307 2308 llvm::Value* object_addr = 2309 irb_.CreateCall3(runtime_func, type_index_value, method_object_addr, thread_object_addr); 2310 2311 EmitGuard_ExceptionLandingPad(dex_pc); 2312 2313 return object_addr; 2314 } 2315 2316 llvm::Value* GBCExpanderPass::Expand_HLInvoke(llvm::CallInst& call_inst) { 2317 art::InvokeType invoke_type = static_cast<art::InvokeType>(LV2UInt(call_inst.getArgOperand(0))); 2318 bool is_static = (invoke_type == art::kStatic); 2319 2320 if (!is_static) { 2321 // Test: Is *this* parameter equal to null? 2322 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2323 llvm::Value* this_addr = call_inst.getArgOperand(3); 2324 int opt_flags = LV2UInt(call_inst.getArgOperand(2)); 2325 2326 EmitGuard_NullPointerException(dex_pc, this_addr, opt_flags); 2327 } 2328 2329 llvm::Value* result = NULL; 2330 if (EmitIntrinsic(call_inst, &result)) { 2331 return result; 2332 } 2333 2334 return EmitInvoke(call_inst); 2335 } 2336 2337 llvm::Value* GBCExpanderPass::Expand_OptArrayLength(llvm::CallInst& call_inst) { 2338 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2339 // Get the array object address 2340 llvm::Value* array_addr = call_inst.getArgOperand(1); 2341 int opt_flags = LV2UInt(call_inst.getArgOperand(0)); 2342 2343 EmitGuard_NullPointerException(dex_pc, array_addr, opt_flags); 2344 2345 // Get the array length and store it to the register 2346 return EmitLoadArrayLength(array_addr); 2347 } 2348 2349 llvm::Value* GBCExpanderPass::Expand_NewArray(llvm::CallInst& call_inst) { 2350 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2351 uint32_t type_idx = LV2UInt(call_inst.getArgOperand(0)); 2352 llvm::Value* length = call_inst.getArgOperand(1); 2353 2354 return EmitAllocNewArray(dex_pc, length, type_idx, false); 2355 } 2356 2357 llvm::Value* GBCExpanderPass::Expand_HLFilledNewArray(llvm::CallInst& call_inst) { 2358 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2359 uint32_t type_idx = LV2UInt(call_inst.getArgOperand(1)); 2360 uint32_t length = call_inst.getNumArgOperands() - 3; 2361 2362 llvm::Value* object_addr = 2363 EmitAllocNewArray(dex_pc, irb_.getInt32(length), type_idx, true); 2364 2365 if (length > 0) { 2366 // Check for the element type 2367 uint32_t type_desc_len = 0; 2368 const char* type_desc = 2369 dex_compilation_unit_->GetDexFile()->StringByTypeIdx(type_idx, &type_desc_len); 2370 2371 DCHECK_GE(type_desc_len, 2u); // should be guaranteed by verifier 2372 DCHECK_EQ(type_desc[0], '['); // should be guaranteed by verifier 2373 bool is_elem_int_ty = (type_desc[1] == 'I'); 2374 2375 uint32_t alignment; 2376 llvm::Constant* elem_size; 2377 llvm::PointerType* field_type; 2378 2379 // NOTE: Currently filled-new-array only supports 'L', '[', and 'I' 2380 // as the element, thus we are only checking 2 cases: primitive int and 2381 // non-primitive type. 2382 if (is_elem_int_ty) { 2383 alignment = sizeof(int32_t); 2384 elem_size = irb_.getPtrEquivInt(sizeof(int32_t)); 2385 field_type = irb_.getJIntTy()->getPointerTo(); 2386 } else { 2387 alignment = irb_.getSizeOfPtrEquivInt(); 2388 elem_size = irb_.getSizeOfPtrEquivIntValue(); 2389 field_type = irb_.getJObjectTy()->getPointerTo(); 2390 } 2391 2392 llvm::Value* data_field_offset = 2393 irb_.getPtrEquivInt(art::mirror::Array::DataOffset(alignment).Int32Value()); 2394 2395 llvm::Value* data_field_addr = 2396 irb_.CreatePtrDisp(object_addr, data_field_offset, field_type); 2397 2398 // TODO: Tune this code. Currently we are generating one instruction for 2399 // one element which may be very space consuming. Maybe changing to use 2400 // memcpy may help; however, since we can't guarantee that the alloca of 2401 // dalvik register are continuous, we can't perform such optimization yet. 2402 for (uint32_t i = 0; i < length; ++i) { 2403 llvm::Value* reg_value = call_inst.getArgOperand(i+3); 2404 2405 irb_.CreateStore(reg_value, data_field_addr, kTBAAHeapArray); 2406 2407 data_field_addr = 2408 irb_.CreatePtrDisp(data_field_addr, elem_size, field_type); 2409 } 2410 } 2411 2412 return object_addr; 2413 } 2414 2415 void GBCExpanderPass::Expand_HLFillArrayData(llvm::CallInst& call_inst) { 2416 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2417 int32_t payload_offset = static_cast<int32_t>(dex_pc) + 2418 LV2SInt(call_inst.getArgOperand(0)); 2419 llvm::Value* array_addr = call_inst.getArgOperand(1); 2420 2421 const art::Instruction::ArrayDataPayload* payload = 2422 reinterpret_cast<const art::Instruction::ArrayDataPayload*>( 2423 dex_compilation_unit_->GetCodeItem()->insns_ + payload_offset); 2424 2425 if (payload->element_count == 0) { 2426 // When the number of the elements in the payload is zero, we don't have 2427 // to copy any numbers. However, we should check whether the array object 2428 // address is equal to null or not. 2429 EmitGuard_NullPointerException(dex_pc, array_addr, 0); 2430 } else { 2431 // To save the code size, we are going to call the runtime function to 2432 // copy the content from DexFile. 2433 2434 // NOTE: We will check for the NullPointerException in the runtime. 2435 2436 llvm::Function* runtime_func = irb_.GetRuntime(FillArrayData); 2437 2438 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2439 2440 EmitUpdateDexPC(dex_pc); 2441 2442 irb_.CreateCall4(runtime_func, 2443 method_object_addr, irb_.getInt32(dex_pc), 2444 array_addr, irb_.getInt32(payload_offset)); 2445 2446 EmitGuard_ExceptionLandingPad(dex_pc); 2447 } 2448 2449 return; 2450 } 2451 2452 llvm::Value* GBCExpanderPass::EmitAllocNewArray(uint32_t dex_pc, 2453 llvm::Value* array_length_value, 2454 uint32_t type_idx, 2455 bool is_filled_new_array) { 2456 llvm::Function* runtime_func; 2457 2458 bool skip_access_check = 2459 driver_->CanAccessTypeWithoutChecks(dex_compilation_unit_->GetDexMethodIndex(), 2460 *dex_compilation_unit_->GetDexFile(), type_idx); 2461 2462 2463 if (is_filled_new_array) { 2464 runtime_func = skip_access_check ? 2465 irb_.GetRuntime(CheckAndAllocArray) : 2466 irb_.GetRuntime(CheckAndAllocArrayWithAccessCheck); 2467 } else { 2468 runtime_func = skip_access_check ? 2469 irb_.GetRuntime(AllocArray) : 2470 irb_.GetRuntime(AllocArrayWithAccessCheck); 2471 } 2472 2473 llvm::Constant* type_index_value = irb_.getInt32(type_idx); 2474 2475 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2476 2477 llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 2478 2479 EmitUpdateDexPC(dex_pc); 2480 2481 llvm::Value* object_addr = 2482 irb_.CreateCall4(runtime_func, type_index_value, method_object_addr, 2483 array_length_value, thread_object_addr); 2484 2485 EmitGuard_ExceptionLandingPad(dex_pc); 2486 2487 return object_addr; 2488 } 2489 2490 llvm::Value* GBCExpanderPass:: 2491 EmitCallRuntimeForCalleeMethodObjectAddr(uint32_t callee_method_idx, 2492 art::InvokeType invoke_type, 2493 llvm::Value* this_addr, 2494 uint32_t dex_pc, 2495 bool is_fast_path) { 2496 llvm::Function* runtime_func = NULL; 2497 2498 switch (invoke_type) { 2499 case art::kStatic: 2500 runtime_func = irb_.GetRuntime(FindStaticMethodWithAccessCheck); 2501 break; 2502 2503 case art::kDirect: 2504 runtime_func = irb_.GetRuntime(FindDirectMethodWithAccessCheck); 2505 break; 2506 2507 case art::kVirtual: 2508 runtime_func = irb_.GetRuntime(FindVirtualMethodWithAccessCheck); 2509 break; 2510 2511 case art::kSuper: 2512 runtime_func = irb_.GetRuntime(FindSuperMethodWithAccessCheck); 2513 break; 2514 2515 case art::kInterface: 2516 if (is_fast_path) { 2517 runtime_func = irb_.GetRuntime(FindInterfaceMethod); 2518 } else { 2519 runtime_func = irb_.GetRuntime(FindInterfaceMethodWithAccessCheck); 2520 } 2521 break; 2522 } 2523 2524 llvm::Value* callee_method_idx_value = irb_.getInt32(callee_method_idx); 2525 2526 if (this_addr == NULL) { 2527 DCHECK_EQ(invoke_type, art::kStatic); 2528 this_addr = irb_.getJNull(); 2529 } 2530 2531 llvm::Value* caller_method_object_addr = EmitLoadMethodObjectAddr(); 2532 2533 llvm::Value* thread_object_addr = irb_.Runtime().EmitGetCurrentThread(); 2534 2535 EmitUpdateDexPC(dex_pc); 2536 2537 llvm::Value* callee_method_object_addr = 2538 irb_.CreateCall4(runtime_func, 2539 callee_method_idx_value, 2540 this_addr, 2541 caller_method_object_addr, 2542 thread_object_addr); 2543 2544 EmitGuard_ExceptionLandingPad(dex_pc); 2545 2546 return callee_method_object_addr; 2547 } 2548 2549 void GBCExpanderPass::EmitMarkGCCard(llvm::Value* value, llvm::Value* target_addr) { 2550 // Using runtime support, let the target can override by InlineAssembly. 2551 irb_.Runtime().EmitMarkGCCard(value, target_addr); 2552 } 2553 2554 void GBCExpanderPass::EmitUpdateDexPC(uint32_t dex_pc) { 2555 if (shadow_frame_ == NULL) { 2556 return; 2557 } 2558 irb_.StoreToObjectOffset(shadow_frame_, 2559 art::ShadowFrame::DexPCOffset(), 2560 irb_.getInt32(dex_pc), 2561 kTBAAShadowFrame); 2562 } 2563 2564 void GBCExpanderPass::EmitGuard_DivZeroException(uint32_t dex_pc, 2565 llvm::Value* denominator, 2566 JType op_jty) { 2567 DCHECK(op_jty == kInt || op_jty == kLong) << op_jty; 2568 2569 llvm::Constant* zero = irb_.getJZero(op_jty); 2570 2571 llvm::Value* equal_zero = irb_.CreateICmpEQ(denominator, zero); 2572 2573 llvm::BasicBlock* block_exception = CreateBasicBlockWithDexPC(dex_pc, "div0"); 2574 2575 llvm::BasicBlock* block_continue = CreateBasicBlockWithDexPC(dex_pc, "cont"); 2576 2577 irb_.CreateCondBr(equal_zero, block_exception, block_continue, kUnlikely); 2578 2579 irb_.SetInsertPoint(block_exception); 2580 EmitUpdateDexPC(dex_pc); 2581 irb_.CreateCall(irb_.GetRuntime(ThrowDivZeroException)); 2582 EmitBranchExceptionLandingPad(dex_pc); 2583 2584 irb_.SetInsertPoint(block_continue); 2585 } 2586 2587 void GBCExpanderPass::EmitGuard_NullPointerException(uint32_t dex_pc, 2588 llvm::Value* object, 2589 int opt_flags) { 2590 bool ignore_null_check = ((opt_flags & MIR_IGNORE_NULL_CHECK) != 0); 2591 if (ignore_null_check) { 2592 llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc); 2593 if (lpad) { 2594 // There is at least one catch: create a "fake" conditional branch to 2595 // keep the exception edge to the catch block. 2596 landing_pad_phi_mapping_[lpad].push_back( 2597 std::make_pair(current_bb_->getUniquePredecessor(), 2598 irb_.GetInsertBlock())); 2599 2600 llvm::BasicBlock* block_continue = 2601 CreateBasicBlockWithDexPC(dex_pc, "cont"); 2602 2603 irb_.CreateCondBr(irb_.getFalse(), lpad, block_continue, kUnlikely); 2604 2605 irb_.SetInsertPoint(block_continue); 2606 } 2607 } else { 2608 llvm::Value* equal_null = irb_.CreateICmpEQ(object, irb_.getJNull()); 2609 2610 llvm::BasicBlock* block_exception = 2611 CreateBasicBlockWithDexPC(dex_pc, "nullp"); 2612 2613 llvm::BasicBlock* block_continue = 2614 CreateBasicBlockWithDexPC(dex_pc, "cont"); 2615 2616 irb_.CreateCondBr(equal_null, block_exception, block_continue, kUnlikely); 2617 2618 irb_.SetInsertPoint(block_exception); 2619 EmitUpdateDexPC(dex_pc); 2620 irb_.CreateCall(irb_.GetRuntime(ThrowNullPointerException), 2621 irb_.getInt32(dex_pc)); 2622 EmitBranchExceptionLandingPad(dex_pc); 2623 2624 irb_.SetInsertPoint(block_continue); 2625 } 2626 } 2627 2628 void 2629 GBCExpanderPass::EmitGuard_ArrayIndexOutOfBoundsException(uint32_t dex_pc, 2630 llvm::Value* array, 2631 llvm::Value* index, 2632 int opt_flags) { 2633 bool ignore_range_check = ((opt_flags & MIR_IGNORE_RANGE_CHECK) != 0); 2634 if (ignore_range_check) { 2635 llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc); 2636 if (lpad) { 2637 // There is at least one catch: create a "fake" conditional branch to 2638 // keep the exception edge to the catch block. 2639 landing_pad_phi_mapping_[lpad].push_back( 2640 std::make_pair(current_bb_->getUniquePredecessor(), 2641 irb_.GetInsertBlock())); 2642 2643 llvm::BasicBlock* block_continue = 2644 CreateBasicBlockWithDexPC(dex_pc, "cont"); 2645 2646 irb_.CreateCondBr(irb_.getFalse(), lpad, block_continue, kUnlikely); 2647 2648 irb_.SetInsertPoint(block_continue); 2649 } 2650 } else { 2651 llvm::Value* array_len = EmitLoadArrayLength(array); 2652 2653 llvm::Value* cmp = irb_.CreateICmpUGE(index, array_len); 2654 2655 llvm::BasicBlock* block_exception = 2656 CreateBasicBlockWithDexPC(dex_pc, "overflow"); 2657 2658 llvm::BasicBlock* block_continue = 2659 CreateBasicBlockWithDexPC(dex_pc, "cont"); 2660 2661 irb_.CreateCondBr(cmp, block_exception, block_continue, kUnlikely); 2662 2663 irb_.SetInsertPoint(block_exception); 2664 2665 EmitUpdateDexPC(dex_pc); 2666 irb_.CreateCall2(irb_.GetRuntime(ThrowIndexOutOfBounds), index, array_len); 2667 EmitBranchExceptionLandingPad(dex_pc); 2668 2669 irb_.SetInsertPoint(block_continue); 2670 } 2671 } 2672 2673 llvm::FunctionType* GBCExpanderPass::GetFunctionType(llvm::Type* ret_type, uint32_t method_idx, 2674 bool is_static) { 2675 // Get method signature 2676 art::DexFile::MethodId const& method_id = 2677 dex_compilation_unit_->GetDexFile()->GetMethodId(method_idx); 2678 2679 uint32_t shorty_size; 2680 const char* shorty = dex_compilation_unit_->GetDexFile()->GetMethodShorty(method_id, &shorty_size); 2681 CHECK_GE(shorty_size, 1u); 2682 2683 // Get argument type 2684 std::vector<llvm::Type*> args_type; 2685 2686 args_type.push_back(irb_.getJObjectTy()); // method object pointer 2687 2688 if (!is_static) { 2689 args_type.push_back(irb_.getJType('L')); // "this" object pointer 2690 } 2691 2692 for (uint32_t i = 1; i < shorty_size; ++i) { 2693 char shorty_type = art::RemapShorty(shorty[i]); 2694 args_type.push_back(irb_.getJType(shorty_type)); 2695 } 2696 2697 return llvm::FunctionType::get(ret_type, args_type, false); 2698 } 2699 2700 2701 llvm::BasicBlock* GBCExpanderPass:: 2702 CreateBasicBlockWithDexPC(uint32_t dex_pc, const char* postfix) { 2703 std::string name; 2704 2705 #if !defined(NDEBUG) 2706 art::StringAppendF(&name, "B%04x.%s", dex_pc, postfix); 2707 #endif 2708 2709 return llvm::BasicBlock::Create(context_, name, func_); 2710 } 2711 2712 llvm::BasicBlock* GBCExpanderPass::GetBasicBlock(uint32_t dex_pc) { 2713 DCHECK(dex_pc < dex_compilation_unit_->GetCodeItem()->insns_size_in_code_units_); 2714 CHECK(basic_blocks_[dex_pc] != NULL); 2715 return basic_blocks_[dex_pc]; 2716 } 2717 2718 int32_t GBCExpanderPass::GetTryItemOffset(uint32_t dex_pc) { 2719 int32_t min = 0; 2720 int32_t max = dex_compilation_unit_->GetCodeItem()->tries_size_ - 1; 2721 2722 while (min <= max) { 2723 int32_t mid = min + (max - min) / 2; 2724 2725 const art::DexFile::TryItem* ti = 2726 art::DexFile::GetTryItems(*dex_compilation_unit_->GetCodeItem(), mid); 2727 uint32_t start = ti->start_addr_; 2728 uint32_t end = start + ti->insn_count_; 2729 2730 if (dex_pc < start) { 2731 max = mid - 1; 2732 } else if (dex_pc >= end) { 2733 min = mid + 1; 2734 } else { 2735 return mid; // found 2736 } 2737 } 2738 2739 return -1; // not found 2740 } 2741 2742 llvm::BasicBlock* GBCExpanderPass::GetLandingPadBasicBlock(uint32_t dex_pc) { 2743 // Find the try item for this address in this method 2744 int32_t ti_offset = GetTryItemOffset(dex_pc); 2745 2746 if (ti_offset == -1) { 2747 return NULL; // No landing pad is available for this address. 2748 } 2749 2750 // Check for the existing landing pad basic block 2751 DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset)); 2752 llvm::BasicBlock* block_lpad = basic_block_landing_pads_[ti_offset]; 2753 2754 if (block_lpad) { 2755 // We have generated landing pad for this try item already. Return the 2756 // same basic block. 2757 return block_lpad; 2758 } 2759 2760 // Get try item from code item 2761 const art::DexFile::TryItem* ti = art::DexFile::GetTryItems(*dex_compilation_unit_->GetCodeItem(), 2762 ti_offset); 2763 2764 std::string lpadname; 2765 2766 #if !defined(NDEBUG) 2767 art::StringAppendF(&lpadname, "lpad%d_%04x_to_%04x", ti_offset, ti->start_addr_, ti->handler_off_); 2768 #endif 2769 2770 // Create landing pad basic block 2771 block_lpad = llvm::BasicBlock::Create(context_, lpadname, func_); 2772 2773 // Change IRBuilder insert point 2774 llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP(); 2775 irb_.SetInsertPoint(block_lpad); 2776 2777 // Find catch block with matching type 2778 llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); 2779 2780 llvm::Value* ti_offset_value = irb_.getInt32(ti_offset); 2781 2782 llvm::Value* catch_handler_index_value = 2783 irb_.CreateCall2(irb_.GetRuntime(FindCatchBlock), 2784 method_object_addr, ti_offset_value); 2785 2786 // Switch instruction (Go to unwind basic block by default) 2787 llvm::SwitchInst* sw = 2788 irb_.CreateSwitch(catch_handler_index_value, GetUnwindBasicBlock()); 2789 2790 // Cases with matched catch block 2791 art::CatchHandlerIterator iter(*dex_compilation_unit_->GetCodeItem(), ti->start_addr_); 2792 2793 for (uint32_t c = 0; iter.HasNext(); iter.Next(), ++c) { 2794 sw->addCase(irb_.getInt32(c), GetBasicBlock(iter.GetHandlerAddress())); 2795 } 2796 2797 // Restore the orignal insert point for IRBuilder 2798 irb_.restoreIP(irb_ip_original); 2799 2800 // Cache this landing pad 2801 DCHECK_GT(basic_block_landing_pads_.size(), static_cast<size_t>(ti_offset)); 2802 basic_block_landing_pads_[ti_offset] = block_lpad; 2803 2804 return block_lpad; 2805 } 2806 2807 llvm::BasicBlock* GBCExpanderPass::GetUnwindBasicBlock() { 2808 // Check the existing unwinding baisc block block 2809 if (basic_block_unwind_ != NULL) { 2810 return basic_block_unwind_; 2811 } 2812 2813 // Create new basic block for unwinding 2814 basic_block_unwind_ = 2815 llvm::BasicBlock::Create(context_, "exception_unwind", func_); 2816 2817 // Change IRBuilder insert point 2818 llvm::IRBuilderBase::InsertPoint irb_ip_original = irb_.saveIP(); 2819 irb_.SetInsertPoint(basic_block_unwind_); 2820 2821 // Pop the shadow frame 2822 Expand_PopShadowFrame(); 2823 2824 // Emit the code to return default value (zero) for the given return type. 2825 char ret_shorty = dex_compilation_unit_->GetShorty()[0]; 2826 ret_shorty = art::RemapShorty(ret_shorty); 2827 if (ret_shorty == 'V') { 2828 irb_.CreateRetVoid(); 2829 } else { 2830 irb_.CreateRet(irb_.getJZero(ret_shorty)); 2831 } 2832 2833 // Restore the orignal insert point for IRBuilder 2834 irb_.restoreIP(irb_ip_original); 2835 2836 return basic_block_unwind_; 2837 } 2838 2839 void GBCExpanderPass::EmitBranchExceptionLandingPad(uint32_t dex_pc) { 2840 if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) { 2841 landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(), 2842 irb_.GetInsertBlock())); 2843 irb_.CreateBr(lpad); 2844 } else { 2845 irb_.CreateBr(GetUnwindBasicBlock()); 2846 } 2847 } 2848 2849 void GBCExpanderPass::EmitGuard_ExceptionLandingPad(uint32_t dex_pc) { 2850 llvm::Value* exception_pending = irb_.Runtime().EmitIsExceptionPending(); 2851 2852 llvm::BasicBlock* block_cont = CreateBasicBlockWithDexPC(dex_pc, "cont"); 2853 2854 if (llvm::BasicBlock* lpad = GetLandingPadBasicBlock(dex_pc)) { 2855 landing_pad_phi_mapping_[lpad].push_back(std::make_pair(current_bb_->getUniquePredecessor(), 2856 irb_.GetInsertBlock())); 2857 irb_.CreateCondBr(exception_pending, lpad, block_cont, kUnlikely); 2858 } else { 2859 irb_.CreateCondBr(exception_pending, GetUnwindBasicBlock(), block_cont, kUnlikely); 2860 } 2861 2862 irb_.SetInsertPoint(block_cont); 2863 } 2864 2865 llvm::Value* 2866 GBCExpanderPass::ExpandIntrinsic(IntrinsicHelper::IntrinsicId intr_id, 2867 llvm::CallInst& call_inst) { 2868 switch (intr_id) { 2869 //==- Thread -----------------------------------------------------------==// 2870 case IntrinsicHelper::GetCurrentThread: { 2871 return irb_.Runtime().EmitGetCurrentThread(); 2872 } 2873 case IntrinsicHelper::CheckSuspend: { 2874 Expand_TestSuspend(call_inst); 2875 return NULL; 2876 } 2877 case IntrinsicHelper::TestSuspend: { 2878 Expand_TestSuspend(call_inst); 2879 return NULL; 2880 } 2881 case IntrinsicHelper::MarkGCCard: { 2882 Expand_MarkGCCard(call_inst); 2883 return NULL; 2884 } 2885 2886 //==- Exception --------------------------------------------------------==// 2887 case IntrinsicHelper::ThrowException: { 2888 return ExpandToRuntime(ThrowException, call_inst); 2889 } 2890 case IntrinsicHelper::HLThrowException: { 2891 uint32_t dex_pc = LV2UInt(call_inst.getMetadata("DexOff")->getOperand(0)); 2892 2893 EmitUpdateDexPC(dex_pc); 2894 2895 irb_.CreateCall(irb_.GetRuntime(ThrowException), 2896 call_inst.getArgOperand(0)); 2897 2898 EmitGuard_ExceptionLandingPad(dex_pc); 2899 return NULL; 2900 } 2901 case IntrinsicHelper::GetException: { 2902 return irb_.Runtime().EmitGetAndClearException(); 2903 } 2904 case IntrinsicHelper::IsExceptionPending: { 2905 return irb_.Runtime().EmitIsExceptionPending(); 2906 } 2907 case IntrinsicHelper::FindCatchBlock: { 2908 return ExpandToRuntime(FindCatchBlock, call_inst); 2909 } 2910 case IntrinsicHelper::ThrowDivZeroException: { 2911 return ExpandToRuntime(ThrowDivZeroException, call_inst); 2912 } 2913 case IntrinsicHelper::ThrowNullPointerException: { 2914 return ExpandToRuntime(ThrowNullPointerException, call_inst); 2915 } 2916 case IntrinsicHelper::ThrowIndexOutOfBounds: { 2917 return ExpandToRuntime(ThrowIndexOutOfBounds, call_inst); 2918 } 2919 2920 //==- Const String -----------------------------------------------------==// 2921 case IntrinsicHelper::ConstString: { 2922 return Expand_ConstString(call_inst); 2923 } 2924 case IntrinsicHelper::LoadStringFromDexCache: { 2925 return Expand_LoadStringFromDexCache(call_inst.getArgOperand(0)); 2926 } 2927 case IntrinsicHelper::ResolveString: { 2928 return ExpandToRuntime(ResolveString, call_inst); 2929 } 2930 2931 //==- Const Class ------------------------------------------------------==// 2932 case IntrinsicHelper::ConstClass: { 2933 return Expand_ConstClass(call_inst); 2934 } 2935 case IntrinsicHelper::InitializeTypeAndVerifyAccess: { 2936 return ExpandToRuntime(InitializeTypeAndVerifyAccess, call_inst); 2937 } 2938 case IntrinsicHelper::LoadTypeFromDexCache: { 2939 return Expand_LoadTypeFromDexCache(call_inst.getArgOperand(0)); 2940 } 2941 case IntrinsicHelper::InitializeType: { 2942 return ExpandToRuntime(InitializeType, call_inst); 2943 } 2944 2945 //==- Lock -------------------------------------------------------------==// 2946 case IntrinsicHelper::LockObject: { 2947 Expand_LockObject(call_inst.getArgOperand(0)); 2948 return NULL; 2949 } 2950 case IntrinsicHelper::UnlockObject: { 2951 Expand_UnlockObject(call_inst.getArgOperand(0)); 2952 return NULL; 2953 } 2954 2955 //==- Cast -------------------------------------------------------------==// 2956 case IntrinsicHelper::CheckCast: { 2957 return ExpandToRuntime(CheckCast, call_inst); 2958 } 2959 case IntrinsicHelper::HLCheckCast: { 2960 Expand_HLCheckCast(call_inst); 2961 return NULL; 2962 } 2963 case IntrinsicHelper::IsAssignable: { 2964 return ExpandToRuntime(IsAssignable, call_inst); 2965 } 2966 2967 //==- Alloc ------------------------------------------------------------==// 2968 case IntrinsicHelper::AllocObject: { 2969 return ExpandToRuntime(AllocObject, call_inst); 2970 } 2971 case IntrinsicHelper::AllocObjectWithAccessCheck: { 2972 return ExpandToRuntime(AllocObjectWithAccessCheck, call_inst); 2973 } 2974 2975 //==- Instance ---------------------------------------------------------==// 2976 case IntrinsicHelper::NewInstance: { 2977 return Expand_NewInstance(call_inst); 2978 } 2979 case IntrinsicHelper::InstanceOf: { 2980 return Expand_InstanceOf(call_inst); 2981 } 2982 2983 //==- Array ------------------------------------------------------------==// 2984 case IntrinsicHelper::NewArray: { 2985 return Expand_NewArray(call_inst); 2986 } 2987 case IntrinsicHelper::OptArrayLength: { 2988 return Expand_OptArrayLength(call_inst); 2989 } 2990 case IntrinsicHelper::ArrayLength: { 2991 return EmitLoadArrayLength(call_inst.getArgOperand(0)); 2992 } 2993 case IntrinsicHelper::AllocArray: { 2994 return ExpandToRuntime(AllocArray, call_inst); 2995 } 2996 case IntrinsicHelper::AllocArrayWithAccessCheck: { 2997 return ExpandToRuntime(AllocArrayWithAccessCheck, 2998 call_inst); 2999 } 3000 case IntrinsicHelper::CheckAndAllocArray: { 3001 return ExpandToRuntime(CheckAndAllocArray, call_inst); 3002 } 3003 case IntrinsicHelper::CheckAndAllocArrayWithAccessCheck: { 3004 return ExpandToRuntime(CheckAndAllocArrayWithAccessCheck, 3005 call_inst); 3006 } 3007 case IntrinsicHelper::ArrayGet: { 3008 return Expand_ArrayGet(call_inst.getArgOperand(0), 3009 call_inst.getArgOperand(1), 3010 kInt); 3011 } 3012 case IntrinsicHelper::ArrayGetWide: { 3013 return Expand_ArrayGet(call_inst.getArgOperand(0), 3014 call_inst.getArgOperand(1), 3015 kLong); 3016 } 3017 case IntrinsicHelper::ArrayGetObject: { 3018 return Expand_ArrayGet(call_inst.getArgOperand(0), 3019 call_inst.getArgOperand(1), 3020 kObject); 3021 } 3022 case IntrinsicHelper::ArrayGetBoolean: { 3023 return Expand_ArrayGet(call_inst.getArgOperand(0), 3024 call_inst.getArgOperand(1), 3025 kBoolean); 3026 } 3027 case IntrinsicHelper::ArrayGetByte: { 3028 return Expand_ArrayGet(call_inst.getArgOperand(0), 3029 call_inst.getArgOperand(1), 3030 kByte); 3031 } 3032 case IntrinsicHelper::ArrayGetChar: { 3033 return Expand_ArrayGet(call_inst.getArgOperand(0), 3034 call_inst.getArgOperand(1), 3035 kChar); 3036 } 3037 case IntrinsicHelper::ArrayGetShort: { 3038 return Expand_ArrayGet(call_inst.getArgOperand(0), 3039 call_inst.getArgOperand(1), 3040 kShort); 3041 } 3042 case IntrinsicHelper::ArrayPut: { 3043 Expand_ArrayPut(call_inst.getArgOperand(0), 3044 call_inst.getArgOperand(1), 3045 call_inst.getArgOperand(2), 3046 kInt); 3047 return NULL; 3048 } 3049 case IntrinsicHelper::ArrayPutWide: { 3050 Expand_ArrayPut(call_inst.getArgOperand(0), 3051 call_inst.getArgOperand(1), 3052 call_inst.getArgOperand(2), 3053 kLong); 3054 return NULL; 3055 } 3056 case IntrinsicHelper::ArrayPutObject: { 3057 Expand_ArrayPut(call_inst.getArgOperand(0), 3058 call_inst.getArgOperand(1), 3059 call_inst.getArgOperand(2), 3060 kObject); 3061 return NULL; 3062 } 3063 case IntrinsicHelper::ArrayPutBoolean: { 3064 Expand_ArrayPut(call_inst.getArgOperand(0), 3065 call_inst.getArgOperand(1), 3066 call_inst.getArgOperand(2), 3067 kBoolean); 3068 return NULL; 3069 } 3070 case IntrinsicHelper::ArrayPutByte: { 3071 Expand_ArrayPut(call_inst.getArgOperand(0), 3072 call_inst.getArgOperand(1), 3073 call_inst.getArgOperand(2), 3074 kByte); 3075 return NULL; 3076 } 3077 case IntrinsicHelper::ArrayPutChar: { 3078 Expand_ArrayPut(call_inst.getArgOperand(0), 3079 call_inst.getArgOperand(1), 3080 call_inst.getArgOperand(2), 3081 kChar); 3082 return NULL; 3083 } 3084 case IntrinsicHelper::ArrayPutShort: { 3085 Expand_ArrayPut(call_inst.getArgOperand(0), 3086 call_inst.getArgOperand(1), 3087 call_inst.getArgOperand(2), 3088 kShort); 3089 return NULL; 3090 } 3091 case IntrinsicHelper::CheckPutArrayElement: { 3092 return ExpandToRuntime(CheckPutArrayElement, call_inst); 3093 } 3094 case IntrinsicHelper::FilledNewArray: { 3095 Expand_FilledNewArray(call_inst); 3096 return NULL; 3097 } 3098 case IntrinsicHelper::FillArrayData: { 3099 return ExpandToRuntime(FillArrayData, call_inst); 3100 } 3101 case IntrinsicHelper::HLFillArrayData: { 3102 Expand_HLFillArrayData(call_inst); 3103 return NULL; 3104 } 3105 case IntrinsicHelper::HLFilledNewArray: { 3106 return Expand_HLFilledNewArray(call_inst); 3107 } 3108 3109 //==- Instance Field ---------------------------------------------------==// 3110 case IntrinsicHelper::InstanceFieldGet: 3111 case IntrinsicHelper::InstanceFieldGetBoolean: 3112 case IntrinsicHelper::InstanceFieldGetByte: 3113 case IntrinsicHelper::InstanceFieldGetChar: 3114 case IntrinsicHelper::InstanceFieldGetShort: { 3115 return ExpandToRuntime(Get32Instance, call_inst); 3116 } 3117 case IntrinsicHelper::InstanceFieldGetWide: { 3118 return ExpandToRuntime(Get64Instance, call_inst); 3119 } 3120 case IntrinsicHelper::InstanceFieldGetObject: { 3121 return ExpandToRuntime(GetObjectInstance, call_inst); 3122 } 3123 case IntrinsicHelper::InstanceFieldGetFast: { 3124 return Expand_IGetFast(call_inst.getArgOperand(0), 3125 call_inst.getArgOperand(1), 3126 call_inst.getArgOperand(2), 3127 kInt); 3128 } 3129 case IntrinsicHelper::InstanceFieldGetWideFast: { 3130 return Expand_IGetFast(call_inst.getArgOperand(0), 3131 call_inst.getArgOperand(1), 3132 call_inst.getArgOperand(2), 3133 kLong); 3134 } 3135 case IntrinsicHelper::InstanceFieldGetObjectFast: { 3136 return Expand_IGetFast(call_inst.getArgOperand(0), 3137 call_inst.getArgOperand(1), 3138 call_inst.getArgOperand(2), 3139 kObject); 3140 } 3141 case IntrinsicHelper::InstanceFieldGetBooleanFast: { 3142 return Expand_IGetFast(call_inst.getArgOperand(0), 3143 call_inst.getArgOperand(1), 3144 call_inst.getArgOperand(2), 3145 kBoolean); 3146 } 3147 case IntrinsicHelper::InstanceFieldGetByteFast: { 3148 return Expand_IGetFast(call_inst.getArgOperand(0), 3149 call_inst.getArgOperand(1), 3150 call_inst.getArgOperand(2), 3151 kByte); 3152 } 3153 case IntrinsicHelper::InstanceFieldGetCharFast: { 3154 return Expand_IGetFast(call_inst.getArgOperand(0), 3155 call_inst.getArgOperand(1), 3156 call_inst.getArgOperand(2), 3157 kChar); 3158 } 3159 case IntrinsicHelper::InstanceFieldGetShortFast: { 3160 return Expand_IGetFast(call_inst.getArgOperand(0), 3161 call_inst.getArgOperand(1), 3162 call_inst.getArgOperand(2), 3163 kShort); 3164 } 3165 case IntrinsicHelper::InstanceFieldPut: 3166 case IntrinsicHelper::InstanceFieldPutBoolean: 3167 case IntrinsicHelper::InstanceFieldPutByte: 3168 case IntrinsicHelper::InstanceFieldPutChar: 3169 case IntrinsicHelper::InstanceFieldPutShort: { 3170 return ExpandToRuntime(Set32Instance, call_inst); 3171 } 3172 case IntrinsicHelper::InstanceFieldPutWide: { 3173 return ExpandToRuntime(Set64Instance, call_inst); 3174 } 3175 case IntrinsicHelper::InstanceFieldPutObject: { 3176 return ExpandToRuntime(SetObjectInstance, call_inst); 3177 } 3178 case IntrinsicHelper::InstanceFieldPutFast: { 3179 Expand_IPutFast(call_inst.getArgOperand(0), 3180 call_inst.getArgOperand(1), 3181 call_inst.getArgOperand(2), 3182 call_inst.getArgOperand(3), 3183 kInt); 3184 return NULL; 3185 } 3186 case IntrinsicHelper::InstanceFieldPutWideFast: { 3187 Expand_IPutFast(call_inst.getArgOperand(0), 3188 call_inst.getArgOperand(1), 3189 call_inst.getArgOperand(2), 3190 call_inst.getArgOperand(3), 3191 kLong); 3192 return NULL; 3193 } 3194 case IntrinsicHelper::InstanceFieldPutObjectFast: { 3195 Expand_IPutFast(call_inst.getArgOperand(0), 3196 call_inst.getArgOperand(1), 3197 call_inst.getArgOperand(2), 3198 call_inst.getArgOperand(3), 3199 kObject); 3200 return NULL; 3201 } 3202 case IntrinsicHelper::InstanceFieldPutBooleanFast: { 3203 Expand_IPutFast(call_inst.getArgOperand(0), 3204 call_inst.getArgOperand(1), 3205 call_inst.getArgOperand(2), 3206 call_inst.getArgOperand(3), 3207 kBoolean); 3208 return NULL; 3209 } 3210 case IntrinsicHelper::InstanceFieldPutByteFast: { 3211 Expand_IPutFast(call_inst.getArgOperand(0), 3212 call_inst.getArgOperand(1), 3213 call_inst.getArgOperand(2), 3214 call_inst.getArgOperand(3), 3215 kByte); 3216 return NULL; 3217 } 3218 case IntrinsicHelper::InstanceFieldPutCharFast: { 3219 Expand_IPutFast(call_inst.getArgOperand(0), 3220 call_inst.getArgOperand(1), 3221 call_inst.getArgOperand(2), 3222 call_inst.getArgOperand(3), 3223 kChar); 3224 return NULL; 3225 } 3226 case IntrinsicHelper::InstanceFieldPutShortFast: { 3227 Expand_IPutFast(call_inst.getArgOperand(0), 3228 call_inst.getArgOperand(1), 3229 call_inst.getArgOperand(2), 3230 call_inst.getArgOperand(3), 3231 kShort); 3232 return NULL; 3233 } 3234 3235 //==- Static Field -----------------------------------------------------==// 3236 case IntrinsicHelper::StaticFieldGet: 3237 case IntrinsicHelper::StaticFieldGetBoolean: 3238 case IntrinsicHelper::StaticFieldGetByte: 3239 case IntrinsicHelper::StaticFieldGetChar: 3240 case IntrinsicHelper::StaticFieldGetShort: { 3241 return ExpandToRuntime(Get32Static, call_inst); 3242 } 3243 case IntrinsicHelper::StaticFieldGetWide: { 3244 return ExpandToRuntime(Get64Static, call_inst); 3245 } 3246 case IntrinsicHelper::StaticFieldGetObject: { 3247 return ExpandToRuntime(GetObjectStatic, call_inst); 3248 } 3249 case IntrinsicHelper::StaticFieldGetFast: { 3250 return Expand_SGetFast(call_inst.getArgOperand(0), 3251 call_inst.getArgOperand(1), 3252 call_inst.getArgOperand(2), 3253 kInt); 3254 } 3255 case IntrinsicHelper::StaticFieldGetWideFast: { 3256 return Expand_SGetFast(call_inst.getArgOperand(0), 3257 call_inst.getArgOperand(1), 3258 call_inst.getArgOperand(2), 3259 kLong); 3260 } 3261 case IntrinsicHelper::StaticFieldGetObjectFast: { 3262 return Expand_SGetFast(call_inst.getArgOperand(0), 3263 call_inst.getArgOperand(1), 3264 call_inst.getArgOperand(2), 3265 kObject); 3266 } 3267 case IntrinsicHelper::StaticFieldGetBooleanFast: { 3268 return Expand_SGetFast(call_inst.getArgOperand(0), 3269 call_inst.getArgOperand(1), 3270 call_inst.getArgOperand(2), 3271 kBoolean); 3272 } 3273 case IntrinsicHelper::StaticFieldGetByteFast: { 3274 return Expand_SGetFast(call_inst.getArgOperand(0), 3275 call_inst.getArgOperand(1), 3276 call_inst.getArgOperand(2), 3277 kByte); 3278 } 3279 case IntrinsicHelper::StaticFieldGetCharFast: { 3280 return Expand_SGetFast(call_inst.getArgOperand(0), 3281 call_inst.getArgOperand(1), 3282 call_inst.getArgOperand(2), 3283 kChar); 3284 } 3285 case IntrinsicHelper::StaticFieldGetShortFast: { 3286 return Expand_SGetFast(call_inst.getArgOperand(0), 3287 call_inst.getArgOperand(1), 3288 call_inst.getArgOperand(2), 3289 kShort); 3290 } 3291 case IntrinsicHelper::StaticFieldPut: 3292 case IntrinsicHelper::StaticFieldPutBoolean: 3293 case IntrinsicHelper::StaticFieldPutByte: 3294 case IntrinsicHelper::StaticFieldPutChar: 3295 case IntrinsicHelper::StaticFieldPutShort: { 3296 return ExpandToRuntime(Set32Static, call_inst); 3297 } 3298 case IntrinsicHelper::StaticFieldPutWide: { 3299 return ExpandToRuntime(Set64Static, call_inst); 3300 } 3301 case IntrinsicHelper::StaticFieldPutObject: { 3302 return ExpandToRuntime(SetObjectStatic, call_inst); 3303 } 3304 case IntrinsicHelper::StaticFieldPutFast: { 3305 Expand_SPutFast(call_inst.getArgOperand(0), 3306 call_inst.getArgOperand(1), 3307 call_inst.getArgOperand(2), 3308 call_inst.getArgOperand(3), 3309 kInt); 3310 return NULL; 3311 } 3312 case IntrinsicHelper::StaticFieldPutWideFast: { 3313 Expand_SPutFast(call_inst.getArgOperand(0), 3314 call_inst.getArgOperand(1), 3315 call_inst.getArgOperand(2), 3316 call_inst.getArgOperand(3), 3317 kLong); 3318 return NULL; 3319 } 3320 case IntrinsicHelper::StaticFieldPutObjectFast: { 3321 Expand_SPutFast(call_inst.getArgOperand(0), 3322 call_inst.getArgOperand(1), 3323 call_inst.getArgOperand(2), 3324 call_inst.getArgOperand(3), 3325 kObject); 3326 return NULL; 3327 } 3328 case IntrinsicHelper::StaticFieldPutBooleanFast: { 3329 Expand_SPutFast(call_inst.getArgOperand(0), 3330 call_inst.getArgOperand(1), 3331 call_inst.getArgOperand(2), 3332 call_inst.getArgOperand(3), 3333 kBoolean); 3334 return NULL; 3335 } 3336 case IntrinsicHelper::StaticFieldPutByteFast: { 3337 Expand_SPutFast(call_inst.getArgOperand(0), 3338 call_inst.getArgOperand(1), 3339 call_inst.getArgOperand(2), 3340 call_inst.getArgOperand(3), 3341 kByte); 3342 return NULL; 3343 } 3344 case IntrinsicHelper::StaticFieldPutCharFast: { 3345 Expand_SPutFast(call_inst.getArgOperand(0), 3346 call_inst.getArgOperand(1), 3347 call_inst.getArgOperand(2), 3348 call_inst.getArgOperand(3), 3349 kChar); 3350 return NULL; 3351 } 3352 case IntrinsicHelper::StaticFieldPutShortFast: { 3353 Expand_SPutFast(call_inst.getArgOperand(0), 3354 call_inst.getArgOperand(1), 3355 call_inst.getArgOperand(2), 3356 call_inst.getArgOperand(3), 3357 kShort); 3358 return NULL; 3359 } 3360 case IntrinsicHelper::LoadDeclaringClassSSB: { 3361 return Expand_LoadDeclaringClassSSB(call_inst.getArgOperand(0)); 3362 } 3363 case IntrinsicHelper::LoadClassSSBFromDexCache: { 3364 return Expand_LoadClassSSBFromDexCache(call_inst.getArgOperand(0)); 3365 } 3366 case IntrinsicHelper::InitializeAndLoadClassSSB: { 3367 return ExpandToRuntime(InitializeStaticStorage, call_inst); 3368 } 3369 3370 //==- High-level Array -------------------------------------------------==// 3371 case IntrinsicHelper::HLArrayGet: { 3372 return Expand_HLArrayGet(call_inst, kInt); 3373 } 3374 case IntrinsicHelper::HLArrayGetBoolean: { 3375 return Expand_HLArrayGet(call_inst, kBoolean); 3376 } 3377 case IntrinsicHelper::HLArrayGetByte: { 3378 return Expand_HLArrayGet(call_inst, kByte); 3379 } 3380 case IntrinsicHelper::HLArrayGetChar: { 3381 return Expand_HLArrayGet(call_inst, kChar); 3382 } 3383 case IntrinsicHelper::HLArrayGetShort: { 3384 return Expand_HLArrayGet(call_inst, kShort); 3385 } 3386 case IntrinsicHelper::HLArrayGetFloat: { 3387 return Expand_HLArrayGet(call_inst, kFloat); 3388 } 3389 case IntrinsicHelper::HLArrayGetWide: { 3390 return Expand_HLArrayGet(call_inst, kLong); 3391 } 3392 case IntrinsicHelper::HLArrayGetDouble: { 3393 return Expand_HLArrayGet(call_inst, kDouble); 3394 } 3395 case IntrinsicHelper::HLArrayGetObject: { 3396 return Expand_HLArrayGet(call_inst, kObject); 3397 } 3398 case IntrinsicHelper::HLArrayPut: { 3399 Expand_HLArrayPut(call_inst, kInt); 3400 return NULL; 3401 } 3402 case IntrinsicHelper::HLArrayPutBoolean: { 3403 Expand_HLArrayPut(call_inst, kBoolean); 3404 return NULL; 3405 } 3406 case IntrinsicHelper::HLArrayPutByte: { 3407 Expand_HLArrayPut(call_inst, kByte); 3408 return NULL; 3409 } 3410 case IntrinsicHelper::HLArrayPutChar: { 3411 Expand_HLArrayPut(call_inst, kChar); 3412 return NULL; 3413 } 3414 case IntrinsicHelper::HLArrayPutShort: { 3415 Expand_HLArrayPut(call_inst, kShort); 3416 return NULL; 3417 } 3418 case IntrinsicHelper::HLArrayPutFloat: { 3419 Expand_HLArrayPut(call_inst, kFloat); 3420 return NULL; 3421 } 3422 case IntrinsicHelper::HLArrayPutWide: { 3423 Expand_HLArrayPut(call_inst, kLong); 3424 return NULL; 3425 } 3426 case IntrinsicHelper::HLArrayPutDouble: { 3427 Expand_HLArrayPut(call_inst, kDouble); 3428 return NULL; 3429 } 3430 case IntrinsicHelper::HLArrayPutObject: { 3431 Expand_HLArrayPut(call_inst, kObject); 3432 return NULL; 3433 } 3434 3435 //==- High-level Instance ----------------------------------------------==// 3436 case IntrinsicHelper::HLIGet: { 3437 return Expand_HLIGet(call_inst, kInt); 3438 } 3439 case IntrinsicHelper::HLIGetBoolean: { 3440 return Expand_HLIGet(call_inst, kBoolean); 3441 } 3442 case IntrinsicHelper::HLIGetByte: { 3443 return Expand_HLIGet(call_inst, kByte); 3444 } 3445 case IntrinsicHelper::HLIGetChar: { 3446 return Expand_HLIGet(call_inst, kChar); 3447 } 3448 case IntrinsicHelper::HLIGetShort: { 3449 return Expand_HLIGet(call_inst, kShort); 3450 } 3451 case IntrinsicHelper::HLIGetFloat: { 3452 return Expand_HLIGet(call_inst, kFloat); 3453 } 3454 case IntrinsicHelper::HLIGetWide: { 3455 return Expand_HLIGet(call_inst, kLong); 3456 } 3457 case IntrinsicHelper::HLIGetDouble: { 3458 return Expand_HLIGet(call_inst, kDouble); 3459 } 3460 case IntrinsicHelper::HLIGetObject: { 3461 return Expand_HLIGet(call_inst, kObject); 3462 } 3463 case IntrinsicHelper::HLIPut: { 3464 Expand_HLIPut(call_inst, kInt); 3465 return NULL; 3466 } 3467 case IntrinsicHelper::HLIPutBoolean: { 3468 Expand_HLIPut(call_inst, kBoolean); 3469 return NULL; 3470 } 3471 case IntrinsicHelper::HLIPutByte: { 3472 Expand_HLIPut(call_inst, kByte); 3473 return NULL; 3474 } 3475 case IntrinsicHelper::HLIPutChar: { 3476 Expand_HLIPut(call_inst, kChar); 3477 return NULL; 3478 } 3479 case IntrinsicHelper::HLIPutShort: { 3480 Expand_HLIPut(call_inst, kShort); 3481 return NULL; 3482 } 3483 case IntrinsicHelper::HLIPutFloat: { 3484 Expand_HLIPut(call_inst, kFloat); 3485 return NULL; 3486 } 3487 case IntrinsicHelper::HLIPutWide: { 3488 Expand_HLIPut(call_inst, kLong); 3489 return NULL; 3490 } 3491 case IntrinsicHelper::HLIPutDouble: { 3492 Expand_HLIPut(call_inst, kDouble); 3493 return NULL; 3494 } 3495 case IntrinsicHelper::HLIPutObject: { 3496 Expand_HLIPut(call_inst, kObject); 3497 return NULL; 3498 } 3499 3500 //==- High-level Invoke ------------------------------------------------==// 3501 case IntrinsicHelper::HLInvokeVoid: 3502 case IntrinsicHelper::HLInvokeObj: 3503 case IntrinsicHelper::HLInvokeInt: 3504 case IntrinsicHelper::HLInvokeFloat: 3505 case IntrinsicHelper::HLInvokeLong: 3506 case IntrinsicHelper::HLInvokeDouble: { 3507 return Expand_HLInvoke(call_inst); 3508 } 3509 3510 //==- Invoke -----------------------------------------------------------==// 3511 case IntrinsicHelper::FindStaticMethodWithAccessCheck: { 3512 return ExpandToRuntime(FindStaticMethodWithAccessCheck, call_inst); 3513 } 3514 case IntrinsicHelper::FindDirectMethodWithAccessCheck: { 3515 return ExpandToRuntime(FindDirectMethodWithAccessCheck, call_inst); 3516 } 3517 case IntrinsicHelper::FindVirtualMethodWithAccessCheck: { 3518 return ExpandToRuntime(FindVirtualMethodWithAccessCheck, call_inst); 3519 } 3520 case IntrinsicHelper::FindSuperMethodWithAccessCheck: { 3521 return ExpandToRuntime(FindSuperMethodWithAccessCheck, call_inst); 3522 } 3523 case IntrinsicHelper::FindInterfaceMethodWithAccessCheck: { 3524 return ExpandToRuntime(FindInterfaceMethodWithAccessCheck, call_inst); 3525 } 3526 case IntrinsicHelper::GetSDCalleeMethodObjAddrFast: { 3527 return Expand_GetSDCalleeMethodObjAddrFast(call_inst.getArgOperand(0)); 3528 } 3529 case IntrinsicHelper::GetVirtualCalleeMethodObjAddrFast: { 3530 return Expand_GetVirtualCalleeMethodObjAddrFast( 3531 call_inst.getArgOperand(0), call_inst.getArgOperand(1)); 3532 } 3533 case IntrinsicHelper::GetInterfaceCalleeMethodObjAddrFast: { 3534 return ExpandToRuntime(FindInterfaceMethod, call_inst); 3535 } 3536 case IntrinsicHelper::InvokeRetVoid: 3537 case IntrinsicHelper::InvokeRetBoolean: 3538 case IntrinsicHelper::InvokeRetByte: 3539 case IntrinsicHelper::InvokeRetChar: 3540 case IntrinsicHelper::InvokeRetShort: 3541 case IntrinsicHelper::InvokeRetInt: 3542 case IntrinsicHelper::InvokeRetLong: 3543 case IntrinsicHelper::InvokeRetFloat: 3544 case IntrinsicHelper::InvokeRetDouble: 3545 case IntrinsicHelper::InvokeRetObject: { 3546 return Expand_Invoke(call_inst); 3547 } 3548 3549 //==- Math -------------------------------------------------------------==// 3550 case IntrinsicHelper::DivInt: { 3551 return Expand_DivRem(call_inst, /* is_div */true, kInt); 3552 } 3553 case IntrinsicHelper::RemInt: { 3554 return Expand_DivRem(call_inst, /* is_div */false, kInt); 3555 } 3556 case IntrinsicHelper::DivLong: { 3557 return Expand_DivRem(call_inst, /* is_div */true, kLong); 3558 } 3559 case IntrinsicHelper::RemLong: { 3560 return Expand_DivRem(call_inst, /* is_div */false, kLong); 3561 } 3562 case IntrinsicHelper::D2L: { 3563 return ExpandToRuntime(art_d2l, call_inst); 3564 } 3565 case IntrinsicHelper::D2I: { 3566 return ExpandToRuntime(art_d2i, call_inst); 3567 } 3568 case IntrinsicHelper::F2L: { 3569 return ExpandToRuntime(art_f2l, call_inst); 3570 } 3571 case IntrinsicHelper::F2I: { 3572 return ExpandToRuntime(art_f2i, call_inst); 3573 } 3574 3575 //==- High-level Static ------------------------------------------------==// 3576 case IntrinsicHelper::HLSget: { 3577 return Expand_HLSget(call_inst, kInt); 3578 } 3579 case IntrinsicHelper::HLSgetBoolean: { 3580 return Expand_HLSget(call_inst, kBoolean); 3581 } 3582 case IntrinsicHelper::HLSgetByte: { 3583 return Expand_HLSget(call_inst, kByte); 3584 } 3585 case IntrinsicHelper::HLSgetChar: { 3586 return Expand_HLSget(call_inst, kChar); 3587 } 3588 case IntrinsicHelper::HLSgetShort: { 3589 return Expand_HLSget(call_inst, kShort); 3590 } 3591 case IntrinsicHelper::HLSgetFloat: { 3592 return Expand_HLSget(call_inst, kFloat); 3593 } 3594 case IntrinsicHelper::HLSgetWide: { 3595 return Expand_HLSget(call_inst, kLong); 3596 } 3597 case IntrinsicHelper::HLSgetDouble: { 3598 return Expand_HLSget(call_inst, kDouble); 3599 } 3600 case IntrinsicHelper::HLSgetObject: { 3601 return Expand_HLSget(call_inst, kObject); 3602 } 3603 case IntrinsicHelper::HLSput: { 3604 Expand_HLSput(call_inst, kInt); 3605 return NULL; 3606 } 3607 case IntrinsicHelper::HLSputBoolean: { 3608 Expand_HLSput(call_inst, kBoolean); 3609 return NULL; 3610 } 3611 case IntrinsicHelper::HLSputByte: { 3612 Expand_HLSput(call_inst, kByte); 3613 return NULL; 3614 } 3615 case IntrinsicHelper::HLSputChar: { 3616 Expand_HLSput(call_inst, kChar); 3617 return NULL; 3618 } 3619 case IntrinsicHelper::HLSputShort: { 3620 Expand_HLSput(call_inst, kShort); 3621 return NULL; 3622 } 3623 case IntrinsicHelper::HLSputFloat: { 3624 Expand_HLSput(call_inst, kFloat); 3625 return NULL; 3626 } 3627 case IntrinsicHelper::HLSputWide: { 3628 Expand_HLSput(call_inst, kLong); 3629 return NULL; 3630 } 3631 case IntrinsicHelper::HLSputDouble: { 3632 Expand_HLSput(call_inst, kDouble); 3633 return NULL; 3634 } 3635 case IntrinsicHelper::HLSputObject: { 3636 Expand_HLSput(call_inst, kObject); 3637 return NULL; 3638 } 3639 3640 //==- High-level Monitor -----------------------------------------------==// 3641 case IntrinsicHelper::MonitorEnter: { 3642 Expand_MonitorEnter(call_inst); 3643 return NULL; 3644 } 3645 case IntrinsicHelper::MonitorExit: { 3646 Expand_MonitorExit(call_inst); 3647 return NULL; 3648 } 3649 3650 //==- Shadow Frame -----------------------------------------------------==// 3651 case IntrinsicHelper::AllocaShadowFrame: { 3652 Expand_AllocaShadowFrame(call_inst.getArgOperand(0)); 3653 return NULL; 3654 } 3655 case IntrinsicHelper::SetVReg: { 3656 Expand_SetVReg(call_inst.getArgOperand(0), 3657 call_inst.getArgOperand(1)); 3658 return NULL; 3659 } 3660 case IntrinsicHelper::PopShadowFrame: { 3661 Expand_PopShadowFrame(); 3662 return NULL; 3663 } 3664 case IntrinsicHelper::UpdateDexPC: { 3665 Expand_UpdateDexPC(call_inst.getArgOperand(0)); 3666 return NULL; 3667 } 3668 3669 //==- Comparison -------------------------------------------------------==// 3670 case IntrinsicHelper::CmplFloat: 3671 case IntrinsicHelper::CmplDouble: { 3672 return Expand_FPCompare(call_inst.getArgOperand(0), 3673 call_inst.getArgOperand(1), 3674 false); 3675 } 3676 case IntrinsicHelper::CmpgFloat: 3677 case IntrinsicHelper::CmpgDouble: { 3678 return Expand_FPCompare(call_inst.getArgOperand(0), 3679 call_inst.getArgOperand(1), 3680 true); 3681 } 3682 case IntrinsicHelper::CmpLong: { 3683 return Expand_LongCompare(call_inst.getArgOperand(0), 3684 call_inst.getArgOperand(1)); 3685 } 3686 3687 //==- Const ------------------------------------------------------------==// 3688 case IntrinsicHelper::ConstInt: 3689 case IntrinsicHelper::ConstLong: { 3690 return call_inst.getArgOperand(0); 3691 } 3692 case IntrinsicHelper::ConstFloat: { 3693 return irb_.CreateBitCast(call_inst.getArgOperand(0), 3694 irb_.getJFloatTy()); 3695 } 3696 case IntrinsicHelper::ConstDouble: { 3697 return irb_.CreateBitCast(call_inst.getArgOperand(0), 3698 irb_.getJDoubleTy()); 3699 } 3700 case IntrinsicHelper::ConstObj: { 3701 CHECK_EQ(LV2UInt(call_inst.getArgOperand(0)), 0U); 3702 return irb_.getJNull(); 3703 } 3704 3705 //==- Method Info ------------------------------------------------------==// 3706 case IntrinsicHelper::MethodInfo: { 3707 // Nothing to be done, because MethodInfo carries optional hints that are 3708 // not needed by the portable path. 3709 return NULL; 3710 } 3711 3712 //==- Copy -------------------------------------------------------------==// 3713 case IntrinsicHelper::CopyInt: 3714 case IntrinsicHelper::CopyFloat: 3715 case IntrinsicHelper::CopyLong: 3716 case IntrinsicHelper::CopyDouble: 3717 case IntrinsicHelper::CopyObj: { 3718 return call_inst.getArgOperand(0); 3719 } 3720 3721 //==- Shift ------------------------------------------------------------==// 3722 case IntrinsicHelper::SHLLong: { 3723 return Expand_IntegerShift(call_inst.getArgOperand(0), 3724 call_inst.getArgOperand(1), 3725 kIntegerSHL, kLong); 3726 } 3727 case IntrinsicHelper::SHRLong: { 3728 return Expand_IntegerShift(call_inst.getArgOperand(0), 3729 call_inst.getArgOperand(1), 3730 kIntegerSHR, kLong); 3731 } 3732 case IntrinsicHelper::USHRLong: { 3733 return Expand_IntegerShift(call_inst.getArgOperand(0), 3734 call_inst.getArgOperand(1), 3735 kIntegerUSHR, kLong); 3736 } 3737 case IntrinsicHelper::SHLInt: { 3738 return Expand_IntegerShift(call_inst.getArgOperand(0), 3739 call_inst.getArgOperand(1), 3740 kIntegerSHL, kInt); 3741 } 3742 case IntrinsicHelper::SHRInt: { 3743 return Expand_IntegerShift(call_inst.getArgOperand(0), 3744 call_inst.getArgOperand(1), 3745 kIntegerSHR, kInt); 3746 } 3747 case IntrinsicHelper::USHRInt: { 3748 return Expand_IntegerShift(call_inst.getArgOperand(0), 3749 call_inst.getArgOperand(1), 3750 kIntegerUSHR, kInt); 3751 } 3752 3753 //==- Conversion -------------------------------------------------------==// 3754 case IntrinsicHelper::IntToChar: { 3755 return irb_.CreateZExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJCharTy()), 3756 irb_.getJIntTy()); 3757 } 3758 case IntrinsicHelper::IntToShort: { 3759 return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJShortTy()), 3760 irb_.getJIntTy()); 3761 } 3762 case IntrinsicHelper::IntToByte: { 3763 return irb_.CreateSExt(irb_.CreateTrunc(call_inst.getArgOperand(0), irb_.getJByteTy()), 3764 irb_.getJIntTy()); 3765 } 3766 3767 //==- Exception --------------------------------------------------------==// 3768 case IntrinsicHelper::CatchTargets: { 3769 UpdatePhiInstruction(current_bb_, irb_.GetInsertBlock()); 3770 llvm::SwitchInst* si = llvm::dyn_cast<llvm::SwitchInst>(call_inst.getNextNode()); 3771 CHECK(si != NULL); 3772 irb_.CreateBr(si->getDefaultDest()); 3773 si->eraseFromParent(); 3774 return call_inst.getArgOperand(0); 3775 } 3776 3777 //==- Constructor barrier-----------------------------------------------==// 3778 case IntrinsicHelper::ConstructorBarrier: { 3779 irb_.CreateMemoryBarrier(art::kStoreStore); 3780 return NULL; 3781 } 3782 3783 //==- Unknown Cases ----------------------------------------------------==// 3784 case IntrinsicHelper::MaxIntrinsicId: 3785 case IntrinsicHelper::UnknownId: 3786 // default: 3787 // NOTE: "default" is intentionally commented so that C/C++ compiler will 3788 // give some warning on unmatched cases. 3789 // NOTE: We should not implement these cases. 3790 break; 3791 } 3792 UNIMPLEMENTED(FATAL) << "Unexpected GBC intrinsic: " << static_cast<int>(intr_id); 3793 return NULL; 3794 } // NOLINT(readability/fn_size) 3795 3796 } // anonymous namespace 3797 3798 namespace art { 3799 namespace llvm { 3800 3801 ::llvm::FunctionPass* 3802 CreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb, 3803 CompilerDriver* driver, const DexCompilationUnit* dex_compilation_unit) { 3804 return new GBCExpanderPass(intrinsic_helper, irb, driver, dex_compilation_unit); 3805 } 3806 3807 } // namespace llvm 3808 } // namespace art 3809