blob: e2f7ce1f05d6ba5a9a289aa0903eed439e0d2efd [file] [log] [blame]
Jesse Wilsonc4824e62011-11-01 14:39:04 -04001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#ifndef HPROF_HPROF_H_
17#define HPROF_HPROF_H_
18
19#include <stdio.h>
Elliott Hughese5448b52012-01-18 16:44:06 -080020
Elliott Hughese5448b52012-01-18 16:44:06 -080021#include <set>
22
Jesse Wilsonc4824e62011-11-01 14:39:04 -040023#include "file.h"
Elliott Hughese5448b52012-01-18 16:44:06 -080024#include "globals.h"
Jesse Wilsonc4824e62011-11-01 14:39:04 -040025#include "object.h"
Elliott Hughesa0e18062012-04-13 15:59:59 -070026#include "safe_map.h"
Jesse Wilson0c54ac12011-11-09 15:14:05 -050027#include "thread_list.h"
Jesse Wilsonc4824e62011-11-01 14:39:04 -040028
29namespace art {
30
31namespace hprof {
32
33#define HPROF_ID_SIZE (sizeof (uint32_t))
34
35#define UNIQUE_ERROR() \
36 -((((uintptr_t)__func__) << 16 | __LINE__) & (0x7fffffff))
37
38#define HPROF_TIME 0
39#define HPROF_NULL_STACK_TRACE 0
40#define HPROF_NULL_THREAD 0
41
Jesse Wilson0c54ac12011-11-09 15:14:05 -050042#define U2_TO_BUF_BE(buf, offset, value) \
43 do { \
Elliott Hughesc1f143d2011-12-01 17:31:10 -080044 unsigned char* buf_ = (unsigned char*)(buf); \
Jesse Wilson0c54ac12011-11-09 15:14:05 -050045 int offset_ = (int)(offset); \
46 uint16_t value_ = (uint16_t)(value); \
47 buf_[offset_ + 0] = (unsigned char)(value_ >> 8); \
48 buf_[offset_ + 1] = (unsigned char)(value_ ); \
49 } while (0)
50
51#define U4_TO_BUF_BE(buf, offset, value) \
52 do { \
Elliott Hughesc1f143d2011-12-01 17:31:10 -080053 unsigned char* buf_ = (unsigned char*)(buf); \
Jesse Wilson0c54ac12011-11-09 15:14:05 -050054 int offset_ = (int)(offset); \
55 uint32_t value_ = (uint32_t)(value); \
56 buf_[offset_ + 0] = (unsigned char)(value_ >> 24); \
57 buf_[offset_ + 1] = (unsigned char)(value_ >> 16); \
58 buf_[offset_ + 2] = (unsigned char)(value_ >> 8); \
59 buf_[offset_ + 3] = (unsigned char)(value_ ); \
60 } while (0)
61
62#define U8_TO_BUF_BE(buf, offset, value) \
63 do { \
Elliott Hughesc1f143d2011-12-01 17:31:10 -080064 unsigned char* buf_ = (unsigned char*)(buf); \
Jesse Wilson0c54ac12011-11-09 15:14:05 -050065 int offset_ = (int)(offset); \
66 uint64_t value_ = (uint64_t)(value); \
67 buf_[offset_ + 0] = (unsigned char)(value_ >> 56); \
68 buf_[offset_ + 1] = (unsigned char)(value_ >> 48); \
69 buf_[offset_ + 2] = (unsigned char)(value_ >> 40); \
70 buf_[offset_ + 3] = (unsigned char)(value_ >> 32); \
71 buf_[offset_ + 4] = (unsigned char)(value_ >> 24); \
72 buf_[offset_ + 5] = (unsigned char)(value_ >> 16); \
73 buf_[offset_ + 6] = (unsigned char)(value_ >> 8); \
74 buf_[offset_ + 7] = (unsigned char)(value_ ); \
75 } while (0)
76
Jesse Wilson3aa66fd2011-11-08 20:53:40 -050077typedef uint32_t HprofId;
78typedef HprofId HprofStringId;
79typedef HprofId HprofObjectId;
80typedef HprofId HprofClassObjectId;
Elliott Hughese5448b52012-01-18 16:44:06 -080081typedef std::set<Class*> ClassSet;
82typedef std::set<Class*>::iterator ClassSetIterator;
Elliott Hughesa0e18062012-04-13 15:59:59 -070083typedef SafeMap<std::string, size_t> StringMap;
84typedef SafeMap<std::string, size_t>::iterator StringMapIterator;
Jesse Wilsonc4824e62011-11-01 14:39:04 -040085
Jesse Wilson3aa66fd2011-11-08 20:53:40 -050086enum HprofBasicType {
Jesse Wilson0b075f12011-11-09 10:57:41 -050087 hprof_basic_object = 2,
88 hprof_basic_boolean = 4,
89 hprof_basic_char = 5,
90 hprof_basic_float = 6,
91 hprof_basic_double = 7,
92 hprof_basic_byte = 8,
93 hprof_basic_short = 9,
94 hprof_basic_int = 10,
95 hprof_basic_long = 11,
Jesse Wilsonc4824e62011-11-01 14:39:04 -040096};
97
Jesse Wilson3aa66fd2011-11-08 20:53:40 -050098enum HprofTag {
Jesse Wilson0b075f12011-11-09 10:57:41 -050099 HPROF_TAG_STRING = 0x01,
100 HPROF_TAG_LOAD_CLASS = 0x02,
101 HPROF_TAG_UNLOAD_CLASS = 0x03,
102 HPROF_TAG_STACK_FRAME = 0x04,
103 HPROF_TAG_STACK_TRACE = 0x05,
104 HPROF_TAG_ALLOC_SITES = 0x06,
105 HPROF_TAG_HEAP_SUMMARY = 0x07,
106 HPROF_TAG_START_THREAD = 0x0A,
107 HPROF_TAG_END_THREAD = 0x0B,
108 HPROF_TAG_HEAP_DUMP = 0x0C,
109 HPROF_TAG_HEAP_DUMP_SEGMENT = 0x1C,
110 HPROF_TAG_HEAP_DUMP_END = 0x2C,
111 HPROF_TAG_CPU_SAMPLES = 0x0D,
112 HPROF_TAG_CONTROL_SETTINGS = 0x0E,
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400113};
114
Jesse Wilson0b075f12011-11-09 10:57:41 -0500115// Values for the first byte of HEAP_DUMP and HEAP_DUMP_SEGMENT records:
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500116enum HprofHeapTag {
Jesse Wilson0b075f12011-11-09 10:57:41 -0500117 /* standard */
118 HPROF_ROOT_UNKNOWN = 0xFF,
119 HPROF_ROOT_JNI_GLOBAL = 0x01,
120 HPROF_ROOT_JNI_LOCAL = 0x02,
121 HPROF_ROOT_JAVA_FRAME = 0x03,
122 HPROF_ROOT_NATIVE_STACK = 0x04,
123 HPROF_ROOT_STICKY_CLASS = 0x05,
124 HPROF_ROOT_THREAD_BLOCK = 0x06,
125 HPROF_ROOT_MONITOR_USED = 0x07,
126 HPROF_ROOT_THREAD_OBJECT = 0x08,
127 HPROF_CLASS_DUMP = 0x20,
128 HPROF_INSTANCE_DUMP = 0x21,
129 HPROF_OBJECT_ARRAY_DUMP = 0x22,
130 HPROF_PRIMITIVE_ARRAY_DUMP = 0x23,
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400131
Jesse Wilson0b075f12011-11-09 10:57:41 -0500132 /* Android */
133 HPROF_HEAP_DUMP_INFO = 0xfe,
134 HPROF_ROOT_INTERNED_STRING = 0x89,
135 HPROF_ROOT_FINALIZING = 0x8a, /* obsolete */
136 HPROF_ROOT_DEBUGGER = 0x8b,
137 HPROF_ROOT_REFERENCE_CLEANUP = 0x8c, /* obsolete */
138 HPROF_ROOT_VM_INTERNAL = 0x8d,
139 HPROF_ROOT_JNI_MONITOR = 0x8e,
140 HPROF_UNREACHABLE = 0x90, /* obsolete */
141 HPROF_PRIMITIVE_ARRAY_NODATA_DUMP = 0xc3,
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400142};
143
Jesse Wilson0b075f12011-11-09 10:57:41 -0500144// Represents a top-level hprof record, whose serialized format is:
145// U1 TAG: denoting the type of the record
146// U4 TIME: number of microseconds since the time stamp in the header
147// U4 LENGTH: number of bytes that follow this uint32_t field and belong to this record
148// U1* BODY: as many bytes as specified in the above uint32_t field
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500149class HprofRecord {
Jesse Wilson0b075f12011-11-09 10:57:41 -0500150 public:
151 int Flush(FILE *fp);
152 int AddU1(uint8_t value);
153 int AddU2(uint16_t value);
154 int AddU4(uint32_t value);
155 int AddU8(uint64_t value);
156 int AddId(HprofObjectId value);
157 int AddU1List(const uint8_t *values, size_t numValues);
158 int AddU2List(const uint16_t *values, size_t numValues);
159 int AddU4List(const uint32_t *values, size_t numValues);
160 int AddU8List(const uint64_t *values, size_t numValues);
161 int AddIdList(const HprofObjectId *values, size_t numValues);
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800162 int AddUtf8String(const char* str);
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500163
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800164 unsigned char* body_;
Jesse Wilson0b075f12011-11-09 10:57:41 -0500165 uint32_t time_;
166 uint32_t length_;
167 size_t alloc_length_;
168 uint8_t tag_;
169 bool dirty_;
Jesse Wilson0c54ac12011-11-09 15:14:05 -0500170
171 private:
172 int GuaranteeRecordAppend(size_t nmore);
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400173};
174
175enum HprofHeapId {
Jesse Wilson0b075f12011-11-09 10:57:41 -0500176 HPROF_HEAP_DEFAULT = 0,
177 HPROF_HEAP_ZYGOTE = 'Z',
178 HPROF_HEAP_APP = 'A'
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400179};
180
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500181class Hprof {
Jesse Wilson0b075f12011-11-09 10:57:41 -0500182 public:
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800183 Hprof(const char* outputFileName, int fd, bool writeHeader, bool directToDdms);
Jesse Wilson0b075f12011-11-09 10:57:41 -0500184 ~Hprof();
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500185
Jesse Wilson0b075f12011-11-09 10:57:41 -0500186 void VisitRoot(const Object* obj);
187 int DumpHeapObject(const Object *obj);
188 bool Finish();
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500189
Jesse Wilson0b075f12011-11-09 10:57:41 -0500190 private:
191 int DumpClasses();
192 int DumpStrings();
193 int StartNewRecord(uint8_t tag, uint32_t time);
194 int FlushCurrentRecord();
195 int MarkRootObject(const Object *obj, jobject jniObj);
Elliott Hughese84278b2012-03-22 10:06:53 -0700196 HprofClassObjectId LookupClassId(Class* c);
Jesse Wilson0b075f12011-11-09 10:57:41 -0500197 HprofStringId LookupStringId(String* string);
198 HprofStringId LookupStringId(const char* string);
Elliott Hughesae80b492012-04-24 10:43:17 -0700199 HprofStringId LookupStringId(const std::string& string);
Elliott Hughese84278b2012-03-22 10:06:53 -0700200 HprofStringId LookupClassNameId(Class* c);
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800201 static HprofBasicType SignatureToBasicTypeAndSize(const char* sig, size_t* sizeOut);
202 static HprofBasicType PrimitiveToBasicTypeAndSize(Primitive::Type prim, size_t* sizeOut);
Jesse Wilson0c54ac12011-11-09 15:14:05 -0500203 static int StackTraceSerialNumber(const void *obj);
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500204
Jesse Wilson0b075f12011-11-09 10:57:41 -0500205 // current_record_ *must* be first so that we can cast from a context to a record.
206 HprofRecord current_record_;
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400207
Jesse Wilson0b075f12011-11-09 10:57:41 -0500208 uint32_t gc_thread_serial_number_;
209 uint8_t gc_scan_state_;
210 HprofHeapId current_heap_; // which heap we're currently emitting
211 size_t objects_in_segment_;
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400212
Jesse Wilson0b075f12011-11-09 10:57:41 -0500213 // If direct_to_ddms_ is set, "file_name_" and "fd" will be ignored.
214 // Otherwise, "file_name_" must be valid, though if "fd" >= 0 it will
215 // only be used for debug messages.
216 bool direct_to_ddms_;
Elliott Hughes7b3cdfc2011-12-08 21:28:17 -0800217 std::string file_name_;
Elliott Hughesc1f143d2011-12-01 17:31:10 -0800218 char* file_data_ptr_; // for open_memstream
Jesse Wilson0b075f12011-11-09 10:57:41 -0500219 size_t file_data_size_; // for open_memstream
220 FILE *mem_fp_;
221 int fd_;
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500222
Jesse Wilson0b075f12011-11-09 10:57:41 -0500223 ClassSet classes_;
Jesse Wilson0b075f12011-11-09 10:57:41 -0500224 size_t next_string_id_;
Jesse Wilson0b075f12011-11-09 10:57:41 -0500225 StringMap strings_;
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400226};
227
Elliott Hughesfbd84562011-11-07 18:56:13 -0800228int DumpHeap(const char* fileName, int fd, bool directToDdms);
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400229
230} // namespace hprof
231
232} // namespace art
233
234#endif // HPROF_HPROF_H_