oatdump.cc revision d5b32607798a46a905ba2d8d5bf7507cc970aa58
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 1678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 1778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom#include <stdio.h> 1878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom#include <stdlib.h> 1978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 2027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include <fstream> 2127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom#include <iostream> 22e5448b5a12003b405b22cde3b94f962ab4888a87Elliott Hughes#include <map> 2378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom#include <string> 2478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom#include <vector> 2578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 2678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom#include "class_linker.h" 27916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom#include "file.h" 2878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom#include "image.h" 296d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h" 30e5448b5a12003b405b22cde3b94f962ab4888a87Elliott Hughes#include "os.h" 3178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom#include "runtime.h" 3278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom#include "space.h" 3378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom#include "stringpiece.h" 3478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 3578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstromnamespace art { 3678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 3778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstromstatic void usage() { 3878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom fprintf(stderr, 3978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom "Usage: oatdump [options] ...\n" 4029e7ac74a3f9aec192099fec381baadaa55730adBrian Carlstrom " Example: oatdump --image=$ANDROID_PRODUCT_OUT/system/framework/boot.art --host-prefix=$ANDROID_PRODUCT_OUT\n" 4129e7ac74a3f9aec192099fec381baadaa55730adBrian Carlstrom " Example: adb shell oatdump --image=/system/framework/boot.art\n" 4278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom "\n"); 4378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom fprintf(stderr, 44a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom " --oat-file=<file.oat>: specifies an input oat filename.\n" 4529e7ac74a3f9aec192099fec381baadaa55730adBrian Carlstrom " Example: --image=/system/framework/boot.oat\n" 46aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom "\n"); 47aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom fprintf(stderr, 48aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom " --image=<file.art>: specifies an input image filename.\n" 4929e7ac74a3f9aec192099fec381baadaa55730adBrian Carlstrom " Example: --image=/system/framework/boot.art\n" 50e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "\n"); 5178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom fprintf(stderr, 52e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom " --boot-image=<file.art>: provide the image file for the boot class path.\n" 5329e7ac74a3f9aec192099fec381baadaa55730adBrian Carlstrom " Example: --boot-image=/system/framework/boot.art\n" 54e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "\n"); 55e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom fprintf(stderr, 5658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " --host-prefix may be used to translate host paths to target paths during\n" 5758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " cross compilation.\n" 5858ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom " Example: --host-prefix=out/target/product/crespo\n" 5978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom "\n"); 6027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom fprintf(stderr, 6127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom " --output=<file> may be used to send the output to a file.\n" 6227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom " Example: --output=/tmp/oatdump.txt\n" 6327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom "\n"); 6478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom exit(EXIT_FAILURE); 6578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom} 6678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 67ff1ed4770bf7ff024a807b9f909b1a26abb78341Ian Rogersconst char* image_roots_descriptions_[] = { 6878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom "kJniStubArray", 69e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "kAbstractMethodErrorStubArray", 70ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers "kInstanceResolutionStubArray", 71ad25ac568407ceb14334e8551dd1c4dd0fd6993cIan Rogers "kStaticResolutionStubArray", 721cb0a1dfc32531c79a968aeac26ccb5525862497Ian Rogers "kUnknownMethodResolutionStubArray", 73e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "kCalleeSaveMethod", 74aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom "kRefsOnlySaveMethod", 75aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom "kRefsAndArgsSaveMethod", 76e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom "kOatLocation", 7758ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom "kDexCaches", 7834f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom "kClassRoots", 7978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom}; 8078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 8127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstromclass OatDump { 82aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom public: 83aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom static void Dump(const std::string& oat_filename, 84aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom std::ostream& os, 85aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatFile& oat_file) { 86aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatHeader& oat_header = oat_file.GetOatHeader(); 87aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 88aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "MAGIC:\n"; 89aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << oat_header.GetMagic() << "\n\n"; 90aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 91aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "CHECKSUM:\n"; 92aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("%08x\n\n", oat_header.GetChecksum()); 93aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 94aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "DEX FILE COUNT:\n"; 95aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << oat_header.GetDexFileCount() << "\n\n"; 96aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 97aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "EXECUTABLE OFFSET:\n"; 98aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("%08x\n\n", oat_header.GetExecutableOffset()); 99aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 10030fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << "BEGIN:\n"; 10130fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << reinterpret_cast<const void*>(oat_file.Begin()) << "\n\n"; 102aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 10330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << "END:\n"; 10430fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << reinterpret_cast<const void*>(oat_file.End()) << "\n\n"; 105aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 106aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << std::flush; 107aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 108ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes std::vector<const OatFile::OatDexFile*> oat_dex_files = oat_file.GetOatDexFiles(); 109aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom for (size_t i = 0; i < oat_dex_files.size(); i++) { 110aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatFile::OatDexFile* oat_dex_file = oat_dex_files[i]; 111aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CHECK(oat_dex_file != NULL); 112a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom DumpOatDexFile(os, oat_file, *oat_dex_file); 113aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 114aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 115aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 116aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom private: 117a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom static void DumpOatDexFile(std::ostream& os, 118aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatFile& oat_file, 119aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatFile::OatDexFile& oat_dex_file) { 120aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "OAT DEX FILE:\n"; 121a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom os << StringPrintf("location: %s\n", oat_dex_file.GetDexFileLocation().c_str()); 1225b332c89fa3fdd7dc184b22c2587d28af304d019Brian Carlstrom os << StringPrintf("checksum: %08x\n", oat_dex_file.GetDexFileLocationChecksum()); 123a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom UniquePtr<const DexFile> dex_file(oat_dex_file.OpenDexFile()); 124a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom if (dex_file.get() == NULL) { 125aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "NOT FOUND\n\n"; 126aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return; 127aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 128aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom for (size_t class_def_index = 0; class_def_index < dex_file->NumClassDefs(); class_def_index++) { 129aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_index); 130aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const char* descriptor = dex_file->GetClassDescriptor(class_def); 131aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom UniquePtr<const OatFile::OatClass> oat_class(oat_dex_file.GetOatClass(class_def_index)); 132aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom CHECK(oat_class.get() != NULL); 133ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("%zd: %s (type_idx=%d) (", class_def_index, descriptor, class_def.class_idx_) 134e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom << oat_class->GetStatus() << ")\n"; 135a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom DumpOatClass(os, oat_file, *oat_class.get(), *(dex_file.get()), class_def); 136aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 137aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 138aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << std::flush; 139aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 140aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 141aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom static void DumpOatClass(std::ostream& os, 142aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatFile& oat_file, 143aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatFile::OatClass& oat_class, 144aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile& dex_file, 145aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile::ClassDef& class_def) { 146aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const byte* class_data = dex_file.GetClassData(class_def); 1470571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers if (class_data == NULL) { // empty class such as a marker interface? 1480571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers return; 1490571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers } 1500571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers ClassDataItemIterator it(dex_file, class_data); 151aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 152aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom // just skipping through the fields to advance class_data 1530571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextStaticField()) { 1540571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 155aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 1560571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextInstanceField()) { 1570571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 158aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 159aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 1600571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_index = 0; 1610571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextDirectMethod()) { 1620571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const OatFile::OatMethod oat_method = oat_class.GetOatMethod(method_index); 1630571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DumpOatMethod(os, method_index, oat_file, oat_method, dex_file, it.GetMemberIndex()); 1640571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method_index++; 1650571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 166aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 1670571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers while (it.HasNextVirtualMethod()) { 1680571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const OatFile::OatMethod oat_method = oat_class.GetOatMethod(method_index); 1690571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DumpOatMethod(os, method_index, oat_file, oat_method, dex_file, it.GetMemberIndex()); 1700571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method_index++; 1710571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers it.Next(); 172aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 1730571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers DCHECK(!it.HasNext()); 174aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << std::flush; 175aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 176aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom static void DumpOatMethod(std::ostream& os, 177aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom uint32_t method_index, 178aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatFile& oat_file, 179aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const OatFile::OatMethod& oat_method, 180aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const DexFile& dex_file, 1810571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers uint32_t method_idx) { 1820571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers const DexFile::MethodId& method_id = dex_file.GetMethodId(method_idx); 183aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const char* name = dex_file.GetMethodName(method_id); 184955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string signature(dex_file.GetMethodSignature(method_id)); 185aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("\t%d: %s %s (method_idx=%d)\n", 1860571d357843c53e042f370f5f2c2e9aa3fe803a9Ian Rogers method_index, name, signature.c_str(), method_idx); 187aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("\t\tcode: %p (offset=%08x)\n", 188ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_method.GetCode(), oat_method.GetCodeOffset()); 189ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\t\tframe_size_in_bytes: %zd\n", 190ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_method.GetFrameSizeInBytes()); 191aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("\t\tcore_spill_mask: %08x\n", 192ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_method.GetCoreSpillMask()); 193aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("\t\tfp_spill_mask: %08x\n", 194ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_method.GetFpSpillMask()); 195aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("\t\tmapping_table: %p (offset=%08x)\n", 196ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_method.GetMappingTable(), oat_method.GetMappingTableOffset()); 197aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("\t\tvmap_table: %p (offset=%08x)\n", 198ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_method.GetVmapTable(), oat_method.GetVmapTableOffset()); 199e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom os << StringPrintf("\t\tgc_map: %p (offset=%08x)\n", 200e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom oat_method.GetGcMap(), oat_method.GetGcMapOffset()); 201aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("\t\tinvoke_stub: %p (offset=%08x)\n", 202ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom oat_method.GetInvokeStub(), oat_method.GetInvokeStubOffset()); 203aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 204aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom}; 205aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 206aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstromclass ImageDump { 20727ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom public: 208916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom static void Dump(const std::string& image_filename, 209aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const std::string& host_prefix, 210916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom std::ostream& os, 211916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom Space& image_space, 212916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom const ImageHeader& image_header) { 21327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom os << "MAGIC:\n"; 21427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom os << image_header.GetMagic() << "\n\n"; 21527ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom 21630fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << "IMAGE BEGIN:\n"; 21730fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << reinterpret_cast<void*>(image_header.GetImageBegin()) << "\n\n"; 218e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom 219aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "OAT CHECKSUM:\n"; 220aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << StringPrintf("%08x\n\n", image_header.GetOatChecksum()); 221aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 22230fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << "OAT BEGIN:\n"; 22330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << reinterpret_cast<void*>(image_header.GetOatBegin()) << "\n\n"; 224916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 22530fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << "OAT END:\n"; 22630fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers os << reinterpret_cast<void*>(image_header.GetOatEnd()) << "\n\n"; 227aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 22827ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom os << "ROOTS:\n"; 229aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << reinterpret_cast<void*>(image_header.GetImageRoots()) << "\n"; 230418d20fc407052d4152157f61e7453359f902383Elliott Hughes CHECK_EQ(arraysize(image_roots_descriptions_), size_t(ImageHeader::kImageRootsMax)); 23127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom for (int i = 0; i < ImageHeader::kImageRootsMax; i++) { 23227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom ImageHeader::ImageRoot image_root = static_cast<ImageHeader::ImageRoot>(i); 23334f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom const char* image_root_description = image_roots_descriptions_[i]; 23434f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom Object* image_root_object = image_header.GetImageRoot(image_root); 23534f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom os << StringPrintf("%s: %p\n", image_root_description, image_root_object); 23634f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom if (image_root_object->IsObjectArray()) { 23734f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom // TODO: replace down_cast with AsObjectArray (g++ currently has a problem with this) 23834f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom ObjectArray<Object>* image_root_object_array 23934f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom = down_cast<ObjectArray<Object>*>(image_root_object); 24034f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom // = image_root_object->AsObjectArray<Object>(); 24134f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom for (int i = 0; i < image_root_object_array->GetLength(); i++) { 242d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Object* value = image_root_object_array->Get(i); 243d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (value != NULL) { 244d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers os << "\t" << i << ": "; 245d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers std::string summary; 246d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers PrettyObjectValue(summary, value->GetClass(), value); 247d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers os << summary; 248d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else { 249d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers os << StringPrintf("\t%d: null\n", i); 250d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 25134f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom } 25234f426c49ac2de8cea70acef6b9ecdd8e62209d2Brian Carlstrom } 25327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 25427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom os << "\n"; 25527ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom 25627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom os << "OBJECTS:\n" << std::flush; 257aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom ImageDump state(image_space, os); 25827ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom HeapBitmap* heap_bitmap = Heap::GetLiveBits(); 25927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom DCHECK(heap_bitmap != NULL); 260aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom heap_bitmap->Walk(ImageDump::Callback, &state); 261916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "\n"; 262916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 263916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "STATS:\n" << std::flush; 264916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom UniquePtr<File> file(OS::OpenFile(image_filename.c_str(), false)); 265916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom state.stats_.file_bytes = file->Length(); 266e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t header_bytes = sizeof(ImageHeader); 267e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom state.stats_.header_bytes = header_bytes; 268e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom size_t alignment_bytes = RoundUp(header_bytes, kObjectAlignment) - header_bytes; 269e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom state.stats_.alignment_bytes += alignment_bytes; 270916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom state.stats_.Dump(os); 271aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "\n"; 272916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 273916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << std::flush; 274aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 275aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "OAT LOCATION:\n" << std::flush; 276aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom Object* oat_location_object = image_header.GetImageRoot(ImageHeader::kOatLocation); 277955724179c6c739524f610023287f56b24dc31deElliott Hughes std::string oat_location(oat_location_object->AsString()->ToModifiedUtf8()); 278aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 279aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << oat_location; 280aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (!host_prefix.empty()) { 281aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom oat_location = host_prefix + oat_location; 282b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom os << " (" << oat_location << ")"; 283aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 284b7bbba49d88eae58223d9878da4069bf6d7140bfBrian Carlstrom os << "\n"; 285ae826983f7903bc0a6bbbe8426bf393fb2f6d747Brian Carlstrom const OatFile* oat_file = class_linker->FindOatFileFromOatLocation(oat_location); 286aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (oat_file == NULL) { 287aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "NOT FOUND\n"; 288aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << std::flush; 289aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return; 290aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 291aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << "\n"; 292aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom os << std::flush; 293aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 294a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom OatDump::Dump(oat_location, os, *oat_file); 29578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 29678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 29727ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom private: 29827ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom 299aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom ImageDump(const Space& dump_space, std::ostream& os) : dump_space_(dump_space), os_(os) {} 300d1bb4f6b7c8dda429f61937cd42f3a0b7367c271Elliott Hughes 301aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom ~ImageDump() {} 30227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom 303d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers static void PrettyObjectValue(std::string& summary, Class* type, Object* value) { 304d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers CHECK(type != NULL); 305d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (value == NULL) { 306d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "null %s\n", PrettyDescriptor(type).c_str()); 307d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (type->IsStringClass()) { 308d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers String* string = value->AsString(); 309d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p String: \"%s\"\n", string, string->ToModifiedUtf8().c_str()); 310d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (value->IsClass()) { 311d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Class* klass = value->AsClass(); 312d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p Class: %s\n", klass, PrettyDescriptor(klass).c_str()); 313d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (value->IsField()) { 314d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Field* field = value->AsField(); 315d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p Field: %s\n", field, PrettyField(field).c_str()); 316d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (value->IsMethod()) { 317d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Method* method = value->AsMethod(); 318d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p Method: %s\n", method, PrettyMethod(method).c_str()); 319d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else { 320d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p %s\n", value, PrettyDescriptor(type).c_str()); 321d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 322d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 323d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers 324d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers static void PrintField(std::string& summary, Field* field, Object* obj) { 325d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers FieldHelper fh(field); 326d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Class* type = fh.GetType(); 327d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "\t%s: ", fh.GetName()); 328d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (type->IsPrimitiveLong()) { 329d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%lld (0x%llx)\n", field->Get64(obj), field->Get64(obj)); 330d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (type->IsPrimitiveDouble()) { 331d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%f (%a)\n", field->GetDouble(obj), field->GetDouble(obj)); 332d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (type->IsPrimitiveFloat()) { 333d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%f (%a)\n", field->GetFloat(obj), field->GetFloat(obj)); 334d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (type->IsPrimitive()){ 335d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%d (0x%x)\n", field->Get32(obj), field->Get32(obj)); 336d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else { 337d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Object* value = field->GetObj(obj); 338d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers PrettyObjectValue(summary, type, value); 339d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 340d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 341d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers 342d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers static void DumpFields(std::string& summary, Object* obj, Class* klass) { 343d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Class* super = klass->GetSuperClass(); 344d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (super != NULL) { 345d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers DumpFields(summary, obj, super); 346d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 347d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers ObjectArray<Field>* fields = klass->GetIFields(); 348d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (fields != NULL) { 349d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers for (int32_t i = 0; i < fields->GetLength(); i++) { 350d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Field* field = fields->Get(i); 351d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers PrintField(summary, field, obj); 352d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 353d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 354d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 355d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers 35678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom static void Callback(Object* obj, void* arg) { 35778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom DCHECK(obj != NULL); 35878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom DCHECK(arg != NULL); 359aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom ImageDump* state = reinterpret_cast<ImageDump*>(arg); 36078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (!state->InDumpSpace(obj)) { 36178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom return; 36278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 363916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 364916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t object_bytes = obj->SizeOf(); 365916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t alignment_bytes = RoundUp(object_bytes, kObjectAlignment) - object_bytes; 366916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom state->stats_.object_bytes += object_bytes; 367916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom state->stats_.alignment_bytes += alignment_bytes; 368916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 36978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom std::string summary; 370d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Class* obj_class = obj->GetClass(); 371d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (obj_class->IsArrayClass()) { 372d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p: %s length:%d\n", obj, PrettyDescriptor(obj_class).c_str(), 373d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers obj->AsArray()->GetLength()); 374d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (obj->IsClass()) { 37578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom Class* klass = obj->AsClass(); 376d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p: java.lang.Class \"%s\" (", obj, 377d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers PrettyDescriptor(klass).c_str()); 3783b6baaa203fa63f1522b2172a1645f90412afdaeElliott Hughes std::ostringstream ss; 379d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers ss << klass->GetStatus() << ")\n"; 380e10b6974d54f38001aee7bec518d45a7d4fb64c1Brian Carlstrom summary += ss.str(); 38178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } else if (obj->IsField()) { 382d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p: java.lang.reflect.Field %s\n", obj, 383d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers PrettyField(obj->AsField()).c_str()); 384d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (obj->IsMethod()) { 385d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p: java.lang.reflect.Method %s\n", obj, 386d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers PrettyMethod(obj->AsMethod()).c_str()); 387d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (obj_class->IsStringClass()) { 388d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p: java.lang.String \"%s\"\n", obj, 389d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers obj->AsString()->ToModifiedUtf8().c_str()); 39078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } else { 391d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "%p: %s\n", obj, PrettyDescriptor(obj_class).c_str()); 39278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 393d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers DumpFields(summary, obj, obj_class); 394d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (obj->IsObjectArray()) { 395d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers ObjectArray<Object>* obj_array = obj->AsObjectArray<Object>(); 396d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers int32_t length = obj_array->GetLength(); 397d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers for (int32_t i = 0; i < length; i++) { 398d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Object* value = obj_array->Get(i); 399d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers size_t run = 0; 400d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers for (int32_t j = i + 1; j < length; j++) { 401d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (value == obj_array->Get(j)) { 402d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers run++; 403d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else { 404d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers break; 405d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 406d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 407d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (run == 0) { 408d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "\t%d: ", i); 40978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } else { 410d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "\t%d to %d: ", i, i + run); 411d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers i = i + run; 41278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 413d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Class* value_class = value == NULL ? obj_class->GetComponentType() : value->GetClass(); 414d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers PrettyObjectValue(summary, value_class, value); 415d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 416d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (obj->IsClass()) { 417d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers ObjectArray<Field>* sfields = obj->AsClass()->GetSFields(); 418d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (sfields != NULL) { 419d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers summary += "\t\tSTATICS:\n"; 420d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers for (int32_t i = 0; i < sfields->GetLength(); i++) { 421d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Field* field = sfields->Get(i); 422d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers PrintField(summary, field, NULL); 423d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 424d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } 425d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (obj->IsMethod()) { 426d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers Method* method = obj->AsMethod(); 427d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers if (method->IsNative()) { 428d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers DCHECK(method->GetGcMap() == NULL) << PrettyMethod(method); 429e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom DCHECK_EQ(0U, method->GetGcMapLength()) << PrettyMethod(method); 4303320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK(method->GetMappingTable() == NULL) << PrettyMethod(method); 431d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers } else if (method->IsAbstract() || method->IsCalleeSaveMethod()) { 432d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers DCHECK(method->GetGcMap() == NULL) << PrettyMethod(method); 433e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom DCHECK_EQ(0U, method->GetGcMapLength()) << PrettyMethod(method); 4343320cf46afd082398aa401b246e6f301cebdf64dBrian Carlstrom DCHECK(method->GetMappingTable() == NULL) << PrettyMethod(method); 435916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom } else { 436e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom DCHECK(method->GetGcMap() != NULL) << PrettyMethod(method); 437e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom DCHECK_NE(0U, method->GetGcMapLength()) << PrettyMethod(method); 438916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 439e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom size_t register_map_bytes = method->GetGcMapLength(); 440e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom state->stats_.register_map_bytes += register_map_bytes; 441e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 442e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom size_t pc_mapping_table_bytes = method->GetMappingTableLength(); 443e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom state->stats_.pc_mapping_table_bytes += pc_mapping_table_bytes; 444916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 4456d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers const DexFile::CodeItem* code_item = MethodHelper(method).GetCodeItem(); 446d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers size_t dex_instruction_bytes = code_item->insns_size_in_code_units_ * 2; 447916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom state->stats_.dex_instruction_bytes += dex_instruction_bytes; 448e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom 449d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers StringAppendF(&summary, "\t\tSIZE: Dex Instructions=%zd GC=%zd Mapping=%zd\n", 450e7d856b911222aa000ca2be0f8f63f5b292141c3Brian Carlstrom dex_instruction_bytes, register_map_bytes, pc_mapping_table_bytes); 45178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 45278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 453d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers std::string descriptor(ClassHelper(obj_class).GetDescriptor()); 454d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers state->stats_.descriptor_to_bytes[descriptor] += object_bytes; 455d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers state->stats_.descriptor_to_count[descriptor] += 1; 456d5b32607798a46a905ba2d8d5bf7507cc970aa58Ian Rogers 45727ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom state->os_ << summary << std::flush; 45878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 45927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom 46027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom bool InDumpSpace(const Object* object) { 46130fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers return dump_space_.Contains(object); 46227ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 463916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 464916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom public: 465916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom struct Stats { 466916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t file_bytes; 467916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 468916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t header_bytes; 469916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t object_bytes; 470916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t alignment_bytes; 471916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 472916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t managed_code_bytes; 473916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t managed_to_native_code_bytes; 474916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t native_to_managed_code_bytes; 475916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 476916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t register_map_bytes; 477916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t pc_mapping_table_bytes; 478916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 479916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t dex_instruction_bytes; 480916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 481916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom Stats() 482916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom : file_bytes(0), 483916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom header_bytes(0), 484916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom object_bytes(0), 485916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom alignment_bytes(0), 486916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom managed_code_bytes(0), 487916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom managed_to_native_code_bytes(0), 488916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom native_to_managed_code_bytes(0), 489916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom register_map_bytes(0), 490916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom pc_mapping_table_bytes(0), 491916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom dex_instruction_bytes(0) {} 492916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 493e5448b5a12003b405b22cde3b94f962ab4888a87Elliott Hughes typedef std::map<std::string, size_t> TableBytes; 494916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom TableBytes descriptor_to_bytes; 495916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 496e5448b5a12003b405b22cde3b94f962ab4888a87Elliott Hughes typedef std::map<std::string, size_t> TableCount; 497916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom TableCount descriptor_to_count; 498916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 499916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom double PercentOfFileBytes(size_t size) { 500916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom return (static_cast<double>(size) / static_cast<double>(file_bytes)) * 100; 501916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom } 502916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 503916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom double PercentOfObjectBytes(size_t size) { 504916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom return (static_cast<double>(size) / static_cast<double>(object_bytes)) * 100; 505916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom } 506916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 507916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom void Dump(std::ostream& os) { 508ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\tfile_bytes = %zd\n", file_bytes); 509916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "\n"; 510916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 511916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "\tfile_bytes = header_bytes + object_bytes + alignment_bytes\n"; 512ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\theader_bytes = %10zd (%2.0f%% of file_bytes)\n", 513916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom header_bytes, PercentOfFileBytes(header_bytes)); 514ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\tobject_bytes = %10zd (%2.0f%% of file_bytes)\n", 515916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom object_bytes, PercentOfFileBytes(object_bytes)); 516ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\talignment_bytes = %10zd (%2.0f%% of file_bytes)\n", 517916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom alignment_bytes, PercentOfFileBytes(alignment_bytes)); 518916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "\n"; 519916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << std::flush; 520916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom CHECK_EQ(file_bytes, header_bytes + object_bytes + alignment_bytes); 521916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 522916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "\tobject_bytes = sum of descriptor_to_bytes values below:\n"; 523916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t object_bytes_total = 0; 524916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom typedef TableBytes::const_iterator It; // TODO: C++0x auto 525916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom for (It it = descriptor_to_bytes.begin(), end = descriptor_to_bytes.end(); it != end; ++it) { 526955724179c6c739524f610023287f56b24dc31deElliott Hughes const std::string& descriptor(it->first); 527916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t bytes = it->second; 528916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom size_t count = descriptor_to_count[descriptor]; 529916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom double average = static_cast<double>(bytes) / static_cast<double>(count); 530916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom double percent = PercentOfObjectBytes(bytes); 531ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\t%32s %8zd bytes %6zd instances " 532916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom "(%3.0f bytes/instance) %2.0f%% of object_bytes\n", 533916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom descriptor.c_str(), bytes, count, 534916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom average, percent); 535916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 536916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom object_bytes_total += bytes; 537916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom } 538916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "\n"; 539916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << std::flush; 540916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom CHECK_EQ(object_bytes, object_bytes_total); 541916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 542ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\tmanaged_code_bytes = %8zd (%2.0f%% of object_bytes)\n", 543916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom managed_code_bytes, PercentOfObjectBytes(managed_code_bytes)); 544ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\tmanaged_to_native_code_bytes = %8zd (%2.0f%% of object_bytes)\n", 545916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom managed_to_native_code_bytes, 546916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom PercentOfObjectBytes(managed_to_native_code_bytes)); 547ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\tnative_to_managed_code_bytes = %8zd (%2.0f%% of object_bytes)\n", 548916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom native_to_managed_code_bytes, 549916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom PercentOfObjectBytes(native_to_managed_code_bytes)); 550916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "\n"; 551916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << std::flush; 552916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 553ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\tregister_map_bytes = %7zd (%2.0f%% of object_bytes)\n", 554916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom register_map_bytes, PercentOfObjectBytes(register_map_bytes)); 555ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\tpc_mapping_table_bytes = %7zd (%2.0f%% of object_bytes)\n", 556916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom pc_mapping_table_bytes, PercentOfObjectBytes(pc_mapping_table_bytes)); 557916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "\n"; 558916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << std::flush; 559916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 560ad6c9c3dbf7541340f22ccbb333f08556ad7e000Elliott Hughes os << StringPrintf("\tdex_instruction_bytes = %zd\n", dex_instruction_bytes); 561916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << StringPrintf("\tmanaged_code_bytes expansion = %.2f\n", 562916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom static_cast<double>(managed_code_bytes) 563916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom / static_cast<double>(dex_instruction_bytes)); 564916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << "\n"; 565916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom os << std::flush; 566916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom } 567916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom } stats_; 568916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom 569916e74e45b60902af342a71bdbfb806ff29c6c2bBrian Carlstrom private: 57027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom const Space& dump_space_; 57127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom std::ostream& os_; 572d1bb4f6b7c8dda429f61937cd42f3a0b7367c271Elliott Hughes 573aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom DISALLOW_COPY_AND_ASSIGN(ImageDump); 57478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom}; 57578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 57678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstromint oatdump(int argc, char** argv) { 57778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom // Skip over argv[0]. 57878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom argv++; 57978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom argc--; 58078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 58178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (argc == 0) { 582aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom fprintf(stderr, "No arguments specified\n"); 58378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom usage(); 58478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 58578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 586aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom const char* oat_filename = NULL; 58778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom const char* image_filename = NULL; 58878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom const char* boot_image_filename = NULL; 58958ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom std::string host_prefix; 59027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom std::ostream* os = &std::cout; 59127ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom UniquePtr<std::ofstream> out; 59278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 59378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom for (int i = 0; i < argc; i++) { 59478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom const StringPiece option(argv[i]); 595a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom if (option.starts_with("--oat-file=")) { 596a6cc893c4b142cd410fc956963b6f5a014e983adBrian Carlstrom oat_filename = option.substr(strlen("--oat-file=")).data(); 597aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } else if (option.starts_with("--image=")) { 59878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom image_filename = option.substr(strlen("--image=")).data(); 599e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom } else if (option.starts_with("--boot-image=")) { 600e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom boot_image_filename = option.substr(strlen("--boot-image=")).data(); 60158ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } else if (option.starts_with("--host-prefix=")) { 60258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom host_prefix = option.substr(strlen("--host-prefix=")).data(); 60327ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } else if (option.starts_with("--output=")) { 60427ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom const char* filename = option.substr(strlen("--output=")).data(); 60527ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom out.reset(new std::ofstream(filename)); 60627ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom if (!out->good()) { 607aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom fprintf(stderr, "Failed to open output filename %s\n", filename); 60827ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom usage(); 60927ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom } 61027ec961a1da540ba7f16c07a682585ab167317adBrian Carlstrom os = out.get(); 61178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } else { 612aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom fprintf(stderr, "Unknown argument %s\n", option.data()); 61378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom usage(); 61478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 61578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 61678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 617aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (image_filename == NULL && oat_filename == NULL) { 618362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes fprintf(stderr, "Either --image or --oat must be specified\n"); 619362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes return EXIT_FAILURE; 62078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 62178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 622aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (image_filename != NULL && oat_filename != NULL) { 623362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes fprintf(stderr, "Either --image or --oat must be specified but not both\n"); 624362f9bc807169bcfc8761dde067bbfb79b5ad0fdElliott Hughes return EXIT_FAILURE; 625aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 626aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 627aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (oat_filename != NULL) { 628a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom const OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, NULL); 629aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (oat_file == NULL) { 630aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom fprintf(stderr, "Failed to open oat file from %s\n", oat_filename); 631aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return EXIT_FAILURE; 632aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 633a004aa933a58428489e42d77f707c2b063b73747Brian Carlstrom OatDump::Dump(oat_filename, *os, *oat_file); 634aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom return EXIT_SUCCESS; 635aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 636aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom 63778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom Runtime::Options options; 63878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom std::string image_option; 639e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom std::string oat_option; 64078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom std::string boot_image_option; 641e24fa61603a60ade3797e4a0c8b3fccb346cb048Brian Carlstrom std::string boot_oat_option; 64258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom if (boot_image_filename != NULL) { 64358ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_image_option += "-Ximage:"; 64458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom boot_image_option += boot_image_filename; 64558ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom options.push_back(std::make_pair(boot_image_option.c_str(), reinterpret_cast<void*>(NULL))); 64658ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom } 647aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom if (image_filename != NULL) { 648aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_option += "-Ximage:"; 649aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom image_option += image_filename; 650aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom options.push_back(std::make_pair(image_option.c_str(), reinterpret_cast<void*>(NULL))); 651aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom } 65258ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom 65358ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom if (!host_prefix.empty()) { 65458ae9416e197ae68ed12ed43d87407d4dfb15093Brian Carlstrom options.push_back(std::make_pair("host-prefix", host_prefix.c_str())); 65578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 65678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 65778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom UniquePtr<Runtime> runtime(Runtime::Create(options, false)); 65878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (runtime.get() == NULL) { 659aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom fprintf(stderr, "Failed to create runtime\n"); 66078128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom return EXIT_FAILURE; 66178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 66278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 66330fab40ee5a07af6b8c3b6b0e9438071695a57f4Ian Rogers ImageSpace* image_space = Heap::GetSpaces()[Heap::GetSpaces().size()-2]->AsImageSpace(); 66478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom CHECK(image_space != NULL); 66578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom const ImageHeader& image_header = image_space->GetImageHeader(); 66678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom if (!image_header.IsValid()) { 667aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom fprintf(stderr, "Invalid image header %s\n", image_filename); 66878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom return EXIT_FAILURE; 66978128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom } 670aded5f7ab991f3c1132851599d3bc60ff6707eedBrian Carlstrom ImageDump::Dump(image_filename, host_prefix, *os, *image_space, image_header); 67178128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom return EXIT_SUCCESS; 67278128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom} 67378128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 67478128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom} // namespace art 67578128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom 67678128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstromint main(int argc, char** argv) { 67778128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom return art::oatdump(argc, argv); 67878128a63b2615744760b7f8ab83df9764a5d4a95Brian Carlstrom} 679