hprof.cc revision e7158116f345df6df73f0df7ebdc2be8e0e4f3e8
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" 511d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/heap.h" 521d54e73444e017d3a65234e0f193846f3e27472bIan Rogers#include "gc/space/space.h" 53622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include "globals.h" 54ad466adf38db74a9840659626858196091151a64Mathieu Chartier#include "jdwp/jdwp.h" 55ad466adf38db74a9840659626858196091151a64Mathieu Chartier#include "jdwp/jdwp_priv.h" 562dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class.h" 572dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h" 582dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h" 59dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes#include "os.h" 60622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include "safe_map.h" 6100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers#include "scoped_thread_state_change.h" 62622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes#include "thread_list.h" 63c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 64c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilsonnamespace art { 65c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 66c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilsonnamespace hprof { 67c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 68ad466adf38db74a9840659626858196091151a64Mathieu Chartierstatic constexpr bool kDirectStream = true; 69622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampestatic constexpr uint32_t kHprofTime = 0; 713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampestatic constexpr uint32_t kHprofNullStackTrace = 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. 783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampestatic constexpr const char* kStaticOverheadName = "$staticOverhead"; 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; 147622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 1483a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampeclass EndianOutput { 149622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes public: 1503a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe EndianOutput() : length_(0), sum_length_(0), max_length_(0), started_(false) {} 1513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual ~EndianOutput() {} 152dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 1533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void StartNewRecord(uint8_t tag, uint32_t time) { 1543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (length_ > 0) { 1553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe EndRecord(); 1563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 1573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, 0U); 1583a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe AddU1(tag); 1593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe AddU4(time); 1603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe AddU4(0xdeaddead); // Length, replaced on flush. 1613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe started_ = true; 162dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 163dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 1643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void EndRecord() { 1653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Replace length in header. 1663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (started_) { 1673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe UpdateU4(sizeof(uint8_t) + sizeof(uint32_t), 1683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ - sizeof(uint8_t) - 2 * sizeof(uint32_t)); 1693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 170dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 1713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleEndRecord(); 172622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 1733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe sum_length_ += length_; 1743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe max_length_ = std::max(max_length_, length_); 1753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ = 0; 1763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe started_ = false; 1773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 178622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 1793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU1(uint8_t value) { 1803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe AddU1List(&value, 1); 1813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 182ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddU2(uint16_t value) { 183ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU2List(&value, 1); 184622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 185ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddU4(uint32_t value) { 186ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4List(&value, 1); 187622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 188622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 189ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddU8(uint64_t value) { 190ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU8List(&value, 1); 191622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 192622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 193ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddObjectId(const mirror::Object* value) { 194ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(PointerToLowMemUInt32(value)); 195ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 196ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers 197ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers // The ID for the synthetic object generated to account for class static overhead. 198ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddClassStaticsId(const mirror::Class* value) { 199ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(1 | PointerToLowMemUInt32(value)); 200622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 201622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 202ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddJniGlobalRefId(jobject value) { 203ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(PointerToLowMemUInt32(value)); 204622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 205622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 206ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddClassId(HprofClassObjectId value) { 207ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(value); 208622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 209622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 210ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddStringId(HprofStringId value) { 211ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU4(value); 212dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 213dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 2143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU1List(const uint8_t* values, size_t count) { 2153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleU1List(values, count); 2163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ += count; 2173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU2List(const uint16_t* values, size_t count) { 2193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleU2List(values, count); 2203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ += count * sizeof(uint16_t); 2213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU4List(const uint32_t* values, size_t count) { 2233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleU4List(values, count); 2243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ += count * sizeof(uint32_t); 2253a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 226ca71458862be8505330b7fd5649a062f31d143dcAndreas Gampe virtual void UpdateU4(size_t offset, uint32_t new_value ATTRIBUTE_UNUSED) { 2273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_LE(offset, length_ - 4); 2283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void AddU8List(const uint64_t* values, size_t count) { 2303a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleU8List(values, count); 2313a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe length_ += count * sizeof(uint64_t); 2323a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 233622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 234ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddIdList(mirror::ObjectArray<mirror::Object>* values) 2353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 236ad466adf38db74a9840659626858196091151a64Mathieu Chartier const int32_t length = values->GetLength(); 237ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers for (int32_t i = 0; i < length; ++i) { 238ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddObjectId(values->GetWithoutChecks(i)); 239ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 240622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 241622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 242ad466adf38db74a9840659626858196091151a64Mathieu Chartier void AddUtf8String(const char* str) { 243622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes // The terminating NUL character is NOT written. 244ad466adf38db74a9840659626858196091151a64Mathieu Chartier AddU1List((const uint8_t*)str, strlen(str)); 245622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 246622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 2473a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t Length() const { 248dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return length_; 249dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 250622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 2513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t SumLength() const { 2523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return sum_length_; 253622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes } 254dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 2553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t MaxLength() const { 2563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return max_length_; 2573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 258dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 2593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe protected: 2603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleU1List(const uint8_t* values ATTRIBUTE_UNUSED, 2613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t count ATTRIBUTE_UNUSED) { 2623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleU2List(const uint16_t* values ATTRIBUTE_UNUSED, 2643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t count ATTRIBUTE_UNUSED) { 2653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleU4List(const uint32_t* values ATTRIBUTE_UNUSED, 2673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t count ATTRIBUTE_UNUSED) { 2683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleU8List(const uint64_t* values ATTRIBUTE_UNUSED, 2703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t count ATTRIBUTE_UNUSED) { 2713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleEndRecord() { 2733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 274dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 2753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t length_; // Current record size. 2763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t sum_length_; // Size of all data. 2773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t max_length_; // Maximum seen length. 2783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool started_; // Was StartRecord called? 279622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes}; 280622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 2813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe// This keeps things buffered until flushed. 2823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampeclass EndianOutputBuffered : public EndianOutput { 283622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes public: 2843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe explicit EndianOutputBuffered(size_t reserve_size) { 2853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.reserve(reserve_size); 2863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 2873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual ~EndianOutputBuffered() {} 2883a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 2893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void UpdateU4(size_t offset, uint32_t new_value) OVERRIDE { 2903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_LE(offset, length_ - 4); 2913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_[offset + 0] = static_cast<uint8_t>((new_value >> 24) & 0xFF); 2923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_[offset + 1] = static_cast<uint8_t>((new_value >> 16) & 0xFF); 2933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_[offset + 2] = static_cast<uint8_t>((new_value >> 8) & 0xFF); 2943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_[offset + 3] = static_cast<uint8_t>((new_value >> 0) & 0xFF); 295dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 296dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 2973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe protected: 2983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleU1List(const uint8_t* values, size_t count) OVERRIDE { 2993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, buffer_.size()); 3003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.insert(buffer_.end(), values, values + count); 3013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3033a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleU2List(const uint16_t* values, size_t count) OVERRIDE { 3043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, buffer_.size()); 3053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (size_t i = 0; i < count; ++i) { 3063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint16_t value = *values; 3073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 3083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 3093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe values++; 310dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 3113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleU4List(const uint32_t* values, size_t count) OVERRIDE { 3143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, buffer_.size()); 3153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (size_t i = 0; i < count; ++i) { 3163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint32_t value = *values; 3173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 24) & 0xFF)); 3183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 16) & 0xFF)); 3193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 3203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 3213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe values++; 322dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 323dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 324dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 3253a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleU8List(const uint64_t* values, size_t count) OVERRIDE { 3263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(length_, buffer_.size()); 3273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (size_t i = 0; i < count; ++i) { 3283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint64_t value = *values; 3293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 56) & 0xFF)); 3303a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 48) & 0xFF)); 3313a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 40) & 0xFF)); 3323a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 32) & 0xFF)); 3333a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 24) & 0xFF)); 3343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 16) & 0xFF)); 3353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 8) & 0xFF)); 3363a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.push_back(static_cast<uint8_t>((value >> 0) & 0xFF)); 3373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe values++; 33800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 339ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 340dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 3413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleEndRecord() OVERRIDE { 3423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(buffer_.size(), length_); 3433a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (kIsDebugBuild && started_) { 3443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint32_t stored_length = 3453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe static_cast<uint32_t>(buffer_[5]) << 24 | 3463a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe static_cast<uint32_t>(buffer_[6]) << 16 | 3473a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe static_cast<uint32_t>(buffer_[7]) << 8 | 3483a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe static_cast<uint32_t>(buffer_[8]); 3493a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK_EQ(stored_length, length_ - sizeof(uint8_t) - 2 * sizeof(uint32_t)); 350ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 3513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HandleFlush(buffer_.data(), length_); 3523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe buffer_.clear(); 353ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 354dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 3553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe virtual void HandleFlush(const uint8_t* buffer ATTRIBUTE_UNUSED, size_t length ATTRIBUTE_UNUSED) { 3563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3583a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe std::vector<uint8_t> buffer_; 3593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe}; 3603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampeclass FileEndianOutput FINAL : public EndianOutputBuffered { 3623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe public: 3633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe FileEndianOutput(File* fp, size_t reserved_size) 3643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe : EndianOutputBuffered(reserved_size), fp_(fp), errors_(false) { 3653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK(fp != nullptr); 3663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ~FileEndianOutput() { 3683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool Errors() { 3713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return errors_; 3723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe protected: 3753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleFlush(const uint8_t* buffer, size_t length) OVERRIDE { 3763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (!errors_) { 3773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe errors_ = !fp_->WriteFully(buffer, length); 378ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 379ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 380ad466adf38db74a9840659626858196091151a64Mathieu Chartier 3813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe private: 3823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe File* fp_; 3833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool errors_; 3843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe}; 3853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampeclass NetStateEndianOutput FINAL : public EndianOutputBuffered { 3873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe public: 3883a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe NetStateEndianOutput(JDWP::JdwpNetStateBase* net_state, size_t reserved_size) 3893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe : EndianOutputBuffered(reserved_size), net_state_(net_state) { 3903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe DCHECK(net_state != nullptr); 3913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 3923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ~NetStateEndianOutput() {} 3933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 3943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe protected: 3953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void HandleFlush(const uint8_t* buffer, size_t length) OVERRIDE { 3963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe std::vector<iovec> iov; 3973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe iov.push_back(iovec()); 3983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe iov[0].iov_base = const_cast<void*>(reinterpret_cast<const void*>(buffer)); 3993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe iov[0].iov_len = length; 4003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe net_state_->WriteBufferedPacketLocked(iov); 4013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 4023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 4033a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe private: 4043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe JDWP::JdwpNetStateBase* net_state_; 4053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe}; 4063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 407bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier#define __ output_-> 4083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 409bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartierclass Hprof : public SingleRootVisitor { 4103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe public: 4113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe Hprof(const char* output_filename, int fd, bool direct_to_ddms) 4123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe : filename_(output_filename), 4133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe fd_(fd), 4143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe direct_to_ddms_(direct_to_ddms), 4153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe start_ns_(NanoTime()), 4163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe current_heap_(HPROF_HEAP_DEFAULT), 4173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe objects_in_segment_(0), 4183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe next_string_id_(0x400000) { 4193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(INFO) << "hprof: heap dump \"" << filename_ << "\" starting..."; 4203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 4213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 4223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void Dump() 4233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 424ad466adf38db74a9840659626858196091151a64Mathieu Chartier LOCKS_EXCLUDED(Locks::heap_bitmap_lock_) { 4253a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // First pass to measure the size of the dump. 4263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t overall_size; 4273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t max_length; 428ad466adf38db74a9840659626858196091151a64Mathieu Chartier { 4293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe EndianOutput count_output; 430bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = &count_output; 431bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessHeap(false); 4323a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe overall_size = count_output.SumLength(); 4333a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe max_length = count_output.MaxLength(); 434bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = nullptr; 435ad466adf38db74a9840659626858196091151a64Mathieu Chartier } 436dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 4373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool okay; 4383a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (direct_to_ddms_) { 4393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (kDirectStream) { 4403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = DumpToDdmsDirect(overall_size, max_length, CHUNK_TYPE("HPDS")); 4414303ba97313458491e038d78efa041d41cf7bb43Andreas Gampe } else { 4423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = DumpToDdmsBuffered(overall_size, max_length); 443dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 4443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 4453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = DumpToFile(overall_size, max_length); 446dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 447dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 448dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes if (okay) { 449dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes uint64_t duration = NanoTime() - start_ns_; 45050b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers LOG(INFO) << "hprof: heap dump completed (" 4513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe << PrettySize(RoundUp(overall_size, 1024)) 45250b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers << ") in " << PrettyDuration(duration); 453dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 454dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 455622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 456622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes private: 45783c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier static void VisitObjectCallback(mirror::Object* obj, void* arg) 458b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 459ad466adf38db74a9840659626858196091151a64Mathieu Chartier DCHECK(obj != nullptr); 460ad466adf38db74a9840659626858196091151a64Mathieu Chartier DCHECK(arg != nullptr); 461bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier reinterpret_cast<Hprof*>(arg)->DumpHeapObject(obj); 462dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 463622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 464bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void DumpHeapObject(mirror::Object* obj) 4653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 4663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 467bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void DumpHeapClass(mirror::Class* klass) 46883c8ee000d525017ead8753fce6bc1020249b96aMathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 469622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 470bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void DumpHeapArray(mirror::Array* obj, mirror::Class* klass) 4713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 4723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 473bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void DumpHeapInstanceObject(mirror::Object* obj, mirror::Class* klass) 4743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 4753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 476bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void ProcessHeap(bool header_first) 4770c8c303c20cdaaf54d26e45cc17dc5afb820d8efHiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 4783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Reset current heap and object count. 4793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe current_heap_ = HPROF_HEAP_DEFAULT; 4803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe objects_in_segment_ = 0; 4813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 4823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (header_first) { 483bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessHeader(); 484bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessBody(); 4853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 486bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessBody(); 487bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessHeader(); 4883a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 4893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 490622a6988351d77da0008142f4ce1ea447d838556Elliott Hughes 491bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void ProcessBody() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 492bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier Runtime* const runtime = Runtime::Current(); 4933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Walk the roots and the heap. 494bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_SEGMENT, kHprofTime); 4953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 496bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier runtime->VisitRoots(this); 497bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier runtime->VisitImageRoots(this); 498bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier runtime->GetHeap()->VisitObjectsPaused(VisitObjectCallback, this); 4993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 500bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_END, kHprofTime); 501bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->EndRecord(); 5023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 5033a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 504bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void ProcessHeader() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 5053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Write the header. 506bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier WriteFixedHeader(); 5073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Write the string and class tables, and any stack traces, to the header. 5083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // (jhat requires that these appear before any of the data in the body that refers to them.) 509bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier WriteStringTable(); 510bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier WriteClassTable(); 511bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier WriteStackTraces(); 512bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->EndRecord(); 5133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 5143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 515bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void WriteClassTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 516dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes uint32_t nextSerialNumber = 1; 517dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 518ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers for (mirror::Class* c : classes_) { 519ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers CHECK(c != nullptr); 520bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_LOAD_CLASS, kHprofTime); 521dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // LOAD CLASS format: 522dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // U4: class serial number (always > 0) 523dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // ID: class object ID. We use the address of the class object structure as its ID. 524dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // U4: stack trace serial number 525dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // ID: class name string ID 5263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(nextSerialNumber++); 5273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(c); 5283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(kHprofNullStackTrace); 5293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddStringId(LookupClassNameId(c)); 530dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 5310c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 5320c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 533bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void WriteStringTable() { 534ad466adf38db74a9840659626858196091151a64Mathieu Chartier for (const std::pair<std::string, HprofStringId>& p : strings_) { 535ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers const std::string& string = p.first; 536ad466adf38db74a9840659626858196091151a64Mathieu Chartier const size_t id = p.second; 537dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 538bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_STRING, kHprofTime); 5390c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 540dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // STRING format: 541dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // ID: ID for this string 5422cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // U1*: UTF8 characters for string (NOT null terminated) 543dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // (the record format encodes the length) 5443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(id); 5453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddUtf8String(string.c_str()); 546dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 547dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 5480c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 549bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void StartNewHeapDumpSegment() { 550dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // This flushes the old segment and starts a new one. 551bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_HEAP_DUMP_SEGMENT, kHprofTime); 552dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes objects_in_segment_ = 0; 553dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // Starting a new HEAP_DUMP resets the heap to default. 554dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes current_heap_ = HPROF_HEAP_DEFAULT; 555dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 556dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 557bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void CheckHeapSegmentConstraints() { 558bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier if (objects_in_segment_ >= kMaxObjectsPerSegment || output_->Length() >= kMaxBytesPerSegment) { 559bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier StartNewHeapDumpSegment(); 5603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 5613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 5623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 563bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void VisitRoot(mirror::Object* obj, const RootInfo& root_info) 564bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 5653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe void MarkRootObject(const mirror::Object* obj, jobject jni_obj, HprofHeapTag heap_tag, 566bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier uint32_t thread_serial); 567dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 568ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HprofClassObjectId LookupClassId(mirror::Class* c) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 569ad466adf38db74a9840659626858196091151a64Mathieu Chartier if (c != nullptr) { 570ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers auto result = classes_.insert(c); 571ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers const mirror::Class* present = *result.first; 572ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers CHECK_EQ(present, c); 573ad466adf38db74a9840659626858196091151a64Mathieu Chartier // Make sure that we've assigned a string ID for this class' name 574ad466adf38db74a9840659626858196091151a64Mathieu Chartier LookupClassNameId(c); 575ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers } 576ad466adf38db74a9840659626858196091151a64Mathieu Chartier return PointerToLowMemUInt32(c); 577dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 578dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 579ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HprofStringId LookupStringId(mirror::String* string) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 580dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return LookupStringId(string->ToModifiedUtf8()); 581dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 582dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 583dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes HprofStringId LookupStringId(const char* string) { 584dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return LookupStringId(std::string(string)); 585dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 586dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 587dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes HprofStringId LookupStringId(const std::string& string) { 588ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers auto it = strings_.find(string); 589dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes if (it != strings_.end()) { 590dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return it->second; 591dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 592dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes HprofStringId id = next_string_id_++; 593dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes strings_.Put(string, id); 594dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return id; 595dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 596dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 597ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HprofStringId LookupClassNameId(mirror::Class* c) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 598dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes return LookupStringId(PrettyDescriptor(c)); 599dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes } 600dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 601bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void WriteFixedHeader() { 6020c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // Write the file header. 6030c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // U1: NUL-terminated magic string. 6043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe const char magic[] = "JAVA PROFILE 1.0.3"; 6053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1List(reinterpret_cast<const uint8_t*>(magic), sizeof(magic)); 6063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6073280517651195602253ed92a2749964e96cad27eCalin Juravle // U4: size of identifiers. We're using addresses as IDs and our heap references are stored 6083280517651195602253ed92a2749964e96cad27eCalin Juravle // as uint32_t. 6093280517651195602253ed92a2749964e96cad27eCalin Juravle // Note of warning: hprof-conv hard-codes the size of identifiers to 4. 610575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe static_assert(sizeof(mirror::HeapReference<mirror::Object>) == sizeof(uint32_t), 611575e78c41ece0dec969d31f46be563d4eb7ae43bAndreas Gampe "Unexpected HeapReference size"); 6123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(sizeof(uint32_t)); 6133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6140c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // The current time, in milliseconds since 0:00 GMT, 1/1/70. 6157b9d996e4cd7d154bb1a244d67139aff0c363cf2Elliott Hughes timeval now; 6163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe const uint64_t nowMs = (gettimeofday(&now, nullptr) < 0) ? 0 : 617ad466adf38db74a9840659626858196091151a64Mathieu Chartier (uint64_t)now.tv_sec * 1000 + now.tv_usec / 1000; 6183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // TODO: It seems it would be correct to use U8. 6190c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // U4: high word of the 64-bit time. 6203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(static_cast<uint32_t>(nowMs >> 32)); 6210c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // U4: low word of the 64-bit time. 6223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(static_cast<uint32_t>(nowMs & 0xFFFFFFFF)); 6230c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 6240c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 625bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier void WriteStackTraces() { 626dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // Write a dummy stack trace record so the analysis tools don't freak out. 627bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_->StartNewRecord(HPROF_TAG_STACK_TRACE, kHprofTime); 6283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(kHprofNullStackTrace); 6293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(kHprofNullThread); 6303a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(0); // no frames 6313a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 6323a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6333a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool DumpToDdmsBuffered(size_t overall_size ATTRIBUTE_UNUSED, size_t max_length ATTRIBUTE_UNUSED) 6340c8c303c20cdaaf54d26e45cc17dc5afb820d8efHiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 6353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(FATAL) << "Unimplemented"; 6363a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe UNREACHABLE(); 6373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // // Send the data off to DDMS. 6383a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iovec iov[2]; 6393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iov[0].iov_base = header_data_ptr_; 6403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iov[0].iov_len = header_data_size_; 6413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iov[1].iov_base = body_data_ptr_; 6423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // iov[1].iov_len = body_data_size_; 6433a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Dbg::DdmSendChunkV(CHUNK_TYPE("HPDS"), iov, 2); 6443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 6453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6463a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool DumpToFile(size_t overall_size, size_t max_length) 6470c8c303c20cdaaf54d26e45cc17dc5afb820d8efHiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 6483a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Where exactly are we writing to? 6493a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe int out_fd; 6503a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (fd_ >= 0) { 6513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe out_fd = dup(fd_); 6523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (out_fd < 0) { 6533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ThrowRuntimeException("Couldn't dump heap; dup(%d) failed: %s", fd_, strerror(errno)); 6543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return false; 6553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 6563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 6573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe out_fd = open(filename_.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 0644); 6583a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (out_fd < 0) { 6593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ThrowRuntimeException("Couldn't dump heap; open(\"%s\") failed: %s", filename_.c_str(), 6603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe strerror(errno)); 6613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return false; 6623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 6633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 6643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe std::unique_ptr<File> file(new File(out_fd, filename_, true)); 6663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool okay; 6673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe { 6683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe FileEndianOutput file_output(file.get(), max_length); 669bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = &file_output; 670bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessHeap(true); 6713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = !file_output.Errors(); 6723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (okay) { 6743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Check for expected size. 6753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK_EQ(file_output.SumLength(), overall_size); 6763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 677bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = nullptr; 6783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 6793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (okay) { 6813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe okay = file->FlushCloseOrErase() == 0; 6823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 6833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe file->Erase(); 6843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 6853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (!okay) { 6863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe std::string msg(StringPrintf("Couldn't dump heap; writing \"%s\" failed: %s", 6873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe filename_.c_str(), strerror(errno))); 6883a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ThrowRuntimeException("%s", msg.c_str()); 6893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(ERROR) << msg; 6903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 6913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return okay; 6933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 6943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 6953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe bool DumpToDdmsDirect(size_t overall_size, size_t max_length, uint32_t chunk_type) 6960c8c303c20cdaaf54d26e45cc17dc5afb820d8efHiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 6973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK(direct_to_ddms_); 6983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe JDWP::JdwpState* state = Dbg::GetJdwpState(); 6993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK(state != nullptr); 7003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe JDWP::JdwpNetStateBase* net_state = state->netState; 7013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK(net_state != nullptr); 7023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7033a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Hold the socket lock for the whole time since we want this to be atomic. 7043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe MutexLock mu(Thread::Current(), *net_state->GetSocketLock()); 7053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Prepare the Ddms chunk. 7073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe constexpr size_t kChunkHeaderSize = kJDWPHeaderLen + 8; 7083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint8_t chunk_header[kChunkHeaderSize] = { 0 }; 7093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe state->SetupChunkHeader(chunk_type, overall_size, kChunkHeaderSize, chunk_header); 7103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Prepare the output and send the chunk header. 7123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe NetStateEndianOutput net_output(net_state, max_length); 713bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = &net_output; 7143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe net_output.AddU1List(chunk_header, kChunkHeaderSize); 7153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Write the dump. 717bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier ProcessHeap(true); 7183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Check for expected size. 7203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK_EQ(net_output.SumLength(), overall_size + kChunkHeaderSize); 721bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier output_ = nullptr; 7223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 7233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return true; 7240c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 7250c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 726dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // If direct_to_ddms_ is set, "filename_" and "fd" will be ignored. 727dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // Otherwise, "filename_" must be valid, though if "fd" >= 0 it will 728dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes // only be used for debug messages. 729dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes std::string filename_; 730dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes int fd_; 731dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes bool direct_to_ddms_; 7320c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 733dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes uint64_t start_ns_; 734dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 735bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier EndianOutput* output_; 736bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier 7377934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom HprofHeapId current_heap_; // Which heap we're currently dumping. 738dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes size_t objects_in_segment_; 739dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 740ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers std::set<mirror::Class*> classes_; 741ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers HprofStringId next_string_id_; 742ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers SafeMap<std::string, HprofStringId> strings_; 743dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes 744dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes DISALLOW_COPY_AND_ASSIGN(Hprof); 745dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes}; 7460c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 7473a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampestatic HprofBasicType SignatureToBasicTypeAndSize(const char* sig, size_t* size_out) { 7480c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson char c = sig[0]; 7490c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson HprofBasicType ret; 7500c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson size_t size; 7510c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 7520c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson switch (c) { 7533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case '[': 7543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'L': 7553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_object; 7563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 4; 7573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 7583a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'Z': 7593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_boolean; 7603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 1; 7613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 7623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'C': 7633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_char; 7643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 2; 7653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 7663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'F': 7673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_float; 7683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 4; 7693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 7703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'D': 7713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_double; 7723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 8; 7733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 7743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'B': 7753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_byte; 7763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 1; 7773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 7783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'S': 7793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_short; 7803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 2; 7813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 7823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'I': 7833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_int; 7843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 4; 7853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 7863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case 'J': 7873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ret = hprof_basic_long; 7883a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size = 8; 7893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 7903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe default: 7913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(FATAL) << "UNREACHABLE"; 7923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe UNREACHABLE(); 7930c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 7940c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 7953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (size_out != nullptr) { 7963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe *size_out = size; 7970c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 7980c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 7990c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson return ret; 8000c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson} 8010c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 8020c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson// Always called when marking objects, but only does 8030c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson// something when ctx->gc_scan_state_ is non-zero, which is usually 8040c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson// only true when marking the root set or unreachable 8050c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson// objects. Used to add rootset references to obj. 8063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampevoid Hprof::MarkRootObject(const mirror::Object* obj, jobject jni_obj, HprofHeapTag heap_tag, 807bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier uint32_t thread_serial) { 8083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (heap_tag == 0) { 8093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return; 8103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 8113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 812bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier CheckHeapSegmentConstraints(); 8133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe switch (heap_tag) { 8153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: object ID 8163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_UNKNOWN: 8173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_STICKY_CLASS: 8183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_MONITOR_USED: 8193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_INTERNED_STRING: 8203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_DEBUGGER: 8213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_VM_INTERNAL: 8223a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(heap_tag); 8233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 8243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 8253a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: object ID 8273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: JNI global ref ID 8283a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_JNI_GLOBAL: 8293a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(heap_tag); 8303a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 8313a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddJniGlobalRefId(jni_obj); 8323a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 8333a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: object ID 8353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: thread serial number 8363a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: frame number in stack trace (-1 for empty) 8373a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_JNI_LOCAL: 8383a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_JNI_MONITOR: 8393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_JAVA_FRAME: 8403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(heap_tag); 8413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 8423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(thread_serial); 8433a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4((uint32_t)-1); 8443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 8453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8463a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: object ID 8473a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: thread serial number 8483a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_NATIVE_STACK: 8493a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_THREAD_BLOCK: 8503a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(heap_tag); 8513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 8523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(thread_serial); 8533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 8543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ID: thread object ID 8563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: thread serial number 8573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // U4: stack trace serial number 8583a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_THREAD_OBJECT: 8593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(heap_tag); 8603a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 8613a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(thread_serial); 8623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4((uint32_t)-1); // xxx 8633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 8643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_CLASS_DUMP: 8663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_INSTANCE_DUMP: 8673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_OBJECT_ARRAY_DUMP: 8683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_PRIMITIVE_ARRAY_DUMP: 8693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_HEAP_DUMP_INFO: 8703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_PRIMITIVE_ARRAY_NODATA_DUMP: 8713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Ignored. 8723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 8733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 8743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_FINALIZING: 8753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_ROOT_REFERENCE_CLEANUP: 8763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe case HPROF_UNREACHABLE: 8773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(FATAL) << "obsolete tag " << static_cast<int>(heap_tag); 8783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 8790c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 8800c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 881dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes ++objects_in_segment_; 8820c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson} 8830c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 8842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersstatic int StackTraceSerialNumber(const mirror::Object* /*obj*/) { 8853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return kHprofNullStackTrace; 8860c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson} 8870c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 888bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::DumpHeapObject(mirror::Object* obj) { 8893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Ignore classes that are retired. 8903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (obj->IsClass() && obj->AsClass()->IsRetired()) { 8913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe return; 8923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 8933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 894e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier gc::Heap* const heap = Runtime::Current()->GetHeap(); 895e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier const gc::space::ContinuousSpace* const space = heap->FindContinuousSpaceFromObject(obj, true); 896ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier HprofHeapId heap_type = HPROF_HEAP_APP; 897ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier if (space != nullptr) { 898ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier if (space->IsZygoteSpace()) { 899ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier heap_type = HPROF_HEAP_ZYGOTE; 900ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier } else if (space->IsImageSpace()) { 901ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier heap_type = HPROF_HEAP_IMAGE; 902ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier } 903e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier } else { 904e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier const auto* los = heap->GetLargeObjectsSpace(); 905e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier if (los->Contains(obj) && los->IsZygoteLargeObject(Thread::Current(), obj)) { 906e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier heap_type = HPROF_HEAP_ZYGOTE; 907e7158116f345df6df73f0df7ebdc2be8e0e4f3e8Mathieu Chartier } 908ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier } 909bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier CheckHeapSegmentConstraints(); 9100c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 911ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier if (heap_type != current_heap_) { 9120c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson HprofStringId nameId; 9130c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 9140c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // This object is in a different heap than the current one. 9150c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // Emit a HEAP_DUMP_INFO tag to change heaps. 9163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_HEAP_DUMP_INFO); 9173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(static_cast<uint32_t>(heap_type)); // uint32_t: heap type 918ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier switch (heap_type) { 9190c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson case HPROF_HEAP_APP: 9200c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson nameId = LookupStringId("app"); 9210c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson break; 9220c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson case HPROF_HEAP_ZYGOTE: 9230c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson nameId = LookupStringId("zygote"); 9240c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson break; 925ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier case HPROF_HEAP_IMAGE: 926ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier nameId = LookupStringId("image"); 927ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier break; 9280c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson default: 9290c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // Internal error 9300c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson LOG(ERROR) << "Unexpected desiredHeap"; 9310c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson nameId = LookupStringId("<ILLEGAL>"); 9320c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson break; 9330c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 9343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddStringId(nameId); 935ae1ad009f7e531aaf95ffbc080a4ad8769c1d4d0Mathieu Chartier current_heap_ = heap_type; 9360c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 9370c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 9382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers mirror::Class* c = obj->GetClass(); 9393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (c == nullptr) { 9402cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // This object will bother HprofReader, because it has a null 9410c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // class, so just don't dump it. It could be 9420c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // gDvm.unlinkedJavaLangClass or it could be an object just 9430c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson // allocated which hasn't been initialized yet. 9440c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } else { 9450c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson if (obj->IsClass()) { 946bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier DumpHeapClass(obj->AsClass()); 9473a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else if (c->IsArrayClass()) { 948bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier DumpHeapArray(obj->AsArray(), c); 9493a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 950bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier DumpHeapInstanceObject(obj, c); 9513a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 9523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 9530c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 9543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe ++objects_in_segment_; 9553a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe} 9560c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 957bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::DumpHeapClass(mirror::Class* klass) { 958ca068b2385ba160367d1e7fd123317b851b99390Sebastien Hertz if (!klass->IsLoaded() && !klass->IsErroneous()) { 959ca068b2385ba160367d1e7fd123317b851b99390Sebastien Hertz // Class is allocated but not yet loaded: we cannot access its fields or super class. 960ca068b2385ba160367d1e7fd123317b851b99390Sebastien Hertz return; 961ca068b2385ba160367d1e7fd123317b851b99390Sebastien Hertz } 9623a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t sFieldCount = klass->NumStaticFields(); 9633a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (sFieldCount != 0) { 9643a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe int byteLength = sFieldCount * sizeof(JValue); // TODO bogus; fields are packed 9653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Create a byte array to reflect the allocation of the 9663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // StaticField array at the end of this class. 9673a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 9683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassStaticsId(klass); 9693a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(StackTraceSerialNumber(klass)); 9703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(byteLength); 9713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(hprof_basic_byte); 9723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (int i = 0; i < byteLength; ++i) { 9733a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(0); 9743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 9753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 9760c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 9773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_CLASS_DUMP); 9783a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassId(LookupClassId(klass)); 9793a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(StackTraceSerialNumber(klass)); 9803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassId(LookupClassId(klass->GetSuperClass())); 9813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(klass->GetClassLoader()); 9823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(nullptr); // no signer 9833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(nullptr); // no prot domain 9843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(nullptr); // reserved 9853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(nullptr); // reserved 9863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (klass->IsClassClass()) { 9873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // ClassObjects have their static fields appended, so aren't all the same size. 9883a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // But they're at least this size. 9893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(sizeof(mirror::Class)); // instance size 9900ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao } else if (klass->IsStringClass()) { 9910ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao // Strings are variable length with character data at the end like arrays. 9920ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao // This outputs the size of an empty string. 9930ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao __ AddU4(sizeof(mirror::String)); 9940ce43539b3bbade7d95482c4da0126a54d5bcba9Jeff Hao } else if (klass->IsArrayClass() || klass->IsPrimitive()) { 9953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(0); 9963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 9973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(klass->GetObjectSize()); // instance size 9983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 9993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU2(0); // empty const pool 10010c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 10023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Static fields 10033a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (sFieldCount == 0) { 10043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU2((uint16_t)0); 10053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 10063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU2((uint16_t)(sFieldCount+1)); 10073a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddStringId(LookupStringId(kStaticOverheadName)); 10083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(hprof_basic_object); 10093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassStaticsId(klass); 10103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (size_t i = 0; i < sFieldCount; ++i) { 1012c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* f = klass->GetStaticField(i); 10133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t size; 10153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); 10163a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddStringId(LookupStringId(f->GetName())); 10173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(t); 101815f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier switch (t) { 101915f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_byte: 1020ff38c04b88e86bffdd520bc1863d05334ada6c94Mathieu Chartier __ AddU1(f->GetByte(klass)); 10213a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 102215f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_boolean: 102315f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier __ AddU1(f->GetBoolean(klass)); 102415f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 102515f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_char: 1026ff38c04b88e86bffdd520bc1863d05334ada6c94Mathieu Chartier __ AddU2(f->GetChar(klass)); 10273a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 102815f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_short: 102915f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier __ AddU2(f->GetShort(klass)); 103015f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 103115f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_float: 103215f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_int: 103315f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_object: 10343a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(f->Get32(klass)); 10353a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 103615f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_double: 103715f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_long: 10383a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU8(f->Get64(klass)); 10393a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe break; 10403a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe default: 10413a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe LOG(FATAL) << "Unexpected size " << size; 10423a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe UNREACHABLE(); 10430c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 10443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 10453a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 10463a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10473a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Instance fields for this class (no superclass fields) 10487c1f53e4253e6acff5e76f00e6bf666518068c4dMathieu Chartier int iFieldCount = klass->NumInstanceFields(); 1049848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (klass->IsStringClass()) { 1050848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU2((uint16_t)iFieldCount + 1); 1051848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } else { 1052848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU2((uint16_t)iFieldCount); 1053848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 10543a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (int i = 0; i < iFieldCount; ++i) { 1055c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* f = klass->GetInstanceField(i); 10563a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddStringId(LookupStringId(f->GetName())); 10573a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HprofBasicType t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), nullptr); 10583a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(t); 10593a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 1060848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Add native value character array for strings. 1061848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (klass->IsStringClass()) { 1062848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddStringId(LookupStringId("value")); 1063848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU1(hprof_basic_object); 1064848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 10653a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe} 10663a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 1067bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::DumpHeapArray(mirror::Array* obj, mirror::Class* klass) { 10683a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe uint32_t length = obj->GetLength(); 10690c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 10703a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (obj->IsObjectArray()) { 10713a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // obj is an object array. 10723a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_OBJECT_ARRAY_DUMP); 10730c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 10743a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 10753a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(StackTraceSerialNumber(obj)); 10763a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(length); 10773a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassId(LookupClassId(klass)); 10780c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 10792cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Dump the elements, which are always objects or null. 10803a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddIdList(obj->AsObjectArray<mirror::Object>()); 10813a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else { 10823a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t size; 10833a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe HprofBasicType t = SignatureToBasicTypeAndSize( 10843a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe Primitive::Descriptor(klass->GetComponentType()->GetPrimitiveType()), &size); 10853a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10863a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // obj is a primitive array. 10873a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 10883a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10893a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 10903a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(StackTraceSerialNumber(obj)); 10913a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(length); 10923a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(t); 10933a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 10943a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Dump the raw, packed element values. 10953a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (size == 1) { 10963a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1List(reinterpret_cast<const uint8_t*>(obj->GetRawData(sizeof(uint8_t), 0)), length); 10973a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else if (size == 2) { 10983a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU2List(reinterpret_cast<const uint16_t*>(obj->GetRawData(sizeof(uint16_t), 0)), length); 10993a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else if (size == 4) { 11003a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4List(reinterpret_cast<const uint32_t*>(obj->GetRawData(sizeof(uint32_t), 0)), length); 11013a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } else if (size == 8) { 11023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU8List(reinterpret_cast<const uint64_t*>(obj->GetRawData(sizeof(uint64_t), 0)), length); 11033a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 11043a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe } 11053a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe} 11063a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 1107bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::DumpHeapInstanceObject(mirror::Object* obj, mirror::Class* klass) { 11083a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // obj is an instance object. 11093a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU1(HPROF_INSTANCE_DUMP); 11103a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddObjectId(obj); 11113a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(StackTraceSerialNumber(obj)); 11123a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddClassId(LookupClassId(klass)); 11133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 11143a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Reserve some space for the length of the instance data, which we won't 11153a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // know until we're done writing it. 1116bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier size_t size_patch_offset = output_->Length(); 11173a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(0x77777777); 11183a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 11193a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // Write the instance data; fields for this class, followed by super class fields, 11203a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe // and so on. Don't write the klass or monitor fields of Object.class. 1121848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao mirror::Class* orig_klass = klass; 11227c1f53e4253e6acff5e76f00e6bf666518068c4dMathieu Chartier do { 11233a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe int ifieldCount = klass->NumInstanceFields(); 11243a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe for (int i = 0; i < ifieldCount; ++i) { 1125c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier ArtField* f = klass->GetInstanceField(i); 11263a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe size_t size; 112715f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier auto t = SignatureToBasicTypeAndSize(f->GetTypeDescriptor(), &size); 112815f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier switch (t) { 112915f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_byte: 1130ff38c04b88e86bffdd520bc1863d05334ada6c94Mathieu Chartier __ AddU1(f->GetByte(obj)); 113115f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 113215f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_boolean: 113315f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier __ AddU1(f->GetBoolean(obj)); 113415f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 113515f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_char: 1136ff38c04b88e86bffdd520bc1863d05334ada6c94Mathieu Chartier __ AddU2(f->GetChar(obj)); 113715f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 113815f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_short: 113915f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier __ AddU2(f->GetShort(obj)); 114015f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 114115f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_float: 114215f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_int: 114315f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_object: 11443a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU4(f->Get32(obj)); 114515f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 114615f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_double: 114715f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier case hprof_basic_long: 11483a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe __ AddU8(f->Get64(obj)); 114915f345cdfaebe480de6387b67d4be4eb5f106870Mathieu Chartier break; 11500c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 11510c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson } 11523a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe 11533a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe klass = klass->GetSuperClass(); 11547c1f53e4253e6acff5e76f00e6bf666518068c4dMathieu Chartier } while (klass != nullptr); 11550c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 1156848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Output native value character array for strings. 1157848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao if (orig_klass->IsStringClass()) { 1158848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao mirror::String* s = obj->AsString(); 115990bcbd50aca23331869f64a2ecb8e6c292c127ffJeff Hao mirror::Object* value; 116090bcbd50aca23331869f64a2ecb8e6c292c127ffJeff Hao if (s->GetLength() == 0) { 116190bcbd50aca23331869f64a2ecb8e6c292c127ffJeff Hao // If string is empty, use an object-aligned address within the string for the value. 116290bcbd50aca23331869f64a2ecb8e6c292c127ffJeff Hao value = reinterpret_cast<mirror::Object*>(reinterpret_cast<uintptr_t>(s) + kObjectAlignment); 116390bcbd50aca23331869f64a2ecb8e6c292c127ffJeff Hao } else { 116490bcbd50aca23331869f64a2ecb8e6c292c127ffJeff Hao value = reinterpret_cast<mirror::Object*>(s->GetValue()); 116590bcbd50aca23331869f64a2ecb8e6c292c127ffJeff Hao } 116690bcbd50aca23331869f64a2ecb8e6c292c127ffJeff Hao __ AddObjectId(value); 1167848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 1168848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Patch the instance field length. 1169848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ UpdateU4(size_patch_offset, output_->Length() - (size_patch_offset + 4)); 1170848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 1171848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU1(HPROF_PRIMITIVE_ARRAY_DUMP); 117290bcbd50aca23331869f64a2ecb8e6c292c127ffJeff Hao __ AddObjectId(value); 1173848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU4(StackTraceSerialNumber(obj)); 1174848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU4(s->GetLength()); 1175848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU1(hprof_basic_char); 1176848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ AddU2List(s->GetValue(), s->GetLength()); 1177848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } else { 1178848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // Patch the instance field length. 1179848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao __ UpdateU4(size_patch_offset, output_->Length() - (size_patch_offset + 4)); 1180848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao } 11810c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson} 11820c54ac102a3c489d284a8db5d91189da5b455c40Jesse Wilson 1183bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartiervoid Hprof::VisitRoot(mirror::Object* obj, const RootInfo& info) { 11840b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson static const HprofHeapTag xlate[] = { 11850b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_UNKNOWN, 11860b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_JNI_GLOBAL, 11870b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_JNI_LOCAL, 11880b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_JAVA_FRAME, 11890b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_NATIVE_STACK, 11900b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_STICKY_CLASS, 11910b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_THREAD_BLOCK, 11920b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_MONITOR_USED, 11930b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_THREAD_OBJECT, 11940b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_INTERNED_STRING, 11950b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_FINALIZING, 11960b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_DEBUGGER, 11970b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_REFERENCE_CLEANUP, 11980b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_VM_INTERNAL, 11990b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson HPROF_ROOT_JNI_MONITOR, 12000b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson }; 1201e34fa1df67fbe0173b4ea9abddcc3ae3d0537037Mathieu Chartier CHECK_LT(info.GetType(), sizeof(xlate) / sizeof(HprofHeapTag)); 12023a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe if (obj == nullptr) { 12030b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson return; 12040b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson } 1205bb87e0f1a52de656bc77cb01cb887e51a0e5198bMathieu Chartier MarkRootObject(obj, 0, xlate[info.GetType()], info.GetThreadId()); 1206c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson} 1207c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 1208dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes// If "direct_to_ddms" is true, the other arguments are ignored, and data is 1209dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes// sent directly to DDMS. 1210dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes// If "fd" is >= 0, the output will be written to that file descriptor. 1211dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes// Otherwise, "filename" is used to create an output file. 1212dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughesvoid DumpHeap(const char* filename, int fd, bool direct_to_ddms) { 12133a91309c30a7575776526ffe6e9a46dc648a59feAndreas Gampe CHECK(filename != nullptr); 12140b075f18e69959f5afbe6d815a766df082ec99dfJesse Wilson 12152cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi Thread* self = Thread::Current(); 12162cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi gc::Heap* heap = Runtime::Current()->GetHeap(); 12172cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (heap->IsGcConcurrentAndMoving()) { 12182cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // Need to take a heap dump while GC isn't running. See the 12192cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi // comment in Heap::VisitObjects(). 12202cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi heap->IncrementDisableMovingGC(self); 12212cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1222bf44d42d978861f33fd5978f49392db3321ae414Mathieu Chartier Runtime::Current()->GetThreadList()->SuspendAll(__FUNCTION__, true /* long suspend */); 1223dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes Hprof hprof(filename, fd, direct_to_ddms); 1224dcfdd2b03af29dcaf234d062a79acb919f130435Elliott Hughes hprof.Dump(); 122500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers Runtime::Current()->GetThreadList()->ResumeAll(); 12262cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi if (heap->IsGcConcurrentAndMoving()) { 12272cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi heap->DecrementDisableMovingGC(self); 12282cd334ae2d4287216523882f0d298cf3901b7ab1Hiroshi Yamauchi } 1229c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson} 1230c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson 1231ad466adf38db74a9840659626858196091151a64Mathieu Chartier} // namespace hprof 1232c4824e60fef6cb9fdf0f8442408338f4141e09deJesse Wilson} // namespace art 1233