blob: 94852bcc6d7fb0463b7c09609e0befba0d04470b [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>
20#include "globals.h"
21#include "file.h"
22#include "object.h"
Jesse Wilson3aa66fd2011-11-08 20:53:40 -050023#include "unordered_map.h"
24#include "unordered_set.h"
Jesse Wilsonc4824e62011-11-01 14:39:04 -040025
26namespace art {
27
28namespace hprof {
29
30#define HPROF_ID_SIZE (sizeof (uint32_t))
31
32#define UNIQUE_ERROR() \
33 -((((uintptr_t)__func__) << 16 | __LINE__) & (0x7fffffff))
34
35#define HPROF_TIME 0
36#define HPROF_NULL_STACK_TRACE 0
37#define HPROF_NULL_THREAD 0
38
Jesse Wilson3aa66fd2011-11-08 20:53:40 -050039typedef uint32_t HprofId;
40typedef HprofId HprofStringId;
41typedef HprofId HprofObjectId;
42typedef HprofId HprofClassObjectId;
43typedef std::tr1::unordered_set<Class*, ObjectIdentityHash> ClassSet;
44typedef std::tr1::unordered_set<Class*, ObjectIdentityHash>::iterator ClassSetIterator;
45typedef std::tr1::unordered_map<std::string, size_t> StringMap;
46typedef std::tr1::unordered_map<std::string, size_t>::iterator StringMapIterator;
Jesse Wilsonc4824e62011-11-01 14:39:04 -040047
Jesse Wilson3aa66fd2011-11-08 20:53:40 -050048enum HprofBasicType {
Jesse Wilsonc4824e62011-11-01 14:39:04 -040049 hprof_basic_object = 2,
50 hprof_basic_boolean = 4,
51 hprof_basic_char = 5,
52 hprof_basic_float = 6,
53 hprof_basic_double = 7,
54 hprof_basic_byte = 8,
55 hprof_basic_short = 9,
56 hprof_basic_int = 10,
57 hprof_basic_long = 11,
58};
59
Jesse Wilson3aa66fd2011-11-08 20:53:40 -050060enum HprofTag {
Jesse Wilsonc4824e62011-11-01 14:39:04 -040061 HPROF_TAG_STRING = 0x01,
62 HPROF_TAG_LOAD_CLASS = 0x02,
63 HPROF_TAG_UNLOAD_CLASS = 0x03,
64 HPROF_TAG_STACK_FRAME = 0x04,
65 HPROF_TAG_STACK_TRACE = 0x05,
66 HPROF_TAG_ALLOC_SITES = 0x06,
67 HPROF_TAG_HEAP_SUMMARY = 0x07,
68 HPROF_TAG_START_THREAD = 0x0A,
69 HPROF_TAG_END_THREAD = 0x0B,
70 HPROF_TAG_HEAP_DUMP = 0x0C,
71 HPROF_TAG_HEAP_DUMP_SEGMENT = 0x1C,
72 HPROF_TAG_HEAP_DUMP_END = 0x2C,
73 HPROF_TAG_CPU_SAMPLES = 0x0D,
74 HPROF_TAG_CONTROL_SETTINGS = 0x0E,
75};
76
77/* Values for the first byte of
78 * HEAP_DUMP and HEAP_DUMP_SEGMENT
79 * records:
80 */
Jesse Wilson3aa66fd2011-11-08 20:53:40 -050081enum HprofHeapTag {
Jesse Wilsonc4824e62011-11-01 14:39:04 -040082 /* standard */
83 HPROF_ROOT_UNKNOWN = 0xFF,
84 HPROF_ROOT_JNI_GLOBAL = 0x01,
85 HPROF_ROOT_JNI_LOCAL = 0x02,
86 HPROF_ROOT_JAVA_FRAME = 0x03,
87 HPROF_ROOT_NATIVE_STACK = 0x04,
88 HPROF_ROOT_STICKY_CLASS = 0x05,
89 HPROF_ROOT_THREAD_BLOCK = 0x06,
90 HPROF_ROOT_MONITOR_USED = 0x07,
91 HPROF_ROOT_THREAD_OBJECT = 0x08,
92 HPROF_CLASS_DUMP = 0x20,
93 HPROF_INSTANCE_DUMP = 0x21,
94 HPROF_OBJECT_ARRAY_DUMP = 0x22,
95 HPROF_PRIMITIVE_ARRAY_DUMP = 0x23,
96
97 /* Android */
98 HPROF_HEAP_DUMP_INFO = 0xfe,
99 HPROF_ROOT_INTERNED_STRING = 0x89,
100 HPROF_ROOT_FINALIZING = 0x8a, /* obsolete */
101 HPROF_ROOT_DEBUGGER = 0x8b,
102 HPROF_ROOT_REFERENCE_CLEANUP = 0x8c, /* obsolete */
103 HPROF_ROOT_VM_INTERNAL = 0x8d,
104 HPROF_ROOT_JNI_MONITOR = 0x8e,
105 HPROF_UNREACHABLE = 0x90, /* obsolete */
106 HPROF_PRIMITIVE_ARRAY_NODATA_DUMP = 0xc3,
107};
108
109/* Represents a top-level hprof record, whose serialized
110 * format is:
111 *
112 * uint8_t TAG: denoting the type of the record
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500113 * uint32_t TIME: number of microseconds since the time stamp in the header
114 * uint32_t LENGTH: number of bytes that follow this uint32_t field
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400115 * and belong to this record
116 * [uint8_t]* BODY: as many bytes as specified in the above uint32_t field
117 */
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500118class HprofRecord {
119 public:
120 int Flush(FILE *fp);
121 int AddU1(uint8_t value);
122 int AddU2(uint16_t value);
123 int AddU4(uint32_t value);
124 int AddU8(uint64_t value);
125 int AddId(HprofObjectId value);
126 int AddU1List(const uint8_t *values, size_t numValues);
127 int AddU2List(const uint16_t *values, size_t numValues);
128 int AddU4List(const uint32_t *values, size_t numValues);
129 int AddU8List(const uint64_t *values, size_t numValues);
130 int AddIdList(const HprofObjectId *values, size_t numValues);
131 int AddUtf8String(const char *str);
132
133 unsigned char *body_;
134 uint32_t time_;
135 uint32_t length_;
136 size_t alloc_length_;
137 uint8_t tag_;
138 bool dirty_;
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400139};
140
141enum HprofHeapId {
142 HPROF_HEAP_DEFAULT = 0,
143 HPROF_HEAP_ZYGOTE = 'Z',
144 HPROF_HEAP_APP = 'A'
145};
146
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500147class Hprof {
148 public:
149 Hprof(const char *outputFileName, int fd, bool writeHeader, bool directToDdms);
150 ~Hprof();
151
152 void VisitRoot(const Object* obj);
153 int DumpHeapObject(const Object *obj);
154 bool Finish();
155
156 private:
157 int DumpClasses();
158 int DumpStrings();
159 int StartNewRecord(uint8_t tag, uint32_t time);
160 int FlushCurrentRecord();
161 int MarkRootObject(const Object *obj, jobject jniObj);
162 HprofClassObjectId LookupClassId(Class* clazz);
163 HprofStringId LookupStringId(String* string);
164 HprofStringId LookupStringId(const char* string);
165 HprofStringId LookupStringId(std::string string);
166 HprofStringId LookupClassNameId(Class* clazz);
167
168 /* current_record_ *must* be first so that we
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400169 * can cast from a context to a record.
170 */
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500171 HprofRecord current_record_;
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400172
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500173 uint32_t gc_thread_serial_number_;
174 uint8_t gc_scan_state_;
175 HprofHeapId current_heap_; // which heap we're currently emitting
176 size_t objects_in_segment_;
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400177
178 /*
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500179 * If direct_to_ddms_ is set, "file_name_" and "fd" will be ignored.
180 * Otherwise, "file_name_" must be valid, though if "fd" >= 0 it will
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400181 * only be used for debug messages.
182 */
Jesse Wilson3aa66fd2011-11-08 20:53:40 -0500183 bool direct_to_ddms_;
184 char *file_name_;
185 char *file_data_ptr_; // for open_memstream
186 size_t file_data_size_; // for open_memstream
187 FILE *mem_fp_;
188 int fd_;
189
190 mutable Mutex classes_lock_;
191 ClassSet classes_;
192
193 size_t next_string_id_;
194 mutable Mutex strings_lock_;
195 StringMap strings_;
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400196};
197
Elliott Hughesfbd84562011-11-07 18:56:13 -0800198int DumpHeap(const char* fileName, int fd, bool directToDdms);
Jesse Wilsonc4824e62011-11-01 14:39:04 -0400199
200} // namespace hprof
201
202} // namespace art
203
204#endif // HPROF_HPROF_H_