OSDN Git Service

resolved conflicts for merge of e9bc7372 to lmp-dev-plus-aosp
authorAndreas Gampe <agampe@google.com>
Fri, 12 Sep 2014 22:50:37 +0000 (15:50 -0700)
committerAndreas Gampe <agampe@google.com>
Fri, 12 Sep 2014 23:14:42 +0000 (16:14 -0700)
Change-Id: I952793dc6c7d17b31a011b4525e76c7b64299491

1  2 
compiler/driver/compiler_driver.cc
compiler/oat_writer.cc
oatdump/oatdump.cc
runtime/class_linker.cc
runtime/dex_file.h
runtime/verifier/method_verifier.cc

Simple merge
@@@ -434,15 -457,13 +434,15 @@@ class OatWriter::InitCodeMethodVisitor 
          } else {
            status = mirror::Class::kStatusNotReady;
          }
 -        const std::vector<uint8_t>& gc_map = compiled_method->GetGcMap();
 -        size_t gc_map_size = gc_map.size() * sizeof(gc_map[0]);
 -        bool is_native = it.MemberIsNative();
 -        CHECK(gc_map_size != 0 || is_native || status < mirror::Class::kStatusVerified)
 -            << &gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " "
 -            << (status < mirror::Class::kStatusVerified) << " " << status << " "
 -            << PrettyMethod(it.GetMemberIndex(), *dex_file_);
 +        std::vector<uint8_t> const * gc_map = compiled_method->GetGcMap();
 +        if (gc_map != nullptr) {
 +          size_t gc_map_size = gc_map->size() * sizeof(gc_map[0]);
-           bool is_native = (it.GetMemberAccessFlags() & kAccNative) != 0;
++          bool is_native = it.MemberIsNative();
 +          CHECK(gc_map_size != 0 || is_native || status < mirror::Class::kStatusVerified)
 +              << gc_map << " " << gc_map_size << " " << (is_native ? "true" : "false") << " "
 +              << (status < mirror::Class::kStatusVerified) << " " << status << " "
 +              << PrettyMethod(it.GetMemberIndex(), *dex_file_);
 +        }
        }
  
        DCHECK_LT(method_offsets_index_, oat_class->method_offsets_.size());
@@@ -108,224 -105,6 +108,224 @@@ const char* image_roots_descriptions_[
    "kClassRoots",
  };
  
-                     it.GetMethodCodeItem(), it.GetMemberAccessFlags(), callback);
 +class OatSymbolizer : public CodeOutput {
 + public:
 +  explicit OatSymbolizer(const OatFile* oat_file, std::string& output_name) :
 +      oat_file_(oat_file), builder_(nullptr), elf_output_(nullptr), output_name_(output_name) {}
 +
 +  bool Init() {
 +    Elf32_Word oat_data_size = oat_file_->GetOatHeader().GetExecutableOffset();
 +
 +    uint32_t diff = static_cast<uint32_t>(oat_file_->End() - oat_file_->Begin());
 +    uint32_t oat_exec_size = diff - oat_data_size;
 +
 +    if (output_name_.empty()) {
 +      output_name_ = "symbolized.oat";
 +    }
 +    elf_output_ = OS::CreateEmptyFile(output_name_.c_str());
 +
 +    builder_.reset(new ElfBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
 +                                  Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>(
 +        this,
 +        elf_output_,
 +        oat_file_->GetOatHeader().GetInstructionSet(),
 +        0,
 +        oat_data_size,
 +        oat_data_size,
 +        oat_exec_size,
 +        true,
 +        false));
 +
 +    if (!builder_->Init()) {
 +      builder_.reset(nullptr);
 +      return false;
 +    }
 +
 +    return true;
 +  }
 +
 +  typedef void (OatSymbolizer::*Callback)(const DexFile::ClassDef&,
 +                                          uint32_t,
 +                                          const OatFile::OatMethod&,
 +                                          const DexFile&,
 +                                          uint32_t,
 +                                          const DexFile::CodeItem*,
 +                                          uint32_t);
 +
 +  bool Symbolize() {
 +    if (builder_.get() == nullptr) {
 +      return false;
 +    }
 +
 +    Walk(&art::OatSymbolizer::RegisterForDedup);
 +
 +    NormalizeState();
 +
 +    Walk(&art::OatSymbolizer::AddSymbol);
 +
 +    bool result = builder_->Write();
 +
 +    elf_output_->Flush();
 +    elf_output_->Close();
 +
 +    return result;
 +  }
 +
 +  void Walk(Callback callback) {
 +    std::vector<const OatFile::OatDexFile*> oat_dex_files = oat_file_->GetOatDexFiles();
 +    for (size_t i = 0; i < oat_dex_files.size(); i++) {
 +      const OatFile::OatDexFile* oat_dex_file = oat_dex_files[i];
 +      CHECK(oat_dex_file != NULL);
 +      WalkOatDexFile(oat_dex_file, callback);
 +    }
 +  }
 +
 +  void WalkOatDexFile(const OatFile::OatDexFile* oat_dex_file, Callback callback) {
 +    std::string error_msg;
 +    std::unique_ptr<const DexFile> dex_file(oat_dex_file->OpenDexFile(&error_msg));
 +    if (dex_file.get() == nullptr) {
 +      return;
 +    }
 +    for (size_t class_def_index = 0;
 +        class_def_index < dex_file->NumClassDefs();
 +        class_def_index++) {
 +      const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index);
 +      const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(class_def_index);
 +      OatClassType type = oat_class.GetType();
 +      switch (type) {
 +        case kOatClassAllCompiled:
 +        case kOatClassSomeCompiled:
 +          WalkOatClass(oat_class, *dex_file.get(), class_def, callback);
 +          break;
 +
 +        case kOatClassNoneCompiled:
 +        case kOatClassMax:
 +          // Ignore.
 +          break;
 +      }
 +    }
 +  }
 +
 +  void WalkOatClass(const OatFile::OatClass& oat_class, const DexFile& dex_file,
 +                    const DexFile::ClassDef& class_def, Callback callback) {
 +    const byte* class_data = dex_file.GetClassData(class_def);
 +    if (class_data == nullptr) {  // empty class such as a marker interface?
 +      return;
 +    }
 +    // Note: even if this is an interface or a native class, we still have to walk it, as there
 +    //       might be a static initializer.
 +    ClassDataItemIterator it(dex_file, class_data);
 +    SkipAllFields(&it);
 +    uint32_t class_method_idx = 0;
 +    while (it.HasNextDirectMethod()) {
 +      const OatFile::OatMethod oat_method = oat_class.GetOatMethod(class_method_idx);
 +      WalkOatMethod(class_def, class_method_idx, oat_method, dex_file, it.GetMemberIndex(),
-                     it.GetMethodCodeItem(), it.GetMemberAccessFlags(), callback);
++                    it.GetMethodCodeItem(), it.GetMethodAccessFlags(), callback);
 +      class_method_idx++;
 +      it.Next();
 +    }
 +    while (it.HasNextVirtualMethod()) {
 +      const OatFile::OatMethod oat_method = oat_class.GetOatMethod(class_method_idx);
 +      WalkOatMethod(class_def, class_method_idx, oat_method, dex_file, it.GetMemberIndex(),
++                    it.GetMethodCodeItem(), it.GetMethodAccessFlags(), callback);
 +      class_method_idx++;
 +      it.Next();
 +    }
 +    DCHECK(!it.HasNext());
 +  }
 +
 +  void WalkOatMethod(const DexFile::ClassDef& class_def, uint32_t class_method_index,
 +                     const OatFile::OatMethod& oat_method, const DexFile& dex_file,
 +                     uint32_t dex_method_idx, const DexFile::CodeItem* code_item,
 +                     uint32_t method_access_flags, Callback callback) {
 +    if ((method_access_flags & kAccAbstract) != 0) {
 +      // Abstract method, no code.
 +      return;
 +    }
 +    if (oat_method.GetCodeOffset() == 0) {
 +      // No code.
 +      return;
 +    }
 +
 +    (this->*callback)(class_def, class_method_index, oat_method, dex_file, dex_method_idx, code_item,
 +                      method_access_flags);
 +  }
 +
 +  void RegisterForDedup(const DexFile::ClassDef& class_def, uint32_t class_method_index,
 +                        const OatFile::OatMethod& oat_method, const DexFile& dex_file,
 +                        uint32_t dex_method_idx, const DexFile::CodeItem* code_item,
 +                        uint32_t method_access_flags) {
 +    state_[oat_method.GetCodeOffset()]++;
 +  }
 +
 +  void NormalizeState() {
 +    for (auto& x : state_) {
 +      if (x.second == 1) {
 +        state_[x.first] = 0;
 +      }
 +    }
 +  }
 +
 +  enum class DedupState {  // private
 +    kNotDeduplicated,
 +    kDeduplicatedFirst,
 +    kDeduplicatedOther
 +  };
 +  DedupState IsDuplicated(uint32_t offset) {
 +    if (state_[offset] == 0) {
 +      return DedupState::kNotDeduplicated;
 +    }
 +    if (state_[offset] == 1) {
 +      return DedupState::kDeduplicatedOther;
 +    }
 +    state_[offset] = 1;
 +    return DedupState::kDeduplicatedFirst;
 +  }
 +
 +  void AddSymbol(const DexFile::ClassDef& class_def, uint32_t class_method_index,
 +                 const OatFile::OatMethod& oat_method, const DexFile& dex_file,
 +                 uint32_t dex_method_idx, const DexFile::CodeItem* code_item,
 +                 uint32_t method_access_flags) {
 +    DedupState dedup = IsDuplicated(oat_method.GetCodeOffset());
 +    if (dedup != DedupState::kDeduplicatedOther) {
 +      std::string pretty_name = PrettyMethod(dex_method_idx, dex_file, true);
 +
 +      if (dedup == DedupState::kDeduplicatedFirst) {
 +        pretty_name = "[Dedup]" + pretty_name;
 +      }
 +
 +      ElfSymtabBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr,
 +      Elf32_Sym, Elf32_Shdr>* symtab = &builder_->symtab_builder_;
 +
 +      symtab->AddSymbol(pretty_name, &builder_->text_builder_, oat_method.GetCodeOffset() -
 +                        oat_file_->GetOatHeader().GetExecutableOffset(), true,
 +                        oat_method.GetQuickCodeSize(), STB_GLOBAL, STT_FUNC);
 +    }
 +  }
 +
 +  // Write oat code. Required by ElfBuilder/CodeOutput.
 +  bool Write(OutputStream* out) {
 +    return out->WriteFully(oat_file_->Begin(), oat_file_->End() - oat_file_->Begin());
 +  }
 +
 + private:
 +  static void SkipAllFields(ClassDataItemIterator* it) {
 +    while (it->HasNextStaticField()) {
 +      it->Next();
 +    }
 +    while (it->HasNextInstanceField()) {
 +      it->Next();
 +    }
 +  }
 +
 +  const OatFile* oat_file_;
 +  std::unique_ptr<ElfBuilder<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn,
 +                              Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr> > builder_;
 +  File* elf_output_;
 +  std::unordered_map<uint32_t, uint32_t> state_;
 +  std::string output_name_;
 +};
 +
  class OatDumper {
   public:
    explicit OatDumper(const OatFile& oat_file, bool dump_raw_mapping_table, bool dump_raw_gc_map)
Simple merge
Simple merge
@@@ -170,8 -167,8 +170,8 @@@ MethodVerifier::FailureKind MethodVerif
                                                        class_loader,
                                                        class_def,
                                                        it.GetMethodCodeItem(),
 -                                                      method,
 +                                                      h_method,
-                                                       it.GetMemberAccessFlags(),
+                                                       it.GetMethodAccessFlags(),
                                                        allow_soft_failures,
                                                        false);
      if (result != kNoFailure) {
                                                        class_loader,
                                                        class_def,
                                                        it.GetMethodCodeItem(),
 -                                                      method,
 +                                                      h_method,
-                                                       it.GetMemberAccessFlags(),
+                                                       it.GetMethodAccessFlags(),
                                                        allow_soft_failures,
                                                        false);
      if (result != kNoFailure) {