Home | History | Annotate | Download | only in alloc
      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