1c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson/* 2c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * Copyright (C) 2008 The Android Open Source Project 3c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * 4c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * you may not use this file except in compliance with the License. 6c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * You may obtain a copy of the License at 7c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * 8c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * 10c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * Unless required by applicable law or agreed to in writing, software 11c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * See the License for the specific language governing permissions and 14c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * limitations under the License. 15c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson */ 16c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 17c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson/* 18c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * Preparation and completion of hprof data generation. The output is 19c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * written into two files and then combined. This is necessary because 20c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * we generate some of the data (strings and classes) while we dump the 21c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * heap, and some analysis tools require that the class and string data 22c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson * appear first. 23c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson */ 24c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 25c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson#include "hprof.h" 266d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers 27622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <cutils/open_memstream.h> 28622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <errno.h> 29622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <fcntl.h> 30622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <stdio.h> 31622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <string.h> 32622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <sys/time.h> 33622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <sys/uio.h> 34622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <time.h> 35622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <time.h> 36622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <unistd.h> 37622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 38622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include <set> 39622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 40c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier#include "art_field-inl.h" 4107ed66b5ae659c452cbe1ab20c3dbf1d6f546461Elliott Hughes#include "base/logging.h" 42e222ee0b794f941af4fb1b32fb8224e32942ea7bElliott Hughes#include "base/stringprintf.h" 4380afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "base/time_utils.h" 44761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/unix_file/fd_file.h" 456d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "class_linker.h" 4662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "common_throws.h" 47c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson#include "debugger.h" 484f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h" 49e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier#include "gc_root.h" 501d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/accounting/heap_bitmap.h" 518c2ff641294715864013737fdec57cdfd410270cMan Cao#include "gc/allocation_record.h" 521d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/heap.h" 531d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/space/space.h" 54622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include "globals.h" 55ad466adf38db74a9840659626858196091151a64Mathieu Chartier#include "jdwp/jdwp.h" 56ad466adf38db74a9840659626858196091151a64Mathieu Chartier#include "jdwp/jdwp_priv.h" 572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class.h" 582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 592dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 60dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes#include "os.h" 61622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include "safe_map.h" 6200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 63622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include "thread_list.h" 64c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 65c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilsonnamespace art { 66c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 67c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilsonnamespace hprof { 68c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 69ad466adf38db74a9840659626858196091151a64Mathieu Chartierstatic constexpr bool kDirectStream = true; 70622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampestatic constexpr uint32_t kHprofTime = 0; 723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampestatic constexpr uint32_t kHprofNullThread = 0; 733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampestatic constexpr size_t kMaxObjectsPerSegment = 128; 753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampestatic constexpr size_t kMaxBytesPerSegment = 4096; 763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe// The static field-name for the synthetic object generated to account for class static overhead. 78a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartierstatic constexpr const char* kClassOverheadName = "$classOverhead"; 79622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 80622a6988351d77da0008142f4ce1ea447d838556Elliott Hughesenum HprofTag { 81622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_STRING = 0x01, 82622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_LOAD_CLASS = 0x02, 83622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_UNLOAD_CLASS = 0x03, 84622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_STACK_FRAME = 0x04, 85622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_STACK_TRACE = 0x05, 86622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_ALLOC_SITES = 0x06, 87622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_HEAP_SUMMARY = 0x07, 88622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_START_THREAD = 0x0A, 89622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_END_THREAD = 0x0B, 90622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_HEAP_DUMP = 0x0C, 91622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_HEAP_DUMP_SEGMENT = 0x1C, 92622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_HEAP_DUMP_END = 0x2C, 93622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_CPU_SAMPLES = 0x0D, 94622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_TAG_CONTROL_SETTINGS = 0x0E, 95622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes}; 96622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 97622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes// Values for the first byte of HEAP_DUMP and HEAP_DUMP_SEGMENT records: 98622a6988351d77da0008142f4ce1ea447d838556Elliott Hughesenum HprofHeapTag { 99622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes // Traditional. 100622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_UNKNOWN = 0xFF, 101622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_JNI_GLOBAL = 0x01, 102622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_JNI_LOCAL = 0x02, 103622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_JAVA_FRAME = 0x03, 104622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_NATIVE_STACK = 0x04, 105622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_STICKY_CLASS = 0x05, 106622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_THREAD_BLOCK = 0x06, 107622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_MONITOR_USED = 0x07, 108622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_THREAD_OBJECT = 0x08, 109622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_CLASS_DUMP = 0x20, 110622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_INSTANCE_DUMP = 0x21, 111622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_OBJECT_ARRAY_DUMP = 0x22, 112622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_PRIMITIVE_ARRAY_DUMP = 0x23, 113622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 114622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes // Android. 115622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_HEAP_DUMP_INFO = 0xfe, 116622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_INTERNED_STRING = 0x89, 117622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_FINALIZING = 0x8a, // Obsolete. 118622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_DEBUGGER = 0x8b, 119622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_REFERENCE_CLEANUP = 0x8c, // Obsolete. 120622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_VM_INTERNAL = 0x8d, 121622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_ROOT_JNI_MONITOR = 0x8e, 122622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_UNREACHABLE = 0x90, // Obsolete. 123dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes HPROF_PRIMITIVE_ARRAY_NODATA_DUMP = 0xc3, // Obsolete. 124622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes}; 125622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 126622a6988351d77da0008142f4ce1ea447d838556Elliott Hughesenum HprofHeapId { 127622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_HEAP_DEFAULT = 0, 128622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes HPROF_HEAP_ZYGOTE = 'Z', 129ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier HPROF_HEAP_APP = 'A', 130ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier HPROF_HEAP_IMAGE = 'I', 131622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes}; 132622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 133622a6988351d77da0008142f4ce1ea447d838556Elliott Hughesenum HprofBasicType { 134622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof_basic_object = 2, 135622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof_basic_boolean = 4, 136622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof_basic_char = 5, 137622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof_basic_float = 6, 138622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof_basic_double = 7, 139622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof_basic_byte = 8, 140622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof_basic_short = 9, 141622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof_basic_int = 10, 142622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes hprof_basic_long = 11, 143622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes}; 144622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 145ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstypedef uint32_t HprofStringId; 146ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogerstypedef uint32_t HprofClassObjectId; 1478c2ff641294715864013737fdec57cdfd410270cMan Caotypedef uint32_t HprofClassSerialNumber; 1488c2ff641294715864013737fdec57cdfd410270cMan Caotypedef uint32_t HprofStackTraceSerialNumber; 1498c2ff641294715864013737fdec57cdfd410270cMan Caotypedef uint32_t HprofStackFrameId; 1508c2ff641294715864013737fdec57cdfd410270cMan Caostatic constexpr HprofStackTraceSerialNumber kHprofNullStackTrace = 0; 151622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 1523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampeclass EndianOutput { 153622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes public: 1543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe EndianOutput() : length_(0), sum_length_(0), max_length_(0), started_(false) {} 1553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual ~EndianOutput() {} 156dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 1573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void StartNewRecord(uint8_t tag, uint32_t time) { 1583a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (length_ > 0) { 1593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe EndRecord(); 1603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 1613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, 0U); 1623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe AddU1(tag); 1633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe AddU4(time); 1643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe AddU4(0xdeaddead); // Length, replaced on flush. 1653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe started_ = true; 166dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 167dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 1683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void EndRecord() { 1693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Replace length in header. 1703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (started_) { 1713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe UpdateU4(sizeof(uint8_t) + sizeof(uint32_t), 1723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ - sizeof(uint8_t) - 2 * sizeof(uint32_t)); 1733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 174dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 1753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleEndRecord(); 176622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 1773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe sum_length_ += length_; 1783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe max_length_ = std::max(max_length_, length_); 1793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ = 0; 1803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe started_ = false; 1813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 182622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 1833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU1(uint8_t value) { 1843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe AddU1List(&value, 1); 1853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 186ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddU2(uint16_t value) { 187ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU2List(&value, 1); 188622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 189ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddU4(uint32_t value) { 190ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4List(&value, 1); 191622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 192622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 193ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddU8(uint64_t value) { 194ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU8List(&value, 1); 195622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 196622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 197ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddObjectId(const mirror::Object* value) { 198ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(PointerToLowMemUInt32(value)); 199ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 200ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 2018c2ff641294715864013737fdec57cdfd410270cMan Cao void AddStackTraceSerialNumber(HprofStackTraceSerialNumber value) { 2028c2ff641294715864013737fdec57cdfd410270cMan Cao AddU4(value); 2038c2ff641294715864013737fdec57cdfd410270cMan Cao } 2048c2ff641294715864013737fdec57cdfd410270cMan Cao 205ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // The ID for the synthetic object generated to account for class static overhead. 206ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddClassStaticsId(const mirror::Class* value) { 207ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(1 | PointerToLowMemUInt32(value)); 208622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 209622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 210ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddJniGlobalRefId(jobject value) { 211ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(PointerToLowMemUInt32(value)); 212622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 213622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 214ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddClassId(HprofClassObjectId value) { 215ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(value); 216622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 217622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 218ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddStringId(HprofStringId value) { 219ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(value); 220dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 221dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 2223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU1List(const uint8_t* values, size_t count) { 2233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleU1List(values, count); 2243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ += count; 2253a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU2List(const uint16_t* values, size_t count) { 2273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleU2List(values, count); 2283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ += count * sizeof(uint16_t); 2293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2303a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU4List(const uint32_t* values, size_t count) { 2313a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleU4List(values, count); 2323a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ += count * sizeof(uint32_t); 2333a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 234ca71458862be8505330b7fd5649a062f31d143dcAndreas Gampe virtual void UpdateU4(size_t offset, uint32_t new_value ATTRIBUTE_UNUSED) { 2353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_LE(offset, length_ - 4); 2363a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU8List(const uint64_t* values, size_t count) { 2383a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleU8List(values, count); 2393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ += count * sizeof(uint64_t); 2403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 241622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 242ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddIdList(mirror::ObjectArray<mirror::Object>* values) 24390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 244ad466adf38db74a9840659626858196091151a64Mathieu Chartier const int32_t length = values->GetLength(); 245ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers for (int32_t i = 0; i < length; ++i) { 246ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddObjectId(values->GetWithoutChecks(i)); 247ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 248622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 249622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 250ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddUtf8String(const char* str) { 251622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes // The terminating NUL character is NOT written. 252ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU1List((const uint8_t*)str, strlen(str)); 253622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 254622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 2553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t Length() const { 256dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return length_; 257dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 258622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 2593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t SumLength() const { 2603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return sum_length_; 261622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 262dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 2633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t MaxLength() const { 2643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return max_length_; 2653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 266dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 2673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe protected: 2683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleU1List(const uint8_t* values ATTRIBUTE_UNUSED, 2693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t count ATTRIBUTE_UNUSED) { 2703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleU2List(const uint16_t* values ATTRIBUTE_UNUSED, 2723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t count ATTRIBUTE_UNUSED) { 2733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleU4List(const uint32_t* values ATTRIBUTE_UNUSED, 2753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t count ATTRIBUTE_UNUSED) { 2763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleU8List(const uint64_t* values ATTRIBUTE_UNUSED, 2783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t count ATTRIBUTE_UNUSED) { 2793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleEndRecord() { 2813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 282dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 2833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t length_; // Current record size. 2843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t sum_length_; // Size of all data. 2853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t max_length_; // Maximum seen length. 2863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool started_; // Was StartRecord called? 287622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes}; 288622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 2893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe// This keeps things buffered until flushed. 2903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampeclass EndianOutputBuffered : public EndianOutput { 291622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes public: 2923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe explicit EndianOutputBuffered(size_t reserve_size) { 2933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.reserve(reserve_size); 2943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual ~EndianOutputBuffered() {} 2963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 2973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void UpdateU4(size_t offset, uint32_t new_value) OVERRIDE { 2983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_LE(offset, length_ - 4); 2993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_[offset + 0] = static_cast<uint8_t>((new_value >> 24) & 0xFF); 3003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_[offset + 1] = static_cast<uint8_t>((new_value >> 16) & 0xFF); 3013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_[offset + 2] = static_cast<uint8_t>((new_value >> 8) & 0xFF); 3023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_[offset + 3] = static_cast<uint8_t>((new_value >> 0) & 0xFF); 303dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 304dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 3053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe protected: 3063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleU1List(const uint8_t* values, size_t count) OVERRIDE { 3073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, buffer_.size()); 3083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.insert(buffer_.end(), values, values + count); 3093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleU2List(const uint16_t* values, size_t count) OVERRIDE { 3123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, buffer_.size()); 3133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (size_t i = 0; i < count; ++i) { 3143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint16_t value = *values; 3153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 3163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 3173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe values++; 318dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 3193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleU4List(const uint32_t* values, size_t count) OVERRIDE { 3223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, buffer_.size()); 3233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (size_t i = 0; i < count; ++i) { 3243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint32_t value = *values; 3253a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 24) & 0xFF)); 3263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 16) & 0xFF)); 3273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 3283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 3293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe values++; 330dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 331dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 332dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 3333a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleU8List(const uint64_t* values, size_t count) OVERRIDE { 3343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, buffer_.size()); 3353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (size_t i = 0; i < count; ++i) { 3363a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint64_t value = *values; 3373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 56) & 0xFF)); 3383a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 48) & 0xFF)); 3393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 40) & 0xFF)); 3403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 32) & 0xFF)); 3413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 24) & 0xFF)); 3423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 16) & 0xFF)); 3433a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 3443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 3453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe values++; 34600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 347ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 348dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 3493a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleEndRecord() OVERRIDE { 3503a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(buffer_.size(), length_); 3513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (kIsDebugBuild && started_) { 3523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint32_t stored_length = 3533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe static_cast<uint32_t>(buffer_[5]) << 24 | 3543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe static_cast<uint32_t>(buffer_[6]) << 16 | 3553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe static_cast<uint32_t>(buffer_[7]) << 8 | 3563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe static_cast<uint32_t>(buffer_[8]); 3573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(stored_length, length_ - sizeof(uint8_t) - 2 * sizeof(uint32_t)); 358ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 3593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleFlush(buffer_.data(), length_); 3603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.clear(); 361ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 362dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 3633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleFlush(const uint8_t* buffer ATTRIBUTE_UNUSED, size_t length ATTRIBUTE_UNUSED) { 3643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe std::vector<uint8_t> buffer_; 3673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe}; 3683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampeclass FileEndianOutput FINAL : public EndianOutputBuffered { 3703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe public: 3713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe FileEndianOutput(File* fp, size_t reserved_size) 3723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe : EndianOutputBuffered(reserved_size), fp_(fp), errors_(false) { 3733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK(fp != nullptr); 3743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ~FileEndianOutput() { 3763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool Errors() { 3793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return errors_; 3803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe protected: 3833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleFlush(const uint8_t* buffer, size_t length) OVERRIDE { 3843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (!errors_) { 3853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe errors_ = !fp_->WriteFully(buffer, length); 386ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 387ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 388ad466adf38db74a9840659626858196091151a64Mathieu Chartier 3893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe private: 3903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe File* fp_; 3913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool errors_; 3923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe}; 3933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampeclass NetStateEndianOutput FINAL : public EndianOutputBuffered { 3953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe public: 3963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe NetStateEndianOutput(JDWP::JdwpNetStateBase* net_state, size_t reserved_size) 3973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe : EndianOutputBuffered(reserved_size), net_state_(net_state) { 3983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK(net_state != nullptr); 3993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 4003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ~NetStateEndianOutput() {} 4013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 4023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe protected: 4033a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleFlush(const uint8_t* buffer, size_t length) OVERRIDE { 4043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe std::vector<iovec> iov; 4053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe iov.push_back(iovec()); 4063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe iov[0].iov_base = const_cast<void*>(reinterpret_cast<const void*>(buffer)); 4073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe iov[0].iov_len = length; 4083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe net_state_->WriteBufferedPacketLocked(iov); 4093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 4103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 4113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe private: 4123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe JDWP::JdwpNetStateBase* net_state_; 4133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe}; 4143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 415bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier#define __ output_-> 4163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 417bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass Hprof : public SingleRootVisitor { 4183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe public: 4193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe Hprof(const char* output_filename, int fd, bool direct_to_ddms) 4203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe : filename_(output_filename), 4213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe fd_(fd), 422c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier direct_to_ddms_(direct_to_ddms) { 4233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(INFO) << "hprof: heap dump \"" << filename_ << "\" starting..."; 4243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 4253a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 4263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void Dump() 427c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier REQUIRES(Locks::mutator_lock_) 428c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier REQUIRES(!Locks::heap_bitmap_lock_, !Locks::alloc_tracker_lock_) { 4298c2ff641294715864013737fdec57cdfd410270cMan Cao { 4308c2ff641294715864013737fdec57cdfd410270cMan Cao MutexLock mu(Thread::Current(), *Locks::alloc_tracker_lock_); 4318c2ff641294715864013737fdec57cdfd410270cMan Cao if (Runtime::Current()->GetHeap()->IsAllocTrackingEnabled()) { 4328c2ff641294715864013737fdec57cdfd410270cMan Cao PopulateAllocationTrackingTraces(); 4338c2ff641294715864013737fdec57cdfd410270cMan Cao } 4348c2ff641294715864013737fdec57cdfd410270cMan Cao } 4358c2ff641294715864013737fdec57cdfd410270cMan Cao 4363a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // First pass to measure the size of the dump. 4373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t overall_size; 4383a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t max_length; 439ad466adf38db74a9840659626858196091151a64Mathieu Chartier { 4403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe EndianOutput count_output; 441bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = &count_output; 442bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessHeap(false); 4433a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe overall_size = count_output.SumLength(); 4443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe max_length = count_output.MaxLength(); 445bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = nullptr; 446ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 447dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 4483a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool okay; 4493a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (direct_to_ddms_) { 4503a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (kDirectStream) { 4513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = DumpToDdmsDirect(overall_size, max_length, CHUNK_TYPE("HPDS")); 4524303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe } else { 4533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = DumpToDdmsBuffered(overall_size, max_length); 454dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 4553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 4563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = DumpToFile(overall_size, max_length); 457dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 458dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 459dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes if (okay) { 460c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier const uint64_t duration = NanoTime() - start_ns_; 461c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier LOG(INFO) << "hprof: heap dump completed (" << PrettySize(RoundUp(overall_size, KB)) 462c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier << ") in " << PrettyDuration(duration) 463c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier << " objects " << total_objects_ 464c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier << " objects with stack traces " << total_objects_with_stack_trace_; 465dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 466dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 467622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 468622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes private: 46983c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier static void VisitObjectCallback(mirror::Object* obj, void* arg) 47090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 471ad466adf38db74a9840659626858196091151a64Mathieu Chartier DCHECK(obj != nullptr); 472ad466adf38db74a9840659626858196091151a64Mathieu Chartier DCHECK(arg != nullptr); 473bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier reinterpret_cast<Hprof*>(arg)->DumpHeapObject(obj); 474dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 475622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 476bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void DumpHeapObject(mirror::Object* obj) 47790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 4783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 479bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void DumpHeapClass(mirror::Class* klass) 48090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 481622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 482bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void DumpHeapArray(mirror::Array* obj, mirror::Class* klass) 48390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 4843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 485bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void DumpHeapInstanceObject(mirror::Object* obj, mirror::Class* klass) 48690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 4873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 488bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void ProcessHeap(bool header_first) 48990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(Locks::mutator_lock_) { 4903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Reset current heap and object count. 4913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe current_heap_ = HPROF_HEAP_DEFAULT; 4923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe objects_in_segment_ = 0; 4933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 4943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (header_first) { 4958c2ff641294715864013737fdec57cdfd410270cMan Cao ProcessHeader(true); 496bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessBody(); 4973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 498bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessBody(); 4998c2ff641294715864013737fdec57cdfd410270cMan Cao ProcessHeader(false); 5003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 5013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 502622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 50390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void ProcessBody() REQUIRES(Locks::mutator_lock_) { 504bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier Runtime* const runtime = Runtime::Current(); 5053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Walk the roots and the heap. 506bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_SEGMENT, kHprofTime); 5073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 508e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler simple_roots_.clear(); 509bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier runtime->VisitRoots(this); 510bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier runtime->VisitImageRoots(this); 511bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier runtime->GetHeap()->VisitObjectsPaused(VisitObjectCallback, this); 5123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 513bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_END, kHprofTime); 514bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->EndRecord(); 5153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 5163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 51790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void ProcessHeader(bool string_first) REQUIRES(Locks::mutator_lock_) { 5183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Write the header. 519bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier WriteFixedHeader(); 5203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Write the string and class tables, and any stack traces, to the header. 5213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // (jhat requires that these appear before any of the data in the body that refers to them.) 5228c2ff641294715864013737fdec57cdfd410270cMan Cao // jhat also requires the string table appear before class table and stack traces. 5238c2ff641294715864013737fdec57cdfd410270cMan Cao // However, WriteStackTraces() can modify the string table, so it's necessary to call 5248c2ff641294715864013737fdec57cdfd410270cMan Cao // WriteStringTable() last in the first pass, to compute the correct length of the output. 5258c2ff641294715864013737fdec57cdfd410270cMan Cao if (string_first) { 5268c2ff641294715864013737fdec57cdfd410270cMan Cao WriteStringTable(); 5278c2ff641294715864013737fdec57cdfd410270cMan Cao } 528bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier WriteClassTable(); 529bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier WriteStackTraces(); 5308c2ff641294715864013737fdec57cdfd410270cMan Cao if (!string_first) { 5318c2ff641294715864013737fdec57cdfd410270cMan Cao WriteStringTable(); 5328c2ff641294715864013737fdec57cdfd410270cMan Cao } 533bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->EndRecord(); 5343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 5353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 53690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void WriteClassTable() SHARED_REQUIRES(Locks::mutator_lock_) { 5378c2ff641294715864013737fdec57cdfd410270cMan Cao for (const auto& p : classes_) { 5388c2ff641294715864013737fdec57cdfd410270cMan Cao mirror::Class* c = p.first; 5398c2ff641294715864013737fdec57cdfd410270cMan Cao HprofClassSerialNumber sn = p.second; 540ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers CHECK(c != nullptr); 541bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_LOAD_CLASS, kHprofTime); 542dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // LOAD CLASS format: 543dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // U4: class serial number (always > 0) 544dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // ID: class object ID. We use the address of the class object structure as its ID. 545dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // U4: stack trace serial number 546dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // ID: class name string ID 5478c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddU4(sn); 5483a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(c); 5498c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(c)); 5503a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddStringId(LookupClassNameId(c)); 551dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 5520c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 5530c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 554bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void WriteStringTable() { 555ad466adf38db74a9840659626858196091151a64Mathieu Chartier for (const std::pair<std::string, HprofStringId>& p : strings_) { 556ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers const std::string& string = p.first; 557ad466adf38db74a9840659626858196091151a64Mathieu Chartier const size_t id = p.second; 558dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 559bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_STRING, kHprofTime); 5600c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 561dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // STRING format: 562dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // ID: ID for this string 5632cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // U1*: UTF8 characters for string (NOT null terminated) 564dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // (the record format encodes the length) 5653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(id); 5663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddUtf8String(string.c_str()); 567dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 568dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 5690c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 570bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void StartNewHeapDumpSegment() { 571dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // This flushes the old segment and starts a new one. 572bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_SEGMENT, kHprofTime); 573dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes objects_in_segment_ = 0; 574dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // Starting a new HEAP_DUMP resets the heap to default. 575dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes current_heap_ = HPROF_HEAP_DEFAULT; 576dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 577dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 578bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void CheckHeapSegmentConstraints() { 579bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (objects_in_segment_ >= kMaxObjectsPerSegment || output_->Length() >= kMaxBytesPerSegment) { 580bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier StartNewHeapDumpSegment(); 5813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 5823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 5833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 584bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoot(mirror::Object* obj, const RootInfo& root_info) 58590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE SHARED_REQUIRES(Locks::mutator_lock_); 5863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void MarkRootObject(const mirror::Object* obj, jobject jni_obj, HprofHeapTag heap_tag, 587bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier uint32_t thread_serial); 588dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 58990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier HprofClassObjectId LookupClassId(mirror::Class* c) SHARED_REQUIRES(Locks::mutator_lock_) { 590ad466adf38db74a9840659626858196091151a64Mathieu Chartier if (c != nullptr) { 5918c2ff641294715864013737fdec57cdfd410270cMan Cao auto it = classes_.find(c); 5928c2ff641294715864013737fdec57cdfd410270cMan Cao if (it == classes_.end()) { 5938c2ff641294715864013737fdec57cdfd410270cMan Cao // first time to see this class 5948c2ff641294715864013737fdec57cdfd410270cMan Cao HprofClassSerialNumber sn = next_class_serial_number_++; 5958c2ff641294715864013737fdec57cdfd410270cMan Cao classes_.Put(c, sn); 5968c2ff641294715864013737fdec57cdfd410270cMan Cao // Make sure that we've assigned a string ID for this class' name 5978c2ff641294715864013737fdec57cdfd410270cMan Cao LookupClassNameId(c); 5988c2ff641294715864013737fdec57cdfd410270cMan Cao } 599ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 600ad466adf38db74a9840659626858196091151a64Mathieu Chartier return PointerToLowMemUInt32(c); 601dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 602dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 6038c2ff641294715864013737fdec57cdfd410270cMan Cao HprofStackTraceSerialNumber LookupStackTraceSerialNumber(const mirror::Object* obj) 60490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 6058c2ff641294715864013737fdec57cdfd410270cMan Cao auto r = allocation_records_.find(obj); 6068c2ff641294715864013737fdec57cdfd410270cMan Cao if (r == allocation_records_.end()) { 6078c2ff641294715864013737fdec57cdfd410270cMan Cao return kHprofNullStackTrace; 6088c2ff641294715864013737fdec57cdfd410270cMan Cao } else { 6098c2ff641294715864013737fdec57cdfd410270cMan Cao const gc::AllocRecordStackTrace* trace = r->second; 6108c2ff641294715864013737fdec57cdfd410270cMan Cao auto result = traces_.find(trace); 6118c2ff641294715864013737fdec57cdfd410270cMan Cao CHECK(result != traces_.end()); 6128c2ff641294715864013737fdec57cdfd410270cMan Cao return result->second; 6138c2ff641294715864013737fdec57cdfd410270cMan Cao } 6148c2ff641294715864013737fdec57cdfd410270cMan Cao } 6158c2ff641294715864013737fdec57cdfd410270cMan Cao 61690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier HprofStringId LookupStringId(mirror::String* string) SHARED_REQUIRES(Locks::mutator_lock_) { 617dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return LookupStringId(string->ToModifiedUtf8()); 618dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 619dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 620dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes HprofStringId LookupStringId(const char* string) { 621dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return LookupStringId(std::string(string)); 622dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 623dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 624dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes HprofStringId LookupStringId(const std::string& string) { 625ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers auto it = strings_.find(string); 626dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes if (it != strings_.end()) { 627dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return it->second; 628dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 629dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes HprofStringId id = next_string_id_++; 630dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes strings_.Put(string, id); 631dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return id; 632dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 633dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 63490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier HprofStringId LookupClassNameId(mirror::Class* c) SHARED_REQUIRES(Locks::mutator_lock_) { 635dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return LookupStringId(PrettyDescriptor(c)); 636dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 637dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 638bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void WriteFixedHeader() { 6390c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // Write the file header. 6400c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // U1: NUL-terminated magic string. 6413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe const char magic[] = "JAVA PROFILE 1.0.3"; 6423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1List(reinterpret_cast<const uint8_t*>(magic), sizeof(magic)); 6433a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6443280517651195602253ed92a2749964e96cad27eCalin Juravle // U4: size of identifiers. We're using addresses as IDs and our heap references are stored 6453280517651195602253ed92a2749964e96cad27eCalin Juravle // as uint32_t. 6463280517651195602253ed92a2749964e96cad27eCalin Juravle // Note of warning: hprof-conv hard-codes the size of identifiers to 4. 647575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe static_assert(sizeof(mirror::HeapReference<mirror::Object>) == sizeof(uint32_t), 648575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe "Unexpected HeapReference size"); 6493a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(sizeof(uint32_t)); 6503a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6510c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // The current time, in milliseconds since 0:00 GMT, 1/1/70. 6527b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes timeval now; 6533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe const uint64_t nowMs = (gettimeofday(&now, nullptr) < 0) ? 0 : 654ad466adf38db74a9840659626858196091151a64Mathieu Chartier (uint64_t)now.tv_sec * 1000 + now.tv_usec / 1000; 6553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // TODO: It seems it would be correct to use U8. 6560c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // U4: high word of the 64-bit time. 6573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(static_cast<uint32_t>(nowMs >> 32)); 6580c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // U4: low word of the 64-bit time. 6593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(static_cast<uint32_t>(nowMs & 0xFFFFFFFF)); 6600c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 6610c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 66290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void WriteStackTraces() SHARED_REQUIRES(Locks::mutator_lock_) { 663dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // Write a dummy stack trace record so the analysis tools don't freak out. 664bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_STACK_TRACE, kHprofTime); 6658c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStackTraceSerialNumber(kHprofNullStackTrace); 6663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(kHprofNullThread); 6673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(0); // no frames 6688c2ff641294715864013737fdec57cdfd410270cMan Cao 6698c2ff641294715864013737fdec57cdfd410270cMan Cao // TODO: jhat complains "WARNING: Stack trace not found for serial # -1", but no trace should 6708c2ff641294715864013737fdec57cdfd410270cMan Cao // have -1 as its serial number (as long as HprofStackTraceSerialNumber doesn't overflow). 6718c2ff641294715864013737fdec57cdfd410270cMan Cao for (const auto& it : traces_) { 6728c2ff641294715864013737fdec57cdfd410270cMan Cao const gc::AllocRecordStackTrace* trace = it.first; 6738c2ff641294715864013737fdec57cdfd410270cMan Cao HprofStackTraceSerialNumber trace_sn = it.second; 6748c2ff641294715864013737fdec57cdfd410270cMan Cao size_t depth = trace->GetDepth(); 6758c2ff641294715864013737fdec57cdfd410270cMan Cao 6768c2ff641294715864013737fdec57cdfd410270cMan Cao // First write stack frames of the trace 6778c2ff641294715864013737fdec57cdfd410270cMan Cao for (size_t i = 0; i < depth; ++i) { 6788c2ff641294715864013737fdec57cdfd410270cMan Cao const gc::AllocRecordStackTraceElement* frame = &trace->GetStackElement(i); 6798c2ff641294715864013737fdec57cdfd410270cMan Cao ArtMethod* method = frame->GetMethod(); 6808c2ff641294715864013737fdec57cdfd410270cMan Cao CHECK(method != nullptr); 6818c2ff641294715864013737fdec57cdfd410270cMan Cao output_->StartNewRecord(HPROF_TAG_STACK_FRAME, kHprofTime); 6828c2ff641294715864013737fdec57cdfd410270cMan Cao // STACK FRAME format: 6838c2ff641294715864013737fdec57cdfd410270cMan Cao // ID: stack frame ID. We use the address of the AllocRecordStackTraceElement object as its ID. 6848c2ff641294715864013737fdec57cdfd410270cMan Cao // ID: method name string ID 6858c2ff641294715864013737fdec57cdfd410270cMan Cao // ID: method signature string ID 6868c2ff641294715864013737fdec57cdfd410270cMan Cao // ID: source file name string ID 6878c2ff641294715864013737fdec57cdfd410270cMan Cao // U4: class serial number 6888c2ff641294715864013737fdec57cdfd410270cMan Cao // U4: >0, line number; 0, no line information available; -1, unknown location 6898c2ff641294715864013737fdec57cdfd410270cMan Cao auto frame_result = frames_.find(frame); 6908c2ff641294715864013737fdec57cdfd410270cMan Cao CHECK(frame_result != frames_.end()); 6918c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddU4(frame_result->second); 6928c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStringId(LookupStringId(method->GetName())); 6938c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStringId(LookupStringId(method->GetSignature().ToString())); 6948c2ff641294715864013737fdec57cdfd410270cMan Cao const char* source_file = method->GetDeclaringClassSourceFile(); 6958c2ff641294715864013737fdec57cdfd410270cMan Cao if (source_file == nullptr) { 6968c2ff641294715864013737fdec57cdfd410270cMan Cao source_file = ""; 6978c2ff641294715864013737fdec57cdfd410270cMan Cao } 6988c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStringId(LookupStringId(source_file)); 6998c2ff641294715864013737fdec57cdfd410270cMan Cao auto class_result = classes_.find(method->GetDeclaringClass()); 7008c2ff641294715864013737fdec57cdfd410270cMan Cao CHECK(class_result != classes_.end()); 7018c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddU4(class_result->second); 7028c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddU4(frame->ComputeLineNumber()); 7038c2ff641294715864013737fdec57cdfd410270cMan Cao } 7048c2ff641294715864013737fdec57cdfd410270cMan Cao 7058c2ff641294715864013737fdec57cdfd410270cMan Cao // Then write the trace itself 7068c2ff641294715864013737fdec57cdfd410270cMan Cao output_->StartNewRecord(HPROF_TAG_STACK_TRACE, kHprofTime); 7078c2ff641294715864013737fdec57cdfd410270cMan Cao // STACK TRACE format: 7088c2ff641294715864013737fdec57cdfd410270cMan Cao // U4: stack trace serial number. We use the address of the AllocRecordStackTrace object as its serial number. 7098c2ff641294715864013737fdec57cdfd410270cMan Cao // U4: thread serial number. We use Thread::GetTid(). 7108c2ff641294715864013737fdec57cdfd410270cMan Cao // U4: number of frames 7118c2ff641294715864013737fdec57cdfd410270cMan Cao // [ID]*: series of stack frame ID's 7128c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStackTraceSerialNumber(trace_sn); 7138c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddU4(trace->GetTid()); 7148c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddU4(depth); 7158c2ff641294715864013737fdec57cdfd410270cMan Cao for (size_t i = 0; i < depth; ++i) { 7168c2ff641294715864013737fdec57cdfd410270cMan Cao const gc::AllocRecordStackTraceElement* frame = &trace->GetStackElement(i); 7178c2ff641294715864013737fdec57cdfd410270cMan Cao auto frame_result = frames_.find(frame); 7188c2ff641294715864013737fdec57cdfd410270cMan Cao CHECK(frame_result != frames_.end()); 7198c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddU4(frame_result->second); 7208c2ff641294715864013737fdec57cdfd410270cMan Cao } 7218c2ff641294715864013737fdec57cdfd410270cMan Cao } 7223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 7233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool DumpToDdmsBuffered(size_t overall_size ATTRIBUTE_UNUSED, size_t max_length ATTRIBUTE_UNUSED) 72590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(Locks::mutator_lock_) { 7263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(FATAL) << "Unimplemented"; 7273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe UNREACHABLE(); 7283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // // Send the data off to DDMS. 7293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iovec iov[2]; 7303a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iov[0].iov_base = header_data_ptr_; 7313a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iov[0].iov_len = header_data_size_; 7323a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iov[1].iov_base = body_data_ptr_; 7333a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iov[1].iov_len = body_data_size_; 7343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Dbg::DdmSendChunkV(CHUNK_TYPE("HPDS"), iov, 2); 7353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 7363a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool DumpToFile(size_t overall_size, size_t max_length) 73890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(Locks::mutator_lock_) { 7393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Where exactly are we writing to? 7403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe int out_fd; 7413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (fd_ >= 0) { 7423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe out_fd = dup(fd_); 7433a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (out_fd < 0) { 7443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ThrowRuntimeException("Couldn't dump heap; dup(%d) failed: %s", fd_, strerror(errno)); 7453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return false; 7463a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 7473a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 7483a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe out_fd = open(filename_.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644); 7493a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (out_fd < 0) { 7503a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ThrowRuntimeException("Couldn't dump heap; open(\"%s\") failed: %s", filename_.c_str(), 7513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe strerror(errno)); 7523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return false; 7533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 7543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 7553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe std::unique_ptr<File> file(new File(out_fd, filename_, true)); 7573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool okay; 7583a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe { 7593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe FileEndianOutput file_output(file.get(), max_length); 760bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = &file_output; 761bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessHeap(true); 7623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = !file_output.Errors(); 7633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (okay) { 765c515f21dabd53e1b68bd2780fe86039d0dab49f8Andreas Gampe // Check for expected size. Output is expected to be less-or-equal than first phase, see 766c515f21dabd53e1b68bd2780fe86039d0dab49f8Andreas Gampe // b/23521263. 767c515f21dabd53e1b68bd2780fe86039d0dab49f8Andreas Gampe DCHECK_LE(file_output.SumLength(), overall_size); 7683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 769bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = nullptr; 7703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 7713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (okay) { 7733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = file->FlushCloseOrErase() == 0; 7743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 7753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe file->Erase(); 7763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 7773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (!okay) { 7783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe std::string msg(StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s", 7793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe filename_.c_str(), strerror(errno))); 7803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ThrowRuntimeException("%s", msg.c_str()); 7813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(ERROR) << msg; 7823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 7833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return okay; 7853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 7863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool DumpToDdmsDirect(size_t overall_size, size_t max_length, uint32_t chunk_type) 78890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(Locks::mutator_lock_) { 7893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK(direct_to_ddms_); 7903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe JDWP::JdwpState* state = Dbg::GetJdwpState(); 7913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK(state != nullptr); 7923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe JDWP::JdwpNetStateBase* net_state = state->netState; 7933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK(net_state != nullptr); 7943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Hold the socket lock for the whole time since we want this to be atomic. 7963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe MutexLock mu(Thread::Current(), *net_state->GetSocketLock()); 7973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Prepare the Ddms chunk. 7993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe constexpr size_t kChunkHeaderSize = kJDWPHeaderLen + 8; 8003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint8_t chunk_header[kChunkHeaderSize] = { 0 }; 8013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe state->SetupChunkHeader(chunk_type, overall_size, kChunkHeaderSize, chunk_header); 8023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8033a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Prepare the output and send the chunk header. 8043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe NetStateEndianOutput net_output(net_state, max_length); 805bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = &net_output; 8063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe net_output.AddU1List(chunk_header, kChunkHeaderSize); 8073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Write the dump. 809bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessHeap(true); 8103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 811c515f21dabd53e1b68bd2780fe86039d0dab49f8Andreas Gampe // Check for expected size. See DumpToFile for comment. 812c515f21dabd53e1b68bd2780fe86039d0dab49f8Andreas Gampe DCHECK_LE(net_output.SumLength(), overall_size + kChunkHeaderSize); 813bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = nullptr; 8143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return true; 8160c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 8170c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 8188c2ff641294715864013737fdec57cdfd410270cMan Cao void PopulateAllocationTrackingTraces() 81990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(Locks::mutator_lock_, Locks::alloc_tracker_lock_) { 8208c2ff641294715864013737fdec57cdfd410270cMan Cao gc::AllocRecordObjectMap* records = Runtime::Current()->GetHeap()->GetAllocationRecords(); 8218c2ff641294715864013737fdec57cdfd410270cMan Cao CHECK(records != nullptr); 8228c2ff641294715864013737fdec57cdfd410270cMan Cao HprofStackTraceSerialNumber next_trace_sn = kHprofNullStackTrace + 1; 8238c2ff641294715864013737fdec57cdfd410270cMan Cao HprofStackFrameId next_frame_id = 0; 82442c3c33df8b6eefc4ba532f1981282510f109928Man Cao size_t count = 0; 8258c2ff641294715864013737fdec57cdfd410270cMan Cao 8268c2ff641294715864013737fdec57cdfd410270cMan Cao for (auto it = records->Begin(), end = records->End(); it != end; ++it) { 8278c2ff641294715864013737fdec57cdfd410270cMan Cao const mirror::Object* obj = it->first.Read(); 82842c3c33df8b6eefc4ba532f1981282510f109928Man Cao if (obj == nullptr) { 82942c3c33df8b6eefc4ba532f1981282510f109928Man Cao continue; 83042c3c33df8b6eefc4ba532f1981282510f109928Man Cao } 83142c3c33df8b6eefc4ba532f1981282510f109928Man Cao ++count; 83223428587d32361736d4c5e0ba7270c7602695a43Mathieu Chartier const gc::AllocRecordStackTrace* trace = it->second.GetStackTrace(); 8338c2ff641294715864013737fdec57cdfd410270cMan Cao 8348c2ff641294715864013737fdec57cdfd410270cMan Cao // Copy the pair into a real hash map to speed up look up. 8358c2ff641294715864013737fdec57cdfd410270cMan Cao auto records_result = allocation_records_.emplace(obj, trace); 8368c2ff641294715864013737fdec57cdfd410270cMan Cao // The insertion should always succeed, i.e. no duplicate object pointers in "records" 8378c2ff641294715864013737fdec57cdfd410270cMan Cao CHECK(records_result.second); 8388c2ff641294715864013737fdec57cdfd410270cMan Cao 8398c2ff641294715864013737fdec57cdfd410270cMan Cao // Generate serial numbers for traces, and IDs for frames. 8408c2ff641294715864013737fdec57cdfd410270cMan Cao auto traces_result = traces_.find(trace); 8418c2ff641294715864013737fdec57cdfd410270cMan Cao if (traces_result == traces_.end()) { 8428c2ff641294715864013737fdec57cdfd410270cMan Cao traces_.emplace(trace, next_trace_sn++); 8438c2ff641294715864013737fdec57cdfd410270cMan Cao // only check frames if the trace is newly discovered 8448c2ff641294715864013737fdec57cdfd410270cMan Cao for (size_t i = 0, depth = trace->GetDepth(); i < depth; ++i) { 8458c2ff641294715864013737fdec57cdfd410270cMan Cao const gc::AllocRecordStackTraceElement* frame = &trace->GetStackElement(i); 8468c2ff641294715864013737fdec57cdfd410270cMan Cao auto frames_result = frames_.find(frame); 8478c2ff641294715864013737fdec57cdfd410270cMan Cao if (frames_result == frames_.end()) { 8488c2ff641294715864013737fdec57cdfd410270cMan Cao frames_.emplace(frame, next_frame_id++); 8498c2ff641294715864013737fdec57cdfd410270cMan Cao } 8508c2ff641294715864013737fdec57cdfd410270cMan Cao } 8518c2ff641294715864013737fdec57cdfd410270cMan Cao } 8528c2ff641294715864013737fdec57cdfd410270cMan Cao } 8538c2ff641294715864013737fdec57cdfd410270cMan Cao CHECK_EQ(traces_.size(), next_trace_sn - kHprofNullStackTrace - 1); 8548c2ff641294715864013737fdec57cdfd410270cMan Cao CHECK_EQ(frames_.size(), next_frame_id); 855c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier total_objects_with_stack_trace_ = count; 8568c2ff641294715864013737fdec57cdfd410270cMan Cao } 8578c2ff641294715864013737fdec57cdfd410270cMan Cao 858dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // If direct_to_ddms_ is set, "filename_" and "fd" will be ignored. 859dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // Otherwise, "filename_" must be valid, though if "fd" >= 0 it will 860dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // only be used for debug messages. 861dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes std::string filename_; 862dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes int fd_; 863dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes bool direct_to_ddms_; 8640c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 865c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier uint64_t start_ns_ = NanoTime(); 866dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 867c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier EndianOutput* output_ = nullptr; 868bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 869c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier HprofHeapId current_heap_ = HPROF_HEAP_DEFAULT; // Which heap we're currently dumping. 870c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier size_t objects_in_segment_ = 0; 871dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 872c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier size_t total_objects_ = 0u; 873c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier size_t total_objects_with_stack_trace_ = 0u; 874c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier 875c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier HprofStringId next_string_id_ = 0x400000; 876ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers SafeMap<std::string, HprofStringId> strings_; 877c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier HprofClassSerialNumber next_class_serial_number_ = 1; 8788c2ff641294715864013737fdec57cdfd410270cMan Cao SafeMap<mirror::Class*, HprofClassSerialNumber> classes_; 8798c2ff641294715864013737fdec57cdfd410270cMan Cao 8808c2ff641294715864013737fdec57cdfd410270cMan Cao std::unordered_map<const gc::AllocRecordStackTrace*, HprofStackTraceSerialNumber, 8818c2ff641294715864013737fdec57cdfd410270cMan Cao gc::HashAllocRecordTypesPtr<gc::AllocRecordStackTrace>, 8828c2ff641294715864013737fdec57cdfd410270cMan Cao gc::EqAllocRecordTypesPtr<gc::AllocRecordStackTrace>> traces_; 8838c2ff641294715864013737fdec57cdfd410270cMan Cao std::unordered_map<const gc::AllocRecordStackTraceElement*, HprofStackFrameId, 8848c2ff641294715864013737fdec57cdfd410270cMan Cao gc::HashAllocRecordTypesPtr<gc::AllocRecordStackTraceElement>, 8858c2ff641294715864013737fdec57cdfd410270cMan Cao gc::EqAllocRecordTypesPtr<gc::AllocRecordStackTraceElement>> frames_; 8868c2ff641294715864013737fdec57cdfd410270cMan Cao std::unordered_map<const mirror::Object*, const gc::AllocRecordStackTrace*> allocation_records_; 887dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 888e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler // Set used to keep track of what simple root records we have already 889e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler // emitted, to avoid emitting duplicate entries. The simple root records are 890e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler // those that contain no other information than the root type and the object 891e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler // id. A pair of root type and object id is packed into a uint64_t, with 892e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler // the root type in the upper 32 bits and the object id in the lower 32 893e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler // bits. 894e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler std::unordered_set<uint64_t> simple_roots_; 895e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler 896e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier friend class GcRootVisitor; 897dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes DISALLOW_COPY_AND_ASSIGN(Hprof); 898dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes}; 8990c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 9003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampestatic HprofBasicType SignatureToBasicTypeAndSize(const char* sig, size_t* size_out) { 9010c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson char c = sig[0]; 9020c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson HprofBasicType ret; 9030c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson size_t size; 9040c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 9050c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson switch (c) { 9063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case '[': 9073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'L': 9083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_object; 9093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 4; 9103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'Z': 9123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_boolean; 9133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 1; 9143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'C': 9163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_char; 9173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 2; 9183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'F': 9203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_float; 9213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 4; 9223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'D': 9243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_double; 9253a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 8; 9263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'B': 9283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_byte; 9293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 1; 9303a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9313a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'S': 9323a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_short; 9333a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 2; 9343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'I': 9363a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_int; 9373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 4; 9383a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'J': 9403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_long; 9413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 8; 9423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9433a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe default: 9443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(FATAL) << "UNREACHABLE"; 9453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe UNREACHABLE(); 9460c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 9470c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 9483a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (size_out != nullptr) { 9493a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe *size_out = size; 9500c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 9510c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 9520c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson return ret; 9530c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson} 9540c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 9550c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson// Always called when marking objects, but only does 9560c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson// something when ctx->gc_scan_state_ is non-zero, which is usually 9570c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson// only true when marking the root set or unreachable 9580c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson// objects. Used to add rootset references to obj. 9593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampevoid Hprof::MarkRootObject(const mirror::Object* obj, jobject jni_obj, HprofHeapTag heap_tag, 960bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier uint32_t thread_serial) { 9613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (heap_tag == 0) { 9623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return; 9633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 9643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 965bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier CheckHeapSegmentConstraints(); 9663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 9673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe switch (heap_tag) { 9683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: object ID 9693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_UNKNOWN: 9703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_STICKY_CLASS: 9713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_MONITOR_USED: 9723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_INTERNED_STRING: 9733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_DEBUGGER: 974e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler case HPROF_ROOT_VM_INTERNAL: { 975e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler uint64_t key = (static_cast<uint64_t>(heap_tag) << 32) | PointerToLowMemUInt32(obj); 976e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler if (simple_roots_.insert(key).second) { 977e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler __ AddU1(heap_tag); 978e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler __ AddObjectId(obj); 979e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler } 9803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 981e792305f5238df71a1928faf142cd35713aa3e47Richard Uhler } 9823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 9833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: object ID 9843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: JNI global ref ID 9853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_JNI_GLOBAL: 9863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(heap_tag); 9873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 9883a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddJniGlobalRefId(jni_obj); 9893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 9903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 9913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: object ID 9923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: thread serial number 9933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: frame number in stack trace (-1 for empty) 9943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_JNI_LOCAL: 9953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_JNI_MONITOR: 9963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_JAVA_FRAME: 9973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(heap_tag); 9983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 9993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(thread_serial); 10003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4((uint32_t)-1); 10013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 10023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10033a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: object ID 10043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: thread serial number 10053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_NATIVE_STACK: 10063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_THREAD_BLOCK: 10073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(heap_tag); 10083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 10093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(thread_serial); 10103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 10113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: thread object ID 10133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: thread serial number 10143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: stack trace serial number 10153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_THREAD_OBJECT: 10163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(heap_tag); 10173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 10183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(thread_serial); 10193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4((uint32_t)-1); // xxx 10203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 10213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_CLASS_DUMP: 10233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_INSTANCE_DUMP: 10243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_OBJECT_ARRAY_DUMP: 10253a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_PRIMITIVE_ARRAY_DUMP: 10263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_HEAP_DUMP_INFO: 10273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_PRIMITIVE_ARRAY_NODATA_DUMP: 10283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Ignored. 10293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 10303a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10313a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_FINALIZING: 10323a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_REFERENCE_CLEANUP: 10333a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_UNREACHABLE: 10343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(FATAL) << "obsolete tag " << static_cast<int>(heap_tag); 10353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 10360c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 10370c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 1038dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes ++objects_in_segment_; 10390c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson} 10400c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 1041e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier// Use for visiting the GcRoots held live by ArtFields, ArtMethods, and ClassLoaders. 1042e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartierclass GcRootVisitor { 1043e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier public: 1044e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier explicit GcRootVisitor(Hprof* hprof) : hprof_(hprof) {} 1045e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1046e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier void operator()(mirror::Object* obj ATTRIBUTE_UNUSED, 1047e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier MemberOffset offset ATTRIBUTE_UNUSED, 1048e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier bool is_static ATTRIBUTE_UNUSED) const {} 1049e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1050e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier // Note that these don't have read barriers. Its OK however since the GC is guaranteed to not be 1051e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier // running during the hprof dumping process. 1052e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier void VisitRootIfNonNull(mirror::CompressedReference<mirror::Object>* root) const 1053e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1054e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier if (!root->IsNull()) { 1055e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier VisitRoot(root); 1056e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier } 1057e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier } 1058e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1059e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier void VisitRoot(mirror::CompressedReference<mirror::Object>* root) const 1060e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 1061e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier mirror::Object* obj = root->AsMirrorPtr(); 1062e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier // The two cases are either classes or dex cache arrays. If it is a dex cache array, then use 1063e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier // VM internal. Otherwise the object is a declaring class of an ArtField or ArtMethod or a 1064e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier // class from a ClassLoader. 1065e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier hprof_->VisitRoot(obj, RootInfo(obj->IsClass() ? kRootStickyClass : kRootVMInternal)); 1066e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier } 1067e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1068e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1069e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier private: 1070e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier Hprof* const hprof_; 1071e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier}; 1072e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1073bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::DumpHeapObject(mirror::Object* obj) { 10743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Ignore classes that are retired. 10753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (obj->IsClass() && obj->AsClass()->IsRetired()) { 10763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return; 10773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 10783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 1079c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier ++total_objects_; 1080c9cd7ac27479c2fbc4c8451536ec628307f260cdMathieu Chartier 1081e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier GcRootVisitor visitor(this); 1082059ef3ddb2088f926ac452889e0953fdcd646a5eMathieu Chartier obj->VisitReferences(visitor, VoidFunctor()); 1083e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 1084e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier gc::Heap* const heap = Runtime::Current()->GetHeap(); 1085e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier const gc::space::ContinuousSpace* const space = heap->FindContinuousSpaceFromObject(obj, true); 1086ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier HprofHeapId heap_type = HPROF_HEAP_APP; 1087ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier if (space != nullptr) { 1088ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier if (space->IsZygoteSpace()) { 1089ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier heap_type = HPROF_HEAP_ZYGOTE; 1090ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier } else if (space->IsImageSpace()) { 1091ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier heap_type = HPROF_HEAP_IMAGE; 1092ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier } 1093e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier } else { 1094e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier const auto* los = heap->GetLargeObjectsSpace(); 1095e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier if (los->Contains(obj) && los->IsZygoteLargeObject(Thread::Current(), obj)) { 1096e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier heap_type = HPROF_HEAP_ZYGOTE; 1097e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier } 1098ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier } 1099bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier CheckHeapSegmentConstraints(); 11000c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 1101ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier if (heap_type != current_heap_) { 11020c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson HprofStringId nameId; 11030c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 11040c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // This object is in a different heap than the current one. 11050c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // Emit a HEAP_DUMP_INFO tag to change heaps. 11063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_HEAP_DUMP_INFO); 11073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(static_cast<uint32_t>(heap_type)); // uint32_t: heap type 1108ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier switch (heap_type) { 11090c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson case HPROF_HEAP_APP: 11100c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson nameId = LookupStringId("app"); 11110c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson break; 11120c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson case HPROF_HEAP_ZYGOTE: 11130c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson nameId = LookupStringId("zygote"); 11140c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson break; 1115ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier case HPROF_HEAP_IMAGE: 1116ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier nameId = LookupStringId("image"); 1117ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier break; 11180c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson default: 11190c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // Internal error 11200c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson LOG(ERROR) << "Unexpected desiredHeap"; 11210c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson nameId = LookupStringId("<ILLEGAL>"); 11220c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson break; 11230c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 11243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddStringId(nameId); 1125ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier current_heap_ = heap_type; 11260c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 11270c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 11282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* c = obj->GetClass(); 11293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (c == nullptr) { 11302cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // This object will bother HprofReader, because it has a null 11310c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // class, so just don't dump it. It could be 11320c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // gDvm.unlinkedJavaLangClass or it could be an object just 11330c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // allocated which hasn't been initialized yet. 11340c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } else { 11350c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson if (obj->IsClass()) { 1136bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier DumpHeapClass(obj->AsClass()); 11373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else if (c->IsArrayClass()) { 1138bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier DumpHeapArray(obj->AsArray(), c); 11393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 1140bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier DumpHeapInstanceObject(obj, c); 11413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 11423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 11430c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 11443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ++objects_in_segment_; 11453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe} 11460c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 1147bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::DumpHeapClass(mirror::Class* klass) { 1148ca068b2385ba160367d1e7fd123317b851b99390Sebastien Hertz if (!klass->IsLoaded() && !klass->IsErroneous()) { 1149ca068b2385ba160367d1e7fd123317b851b99390Sebastien Hertz // Class is allocated but not yet loaded: we cannot access its fields or super class. 1150ca068b2385ba160367d1e7fd123317b851b99390Sebastien Hertz return; 1151ca068b2385ba160367d1e7fd123317b851b99390Sebastien Hertz } 1152a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier const size_t num_static_fields = klass->NumStaticFields(); 1153a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier // Total class size including embedded IMT, embedded vtable, and static fields. 1154a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier const size_t class_size = klass->GetClassSize(); 1155a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier // Class size excluding static fields (relies on reference fields being the first static fields). 1156a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier const size_t class_size_without_overhead = sizeof(mirror::Class); 1157a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier CHECK_LE(class_size_without_overhead, class_size); 1158a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier const size_t overhead_size = class_size - class_size_without_overhead; 1159a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier 1160a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier if (overhead_size != 0) { 11613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Create a byte array to reflect the allocation of the 11623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // StaticField array at the end of this class. 11633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 11643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassStaticsId(klass); 11658c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(klass)); 1166a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier __ AddU4(overhead_size); 11673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(hprof_basic_byte); 1168a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier for (size_t i = 0; i < overhead_size; ++i) { 11693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(0); 11703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 11713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 11720c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 11733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_CLASS_DUMP); 11743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassId(LookupClassId(klass)); 11758c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(klass)); 11763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassId(LookupClassId(klass->GetSuperClass())); 11773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(klass->GetClassLoader()); 11783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(nullptr); // no signer 11793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(nullptr); // no prot domain 11803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(nullptr); // reserved 11813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(nullptr); // reserved 11823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (klass->IsClassClass()) { 11833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ClassObjects have their static fields appended, so aren't all the same size. 11843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // But they're at least this size. 1185a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier __ AddU4(class_size_without_overhead); // instance size 11860ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao } else if (klass->IsStringClass()) { 11870ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao // Strings are variable length with character data at the end like arrays. 11880ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao // This outputs the size of an empty string. 11890ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao __ AddU4(sizeof(mirror::String)); 11900ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao } else if (klass->IsArrayClass() || klass->IsPrimitive()) { 11913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(0); 11923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 11933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(klass->GetObjectSize()); // instance size 11943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 11953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 11963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU2(0); // empty const pool 11970c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 11983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Static fields 1199a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier if (overhead_size == 0) { 1200a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier __ AddU2(static_cast<uint16_t>(0)); 12013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 1202a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier __ AddU2(static_cast<uint16_t>(num_static_fields + 1)); 1203a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier __ AddStringId(LookupStringId(kClassOverheadName)); 12043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(hprof_basic_object); 12053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassStaticsId(klass); 12063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 1207a6d3a7ef8e648e8a65b38ea0bc475fad1d1fc105Mathieu Chartier for (size_t i = 0; i < num_static_fields; ++i) { 1208c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* f = klass->GetStaticField(i); 12093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 12103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t size; 12113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); 12123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddStringId(LookupStringId(f->GetName())); 12133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(t); 121415f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier switch (t) { 121515f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_byte: 1216ff38c04b88e86bffdd520bc1863d05334ada6c94Mathieu Chartier __ AddU1(f->GetByte(klass)); 12173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 121815f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_boolean: 121915f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier __ AddU1(f->GetBoolean(klass)); 122015f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 122115f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_char: 1222ff38c04b88e86bffdd520bc1863d05334ada6c94Mathieu Chartier __ AddU2(f->GetChar(klass)); 12233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 122415f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_short: 122515f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier __ AddU2(f->GetShort(klass)); 122615f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 122715f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_float: 122815f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_int: 122915f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_object: 12303a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(f->Get32(klass)); 12313a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 123215f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_double: 123315f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_long: 12343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU8(f->Get64(klass)); 12353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 12363a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe default: 12373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(FATAL) << "Unexpected size " << size; 12383a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe UNREACHABLE(); 12390c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 12403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 12413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 12423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 12433a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Instance fields for this class (no superclass fields) 12447c1f53e4253e6acff5e76f00e6bf666518068c4dMathieu Chartier int iFieldCount = klass->NumInstanceFields(); 1245848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (klass->IsStringClass()) { 1246848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU2((uint16_t)iFieldCount + 1); 1247848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } else { 1248848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU2((uint16_t)iFieldCount); 1249848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 12503a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (int i = 0; i < iFieldCount; ++i) { 1251c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* f = klass->GetInstanceField(i); 12523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddStringId(LookupStringId(f->GetName())); 12533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), nullptr); 12543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(t); 12553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 1256848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Add native value character array for strings. 1257848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (klass->IsStringClass()) { 1258848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddStringId(LookupStringId("value")); 1259848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU1(hprof_basic_object); 1260848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 12613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe} 12623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 1263bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::DumpHeapArray(mirror::Array* obj, mirror::Class* klass) { 12643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint32_t length = obj->GetLength(); 12650c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 12663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (obj->IsObjectArray()) { 12673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // obj is an object array. 12683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_OBJECT_ARRAY_DUMP); 12690c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 12703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 12718c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj)); 12723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(length); 12733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassId(LookupClassId(klass)); 12740c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 12752cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Dump the elements, which are always objects or null. 12763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddIdList(obj->AsObjectArray<mirror::Object>()); 12773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 12783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t size; 12793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HprofBasicType t = SignatureToBasicTypeAndSize( 12803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe Primitive::Descriptor(klass->GetComponentType()->GetPrimitiveType()), &size); 12813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 12823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // obj is a primitive array. 12833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 12843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 12853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 12868c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj)); 12873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(length); 12883a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(t); 12893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 12903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Dump the raw, packed element values. 12913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (size == 1) { 12923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1List(reinterpret_cast<const uint8_t*>(obj->GetRawData(sizeof(uint8_t), 0)), length); 12933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else if (size == 2) { 12943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU2List(reinterpret_cast<const uint16_t*>(obj->GetRawData(sizeof(uint16_t), 0)), length); 12953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else if (size == 4) { 12963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4List(reinterpret_cast<const uint32_t*>(obj->GetRawData(sizeof(uint32_t), 0)), length); 12973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else if (size == 8) { 12983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU8List(reinterpret_cast<const uint64_t*>(obj->GetRawData(sizeof(uint64_t), 0)), length); 12993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 13003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 13013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe} 13023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 1303bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::DumpHeapInstanceObject(mirror::Object* obj, mirror::Class* klass) { 13043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // obj is an instance object. 13053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_INSTANCE_DUMP); 13063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 13078c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj)); 13083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassId(LookupClassId(klass)); 13093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 13103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Reserve some space for the length of the instance data, which we won't 13113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // know until we're done writing it. 1312bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier size_t size_patch_offset = output_->Length(); 13133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(0x77777777); 13143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 131507d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier // What we will use for the string value if the object is a string. 131607d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier mirror::Object* string_value = nullptr; 131707d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier 131807d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier // Write the instance data; fields for this class, followed by super class fields, and so on. 13197c1f53e4253e6acff5e76f00e6bf666518068c4dMathieu Chartier do { 132007d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier const size_t instance_fields = klass->NumInstanceFields(); 132107d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier for (size_t i = 0; i < instance_fields; ++i) { 1322c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* f = klass->GetInstanceField(i); 13233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t size; 132407d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); 132515f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier switch (t) { 132615f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_byte: 1327ff38c04b88e86bffdd520bc1863d05334ada6c94Mathieu Chartier __ AddU1(f->GetByte(obj)); 132815f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 132915f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_boolean: 133015f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier __ AddU1(f->GetBoolean(obj)); 133115f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 133215f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_char: 1333ff38c04b88e86bffdd520bc1863d05334ada6c94Mathieu Chartier __ AddU2(f->GetChar(obj)); 133415f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 133515f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_short: 133615f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier __ AddU2(f->GetShort(obj)); 133715f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 133815f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_float: 133915f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_int: 134015f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_object: 13413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(f->Get32(obj)); 134215f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 134315f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_double: 134415f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_long: 13453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU8(f->Get64(obj)); 134615f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 13470c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 13480c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 134907d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier // Add value field for String if necessary. 135007d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier if (klass->IsStringClass()) { 135107d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier mirror::String* s = obj->AsString(); 135207d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier if (s->GetLength() == 0) { 135307d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier // If string is empty, use an object-aligned address within the string for the value. 135407d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier string_value = reinterpret_cast<mirror::Object*>( 135507d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier reinterpret_cast<uintptr_t>(s) + kObjectAlignment); 135607d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier } else { 135707d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier string_value = reinterpret_cast<mirror::Object*>(s->GetValue()); 135807d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier } 135907d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier __ AddObjectId(string_value); 136007d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier } 13613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 13623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe klass = klass->GetSuperClass(); 13637c1f53e4253e6acff5e76f00e6bf666518068c4dMathieu Chartier } while (klass != nullptr); 13640c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 136507d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier // Patch the instance field length. 136607d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier __ UpdateU4(size_patch_offset, output_->Length() - (size_patch_offset + 4)); 136707d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier 1368848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Output native value character array for strings. 136907d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier CHECK_EQ(obj->IsString(), string_value != nullptr); 137007d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier if (string_value != nullptr) { 1371848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao mirror::String* s = obj->AsString(); 1372848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 137307d7eab545916ef0602afddae162f5b6b1a68b7dMathieu Chartier __ AddObjectId(string_value); 13748c2ff641294715864013737fdec57cdfd410270cMan Cao __ AddStackTraceSerialNumber(LookupStackTraceSerialNumber(obj)); 1375848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU4(s->GetLength()); 1376848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU1(hprof_basic_char); 1377848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU2List(s->GetValue(), s->GetLength()); 1378848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 13790c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson} 13800c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 1381bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::VisitRoot(mirror::Object* obj, const RootInfo& info) { 13820b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson static const HprofHeapTag xlate[] = { 13830b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_UNKNOWN, 13840b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_JNI_GLOBAL, 13850b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_JNI_LOCAL, 13860b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_JAVA_FRAME, 13870b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_NATIVE_STACK, 13880b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_STICKY_CLASS, 13890b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_THREAD_BLOCK, 13900b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_MONITOR_USED, 13910b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_THREAD_OBJECT, 13920b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_INTERNED_STRING, 13930b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_FINALIZING, 13940b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_DEBUGGER, 13950b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_REFERENCE_CLEANUP, 13960b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_VM_INTERNAL, 13970b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_JNI_MONITOR, 13980b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson }; 1399e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier CHECK_LT(info.GetType(), sizeof(xlate) / sizeof(HprofHeapTag)); 14003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (obj == nullptr) { 14010b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson return; 14020b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson } 1403bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier MarkRootObject(obj, 0, xlate[info.GetType()], info.GetThreadId()); 1404c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson} 1405c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 1406dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes// If "direct_to_ddms" is true, the other arguments are ignored, and data is 1407dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes// sent directly to DDMS. 1408dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes// If "fd" is >= 0, the output will be written to that file descriptor. 1409dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes// Otherwise, "filename" is used to create an output file. 1410dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughesvoid DumpHeap(const char* filename, int fd, bool direct_to_ddms) { 14113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK(filename != nullptr); 14120b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson 14132cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Thread* self = Thread::Current(); 14142cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi gc::Heap* heap = Runtime::Current()->GetHeap(); 14152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (heap->IsGcConcurrentAndMoving()) { 14162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Need to take a heap dump while GC isn't running. See the 14172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // comment in Heap::VisitObjects(). 14182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi heap->IncrementDisableMovingGC(self); 14192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 14204f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier { 14214f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier ScopedSuspendAll ssa(__FUNCTION__, true /* long suspend */); 14224f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier Hprof hprof(filename, fd, direct_to_ddms); 14234f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier hprof.Dump(); 14244f55e22630d99ca0edd9e951e5ee96b57bb9b980Mathieu Chartier } 14252cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (heap->IsGcConcurrentAndMoving()) { 14262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi heap->DecrementDisableMovingGC(self); 14272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1428c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson} 1429c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 1430ad466adf38db74a9840659626858196091151a64Mathieu Chartier} // namespace hprof 1431c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson} // namespace art 1432