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