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