src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/cms/CompactibleFreeListSpace.java
branchaefimov-dns-client-branch
changeset 59099 fcdb8e7ead8f
parent 58984 15e026239a6c
parent 59075 355f4f42dda5
child 59100 b92aac38b046
equal deleted inserted replaced
58984:15e026239a6c 59099:fcdb8e7ead8f
     1 /*
       
     2  * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 package sun.jvm.hotspot.gc.cms;
       
    26 
       
    27 import java.io.*;
       
    28 import java.util.*;
       
    29 
       
    30 import sun.jvm.hotspot.debugger.*;
       
    31 import sun.jvm.hotspot.gc.shared.*;
       
    32 import sun.jvm.hotspot.memory.*;
       
    33 import sun.jvm.hotspot.oops.*;
       
    34 import sun.jvm.hotspot.runtime.*;
       
    35 import sun.jvm.hotspot.types.*;
       
    36 import sun.jvm.hotspot.utilities.*;
       
    37 
       
    38 public class CompactibleFreeListSpace extends CompactibleSpace implements LiveRegionsProvider {
       
    39    private static AddressField collectorField;
       
    40    private static AddressField indexedFreeListField;
       
    41    private static AddressField dictionaryField;
       
    42    private static long         smallLinearAllocBlockFieldOffset;
       
    43 
       
    44    private int heapWordSize;     // 4 for 32bit, 8 for 64 bits
       
    45    private int IndexSetStart;    // for small indexed list
       
    46    private int IndexSetSize;
       
    47    private int IndexSetStride;
       
    48    private static long MinChunkSizeInBytes;
       
    49 
       
    50    static {
       
    51       VM.registerVMInitializedObserver(new Observer() {
       
    52          public void update(Observable o, Object data) {
       
    53             initialize(VM.getVM().getTypeDataBase());
       
    54          }
       
    55       });
       
    56    }
       
    57 
       
    58    private static synchronized void initialize(TypeDataBase db) {
       
    59       long sizeofFreeChunk = db.lookupType("FreeChunk").getSize();
       
    60       VM vm = VM.getVM();
       
    61 
       
    62      Type type = db.lookupType("CompactibleFreeListSpace");
       
    63      collectorField = type.getAddressField("_collector");
       
    64      collectorField       = type.getAddressField("_collector");
       
    65      dictionaryField      = type.getAddressField("_dictionary");
       
    66      indexedFreeListField = type.getAddressField("_indexedFreeList[0]");
       
    67      smallLinearAllocBlockFieldOffset = type.getField("_smallLinearAllocBlock").getOffset();
       
    68      MinChunkSizeInBytes = (type.getCIntegerField("_min_chunk_size_in_bytes")).getValue();
       
    69    }
       
    70 
       
    71    public CompactibleFreeListSpace(Address addr) {
       
    72       super(addr);
       
    73       VM vm = VM.getVM();
       
    74       heapWordSize   = vm.getHeapWordSize();
       
    75       IndexSetStart  = vm.getMinObjAlignmentInBytes() / heapWordSize;
       
    76       IndexSetStride = IndexSetStart;
       
    77       IndexSetSize   = vm.getIndexSetSize();
       
    78    }
       
    79 
       
    80    // Accessing block offset table
       
    81    public CMSCollector collector() {
       
    82     return (CMSCollector) VMObjectFactory.newObject(
       
    83                                  CMSCollector.class,
       
    84                                  collectorField.getValue(addr));
       
    85    }
       
    86 
       
    87    public long free0() {
       
    88      return capacity() - used0();
       
    89    }
       
    90 
       
    91    public long used() {
       
    92      return capacity() - free();
       
    93    }
       
    94 
       
    95    public long used0() {
       
    96       List<MemRegion> regions = getLiveRegions();
       
    97       long usedSize = 0L;
       
    98       for (Iterator<MemRegion> itr = regions.iterator(); itr.hasNext();) {
       
    99          MemRegion mr = itr.next();
       
   100          usedSize += mr.byteSize();
       
   101       }
       
   102       return usedSize;
       
   103    }
       
   104 
       
   105    public long free() {
       
   106       // small chunks
       
   107       long size = 0;
       
   108       Address cur = addr.addOffsetTo( indexedFreeListField.getOffset() );
       
   109       cur = cur.addOffsetTo(IndexSetStart*AdaptiveFreeList.sizeOf());
       
   110       for (int i=IndexSetStart; i<IndexSetSize; i += IndexSetStride) {
       
   111          AdaptiveFreeList freeList = (AdaptiveFreeList) VMObjectFactory.newObject(AdaptiveFreeList.class, cur);
       
   112          size += i*freeList.count();
       
   113          cur= cur.addOffsetTo(IndexSetStride*AdaptiveFreeList.sizeOf());
       
   114       }
       
   115 
       
   116       // large block
       
   117       AFLBinaryTreeDictionary aflbd = (AFLBinaryTreeDictionary) VMObjectFactory.newObject(AFLBinaryTreeDictionary.class,
       
   118                                                                                    dictionaryField.getValue(addr));
       
   119       size += aflbd.size();
       
   120 
       
   121 
       
   122       // linear block in TLAB
       
   123       LinearAllocBlock lab = (LinearAllocBlock) VMObjectFactory.newObject(LinearAllocBlock.class,
       
   124                                                                           addr.addOffsetTo(smallLinearAllocBlockFieldOffset));
       
   125       size += lab.word_size();
       
   126 
       
   127       return size*heapWordSize;
       
   128   }
       
   129 
       
   130    public void printOn(PrintStream tty) {
       
   131       tty.print("free-list-space");
       
   132       tty.print("[ " + bottom() + " , " + end() + " ) ");
       
   133       long cap = capacity();
       
   134       long used_size = used();
       
   135       long free_size = free();
       
   136       int  used_perc = (int)((double)used_size/cap*100);
       
   137       tty.print("space capacity = " + cap + " used(" + used_perc + "%)= " + used_size + " ");
       
   138       tty.print("free= " + free_size );
       
   139       tty.print("\n");
       
   140 
       
   141    }
       
   142 
       
   143    public Address skipBlockSizeUsingPrintezisBits(Address pos) {
       
   144        CMSCollector collector = collector();
       
   145        long size = 0;
       
   146        Address addr = null;
       
   147 
       
   148        if (collector != null) {
       
   149          size = collector.blockSizeUsingPrintezisBits(pos);
       
   150          if (size >= 3) {
       
   151            addr = pos.addOffsetTo(adjustObjectSizeInBytes(size));
       
   152          }
       
   153        }
       
   154        return addr;
       
   155    }
       
   156 
       
   157   @Override
       
   158    public List<MemRegion> getLiveRegions() {
       
   159       List<MemRegion> res = new ArrayList<>();
       
   160       VM vm = VM.getVM();
       
   161       Debugger dbg = vm.getDebugger();
       
   162       ObjectHeap heap = vm.getObjectHeap();
       
   163       Address cur = bottom();
       
   164       Address regionStart = cur;
       
   165       Address limit = end();
       
   166       final long addressSize = vm.getAddressSize();
       
   167 
       
   168       for (; cur.lessThan(limit);) {
       
   169          Address k = cur.getAddressAt(addressSize);
       
   170          if (FreeChunk.indicatesFreeChunk(cur)) {
       
   171             if (! cur.equals(regionStart)) {
       
   172                res.add(new MemRegion(regionStart, cur));
       
   173             }
       
   174             FreeChunk fc = (FreeChunk) VMObjectFactory.newObject(FreeChunk.class, cur);
       
   175             long chunkSize = fc.size();
       
   176             if (Assert.ASSERTS_ENABLED) {
       
   177                Assert.that(chunkSize > 0, "invalid FreeChunk size");
       
   178             }
       
   179             // note that fc.size() gives chunk size in heap words
       
   180             cur = cur.addOffsetTo(chunkSize * addressSize);
       
   181             regionStart = cur;
       
   182          } else if (k != null) {
       
   183             Oop obj = heap.newOop(cur.addOffsetToAsOopHandle(0));
       
   184             long objectSize = obj.getObjectSize();
       
   185             cur = cur.addOffsetTo(adjustObjectSizeInBytes(objectSize));
       
   186          } else {
       
   187             // FIXME: need to do a better job here.
       
   188             // can I use bitMap here?
       
   189             //Find the object size using Printezis bits and skip over
       
   190             long size = collector().blockSizeUsingPrintezisBits(cur);
       
   191             if (size == -1) {
       
   192               break;
       
   193             }
       
   194             cur = cur.addOffsetTo(adjustObjectSizeInBytes(size));
       
   195          }
       
   196       }
       
   197       return res;
       
   198    }
       
   199 
       
   200    //-- Internals only below this point
       
   201 
       
   202    // Unlike corresponding VM code, we operate on byte size rather than
       
   203    // HeapWord size for convenience.
       
   204 
       
   205    public static long adjustObjectSizeInBytes(long sizeInBytes) {
       
   206       return Oop.alignObjectSize(Math.max(sizeInBytes, MinChunkSizeInBytes));
       
   207    }
       
   208 
       
   209 }