• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 /*
17  * Types and macros used internally by the heap.
18  */
19 #ifndef _DALVIK_ALLOC_HEAP_INTERNAL
20 #define _DALVIK_ALLOC_HEAP_INTERNAL
21 
22 #include <time.h>  // for struct timespec
23 
24 #include "HeapTable.h"
25 #include "MarkSweep.h"
26 
27 #define SCHEDULED_REFERENCE_MAGIC   ((Object*)0x87654321)
28 
29 #define ptr2chunk(p)    (((DvmHeapChunk *)(p)) - 1)
30 #define chunk2ptr(p)    ((void *)(((DvmHeapChunk *)(p)) + 1))
31 
32 #define WITH_OBJECT_HEADERS 0
33 #if WITH_OBJECT_HEADERS
34 #define OBJECT_HEADER   0x11335577
35 extern u2 gGeneration;
36 #endif
37 
38 typedef struct DvmHeapChunk {
39 #if WITH_OBJECT_HEADERS
40     u4 header;
41     const Object *parent;
42     const Object *parentOld;
43     const Object *markFinger;
44     const Object *markFingerOld;
45     u2 birthGeneration;
46     u2 markCount;
47     u2 scanCount;
48     u2 oldMarkGeneration;
49     u2 markGeneration;
50     u2 oldScanGeneration;
51     u2 scanGeneration;
52 #endif
53 #if WITH_HPROF && WITH_HPROF_STACK
54     u4 stackTraceSerialNumber;
55 #endif
56     u8 data[0];
57 } DvmHeapChunk;
58 
59 struct GcHeap {
60     HeapSource      *heapSource;
61 
62     /* List of heap objects that the GC should never collect.
63      * These should be included in the root set of objects.
64      */
65     HeapRefTable    nonCollectableRefs;
66 
67     /* List of heap objects that will require finalization when
68      * collected.  I.e., instance objects
69      *
70      *     a) whose class definitions override java.lang.Object.finalize()
71      *
72      * *** AND ***
73      *
74      *     b) that have never been finalized.
75      *
76      * Note that this does not exclude non-garbage objects;  this
77      * is not the list of pending finalizations, but of objects that
78      * potentially have finalization in their futures.
79      */
80     LargeHeapRefTable  *finalizableRefs;
81 
82     /* The list of objects that need to have finalize() called
83      * on themselves.  These references are part of the root set.
84      *
85      * This table is protected by gDvm.heapWorkerListLock, which must
86      * be acquired after the heap lock.
87      */
88     LargeHeapRefTable  *pendingFinalizationRefs;
89 
90     /* Linked lists of subclass instances of java/lang/ref/Reference
91      * that we find while recursing.  The "next" pointers are hidden
92      * in the objects' <code>int Reference.vmData</code> fields.
93      * These lists are cleared and rebuilt each time the GC runs.
94      */
95     Object         *softReferences;
96     Object         *weakReferences;
97     Object         *phantomReferences;
98 
99     /* The list of Reference objects that need to be cleared and/or
100      * enqueued.  The bottom two bits of the object pointers indicate
101      * whether they should be cleared and/or enqueued.
102      *
103      * This table is protected by gDvm.heapWorkerListLock, which must
104      * be acquired after the heap lock.
105      */
106     LargeHeapRefTable  *referenceOperations;
107 
108     /* If non-null, the method that the HeapWorker is currently
109      * executing.
110      */
111     Object *heapWorkerCurrentObject;
112     Method *heapWorkerCurrentMethod;
113 
114     /* If heapWorkerCurrentObject is non-null, this gives the time when
115      * HeapWorker started executing that method.  The time value must come
116      * from dvmGetRelativeTimeUsec().
117      *
118      * The "Cpu" entry tracks the per-thread CPU timer (when available).
119      */
120     u8 heapWorkerInterpStartTime;
121     u8 heapWorkerInterpCpuStartTime;
122 
123     /* If any fields are non-zero, indicates the next (absolute) time that
124      * the HeapWorker thread should call dvmHeapSourceTrim().
125      */
126     struct timespec heapWorkerNextTrim;
127 
128     /* The current state of the mark step.
129      * Only valid during a GC.
130      */
131     GcMarkContext   markContext;
132 
133     /* Set to dvmGetRelativeTimeUsec() whenever a GC begins.
134      * The value is preserved between GCs, so it can be used
135      * to determine the time between successive GCs.
136      * Initialized to zero before the first GC.
137      */
138     u8              gcStartTime;
139 
140     /* Is the GC running?  Used to avoid recursive calls to GC.
141      */
142     bool            gcRunning;
143 
144     /* Set at the end of a GC to indicate the collection policy
145      * for SoftReferences during the following GC.
146      */
147     enum { SR_COLLECT_NONE, SR_COLLECT_SOME, SR_COLLECT_ALL }
148                     softReferenceCollectionState;
149 
150     /* The size of the heap is compared against this value
151      * to determine when to start collecting SoftReferences.
152      */
153     size_t          softReferenceHeapSizeThreshold;
154 
155     /* A value that will increment every time we see a SoftReference
156      * whose referent isn't marked (during SR_COLLECT_SOME).
157      * The absolute value is meaningless, and does not need to
158      * be reset or initialized at any point.
159      */
160     int             softReferenceColor;
161 
162     /* Indicates whether or not the object scanner should bother
163      * keeping track of any references.  If markAllReferents is
164      * true, referents will be hard-marked.  If false, normal
165      * reference following is used.
166      */
167     bool            markAllReferents;
168 
169 #if DVM_TRACK_HEAP_MARKING
170     /* Every time an unmarked object becomes marked, markCount
171      * is incremented and markSize increases by the size of
172      * that object.
173      */
174     size_t          markCount;
175     size_t          markSize;
176 #endif
177 
178     /*
179      * Debug control values
180      */
181 
182     int             ddmHpifWhen;
183     int             ddmHpsgWhen;
184     int             ddmHpsgWhat;
185     int             ddmNhsgWhen;
186     int             ddmNhsgWhat;
187 
188 #if WITH_HPROF
189     bool            hprofDumpOnGc;
190     const char*     hprofFileName;
191     hprof_context_t *hprofContext;
192     int             hprofResult;
193 #endif
194 };
195 
196 bool dvmLockHeap(void);
197 void dvmUnlockHeap(void);
198 void dvmLogGcStats(size_t numFreed, size_t sizeFreed, size_t gcTimeMs);
199 void dvmLogMadviseStats(size_t madvisedSizes[], size_t arrayLen);
200 void dvmHeapSizeChanged(void);
201 
202 /*
203  * Logging helpers
204  */
205 
206 #define HEAP_LOG_TAG      LOG_TAG "-heap"
207 
208 #if LOG_NDEBUG
209 #define LOGV_HEAP(...)    ((void)0)
210 #define LOGD_HEAP(...)    ((void)0)
211 #else
212 #define LOGV_HEAP(...)    LOG(LOG_VERBOSE, HEAP_LOG_TAG, __VA_ARGS__)
213 #define LOGD_HEAP(...)    LOG(LOG_DEBUG, HEAP_LOG_TAG, __VA_ARGS__)
214 #endif
215 #define LOGI_HEAP(...)    LOG(LOG_INFO, HEAP_LOG_TAG, __VA_ARGS__)
216 #define LOGW_HEAP(...)    LOG(LOG_WARN, HEAP_LOG_TAG, __VA_ARGS__)
217 #define LOGE_HEAP(...)    LOG(LOG_ERROR, HEAP_LOG_TAG, __VA_ARGS__)
218 
219 #define QUIET_ZYGOTE_GC 1
220 #if QUIET_ZYGOTE_GC
221 #undef LOGI_HEAP
222 #define LOGI_HEAP(...) \
223     do { \
224         if (!gDvm.zygote) { \
225             LOG(LOG_INFO, HEAP_LOG_TAG, __VA_ARGS__); \
226         } \
227     } while (false)
228 #endif
229 
230 #define FRACTIONAL_MB(n)    (n) / (1024 * 1024), \
231                             ((((n) % (1024 * 1024)) / 1024) * 1000) / 1024
232 #define FRACTIONAL_PCT(n,max)    ((n) * 100) / (max), \
233                                  (((n) * 1000) / (max)) % 10
234 
235 #endif  // _DALVIK_ALLOC_HEAP_INTERNAL
236