diff options
| author | 2012-04-16 17:54:20 -0700 | |
|---|---|---|
| committer | 2012-04-16 17:54:20 -0700 | |
| commit | 53d160d2bf4ae21fa524b7476da1feab8f1b819c (patch) | |
| tree | a751c859f61e27bbbddfeeafed26d17a1ec45201 | |
| parent | 3ea0f42467790809fcfc9fc861605d465808090f (diff) | |
| parent | 110bcbafbbc4c27bf31d32732aab06f900c02653 (diff) | |
Merge "Update frame size after the bitcode is translated into machine code." into ics-mr1-plus-art
| -rw-r--r-- | src/compiled_method.h | 8 | ||||
| -rw-r--r-- | src/compiler_llvm/compilation_unit.cc | 65 | ||||
| -rw-r--r-- | src/compiler_llvm/compilation_unit.h | 12 | ||||
| -rw-r--r-- | src/compiler_llvm/jni_compiler.cc | 11 | ||||
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 11 | ||||
| -rw-r--r-- | src/oat_writer.cc | 1 | ||||
| -rw-r--r-- | src/object.h | 2 |
7 files changed, 101 insertions, 9 deletions
diff --git a/src/compiled_method.h b/src/compiled_method.h index 29202564a2..96dfa00c2d 100644 --- a/src/compiled_method.h +++ b/src/compiled_method.h @@ -65,6 +65,12 @@ class CompiledMethod { const std::vector<uint16_t>& GetVmapTable() const; const std::vector<uint8_t>& GetGcMap() const; +#if defined(ART_USE_LLVM_COMPILER) + void SetFrameSizeInBytes(size_t new_frame_size_in_bytes) { + frame_size_in_bytes_ = new_frame_size_in_bytes; + } +#endif + // Aligns an offset from a page aligned value to make it suitable // for code storage. important to ensure that PC relative value // computations work out as expected on ARM. @@ -99,7 +105,7 @@ class CompiledMethod { // For non-LLVM const InstructionSet instruction_set_; std::vector<uint8_t> code_; - const size_t frame_size_in_bytes_; + size_t frame_size_in_bytes_; const uint32_t core_spill_mask_; const uint32_t fp_spill_mask_; std::vector<uint32_t> mapping_table_; diff --git a/src/compiler_llvm/compilation_unit.cc b/src/compiler_llvm/compilation_unit.cc index fde023c914..09e193d46b 100644 --- a/src/compiler_llvm/compilation_unit.cc +++ b/src/compiler_llvm/compilation_unit.cc @@ -16,6 +16,7 @@ #include "compilation_unit.h" +#include "compiled_method.h" #include "instruction_set.h" #include "ir_builder.h" #include "logging.h" @@ -34,6 +35,9 @@ #include <llvm/Assembly/PrintModulePass.h> #include <llvm/Bitcode/ReaderWriter.h> #include <llvm/CallGraphSCCPass.h> +#include <llvm/CodeGen/MachineFrameInfo.h> +#include <llvm/CodeGen/MachineFunction.h> +#include <llvm/CodeGen/MachineFunctionPass.h> #include <llvm/DerivedTypes.h> #include <llvm/LLVMContext.h> #include <llvm/Module.h> @@ -57,6 +61,40 @@ #include <string> +namespace { + +class UpdateFrameSizePass : public llvm::MachineFunctionPass { + public: + static char ID; + + UpdateFrameSizePass() : llvm::MachineFunctionPass(ID), cunit_(NULL) { + LOG(FATAL) << "Unexpected instantiation of UpdateFrameSizePass"; + // NOTE: We have to declare this constructor for llvm::RegisterPass, but + // this constructor won't work because we have no information on + // CompilationUnit. Thus, we should place a LOG(FATAL) here. + } + + UpdateFrameSizePass(art::compiler_llvm::CompilationUnit* cunit) + : llvm::MachineFunctionPass(ID), cunit_(cunit) { + } + + virtual bool runOnMachineFunction(llvm::MachineFunction &MF) { + cunit_->UpdateFrameSizeInBytes(MF.getFunction(), + MF.getFrameInfo()->getStackSize()); + return false; + } + + private: + art::compiler_llvm::CompilationUnit* cunit_; +}; + +char UpdateFrameSizePass::ID = 0; + +llvm::RegisterPass<UpdateFrameSizePass> reg_update_frame_size_pass_( + "update-frame-size", "Update frame size pass", false, false); + +} // end anonymous namespace + namespace art { namespace compiler_llvm { @@ -204,6 +242,9 @@ bool CompilationUnit::Materialize() { return false; } + // Add pass to update the frame_size_in_bytes_ + pm.add(new ::UpdateFrameSizePass(this)); + // Run the per-function optimization fpm.doInitialization(); for (llvm::Module::iterator F = module_->begin(), E = module_->end(); @@ -227,5 +268,29 @@ bool CompilationUnit::Materialize() { } +void CompilationUnit::RegisterCompiledMethod(const llvm::Function* func, + CompiledMethod* compiled_method) { + compiled_methods_map_.Put(func, compiled_method); +} + + +void CompilationUnit::UpdateFrameSizeInBytes(const llvm::Function* func, + size_t frame_size_in_bytes) { + SafeMap<const llvm::Function*, CompiledMethod*>::iterator iter = + compiled_methods_map_.find(func); + + if (iter != compiled_methods_map_.end()) { + CompiledMethod* compiled_method = iter->second; + compiled_method->SetFrameSizeInBytes(frame_size_in_bytes); + + if (frame_size_in_bytes > 1728u) { + LOG(WARNING) << "Huge frame size: " << frame_size_in_bytes + << " elf_idx=" << compiled_method->GetElfIndex() + << " elf_func_idx=" << compiled_method->GetElfFuncIndex(); + } + } +} + + } // namespace compiler_llvm } // namespace art diff --git a/src/compiler_llvm/compilation_unit.h b/src/compiler_llvm/compilation_unit.h index 4b33eceacc..18ecfa0672 100644 --- a/src/compiler_llvm/compilation_unit.h +++ b/src/compiler_llvm/compilation_unit.h @@ -23,11 +23,17 @@ #include "logging.h" #include "runtime_support_builder.h" #include "runtime_support_func.h" +#include "safe_map.h" #include <UniquePtr.h> #include <string> +namespace art { + class CompiledMethod; +} + namespace llvm { + class Function; class LLVMContext; class Module; } @@ -96,6 +102,10 @@ class CompilationUnit { mem_usage_ += usage; } + void RegisterCompiledMethod(const llvm::Function* func, CompiledMethod* cm); + + void UpdateFrameSizeInBytes(const llvm::Function* func, size_t frame_size_in_bytes); + private: InstructionSet insn_set_; const size_t elf_idx_; @@ -108,6 +118,8 @@ class CompilationUnit { std::string elf_image_; std::string bitcode_filename_; + SafeMap<const llvm::Function*, CompiledMethod*> compiled_methods_map_; + size_t mem_usage_; uint16_t num_elf_funcs_; }; diff --git a/src/compiler_llvm/jni_compiler.cc b/src/compiler_llvm/jni_compiler.cc index 68ce2d88b5..b35d7929a3 100644 --- a/src/compiler_llvm/jni_compiler.cc +++ b/src/compiler_llvm/jni_compiler.cc @@ -293,9 +293,14 @@ CompiledMethod* JniCompiler::Compile() { // Verify the generated bitcode llvm::verifyFunction(*func_, llvm::PrintMessageAction); - return new CompiledMethod(cunit_->GetInstructionSet(), - cunit_->GetElfIndex(), - elf_func_idx_); + CompiledMethod* compiled_method = + new CompiledMethod(cunit_->GetInstructionSet(), + cunit_->GetElfIndex(), + elf_func_idx_); + + cunit_->RegisterCompiledMethod(func_, compiled_method); + + return compiled_method; } diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc index fc9c4d8c4f..153d99a93b 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc @@ -3681,9 +3681,14 @@ CompiledMethod *MethodCompiler::Compile() { // Dex file. Besides, we have to convert the code unit into bytes. // Thus, we got our magic number 9. - return new CompiledMethod(cunit_->GetInstructionSet(), - cunit_->GetElfIndex(), - elf_func_idx_); + CompiledMethod* compiled_method = + new CompiledMethod(cunit_->GetInstructionSet(), + cunit_->GetElfIndex(), + elf_func_idx_); + + cunit_->RegisterCompiledMethod(func_, compiled_method); + + return compiled_method; } diff --git a/src/oat_writer.cc b/src/oat_writer.cc index 2ccf2075d8..4d11237946 100644 --- a/src/oat_writer.cc +++ b/src/oat_writer.cc @@ -277,6 +277,7 @@ size_t OatWriter::InitOatCodeMethod(size_t offset, size_t oat_class_index, if (compiled_method->IsExecutableInElf()) { code_elf_idx = compiled_method->GetElfIndex(); code_elf_func_idx = compiled_method->GetElfFuncIndex(); + frame_size_in_bytes = compiled_method->GetFrameSizeInBytes(); } else { offset = compiled_method->AlignCode(offset); DCHECK_ALIGNED(offset, kArmAlignment); diff --git a/src/object.h b/src/object.h index 00492f0c49..5e67f625db 100644 --- a/src/object.h +++ b/src/object.h @@ -798,9 +798,7 @@ class MANAGED Method : public Object { size_t GetFrameSizeInBytes() const { DCHECK_EQ(sizeof(size_t), sizeof(uint32_t)); size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(Method, frame_size_in_bytes_), false); -#if !defined(ART_USE_LLVM_COMPILER) // LLVM uses shadow stack instead. DCHECK_LE(static_cast<size_t>(kStackAlignment), result); -#endif return result; } |