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