1 /*
   2  * Copyright (c) 2014, 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 package common;
  24 
  25 import com.oracle.java.testlibrary.cli.CommandLineOptionTest;
  26 import sun.hotspot.code.BlobType;
  27 
  28 import java.util.ArrayList;
  29 import java.util.Collections;
  30 import java.util.EnumSet;
  31 import java.util.List;
  32 
  33 public class CodeCacheOptions {
  34     public static final String SEGMENTED_CODE_CACHE = "SegmentedCodeCache";
  35 
  36     private static final EnumSet<BlobType> NON_SEGMENTED_HEAPS
  37             = EnumSet.of(BlobType.All);
  38     private static final EnumSet<BlobType> ALL_SEGMENTED_HEAPS
  39             = EnumSet.complementOf(NON_SEGMENTED_HEAPS);
  40     private static final EnumSet<BlobType> SEGMENTED_HEAPS_WO_PROFILED
  41             = EnumSet.of(BlobType.NonNMethod, BlobType.MethodNonProfiled);
  42     private static final EnumSet<BlobType> ONLY_NON_METHODS_HEAP
  43             = EnumSet.of(BlobType.NonNMethod);
  44 
  45     public final long reserved;
  46     public final long nonNmethods;
  47     public final long nonProfiled;
  48     public final long profiled;
  49     public final boolean segmented;
  50 
  51     public static long mB(long val) {
  52         return CodeCacheOptions.kB(val) * 1024L;
  53     }
  54 
  55     public static long kB(long val) {
  56         return val * 1024L;
  57     }
  58 
  59     public CodeCacheOptions(long reserved) {
  60         this.reserved = reserved;
  61         this.nonNmethods = 0;
  62         this.nonProfiled = 0;
  63         this.profiled = 0;
  64         this.segmented = false;
  65     }
  66 
  67     public CodeCacheOptions(long reserved, long nonNmethods, long nonProfiled,
  68             long profiled) {
  69         this.reserved = reserved;
  70         this.nonNmethods = nonNmethods;
  71         this.nonProfiled = nonProfiled;
  72         this.profiled = profiled;
  73         this.segmented = true;
  74     }
  75 
  76     public long sizeForHeap(BlobType heap) {
  77         switch (heap) {
  78             case All:
  79                 return this.reserved;
  80             case NonNMethod:
  81                 return this.nonNmethods;
  82             case MethodNonProfiled:
  83                 return this.nonProfiled;
  84             case MethodProfiled:
  85                 return this.profiled;
  86             default:
  87                 throw new Error("Unknown heap: " + heap.name());
  88         }
  89     }
  90 
  91     public String[] prepareOptions(String... additionalOptions) {
  92         List<String> options = new ArrayList<>();
  93         Collections.addAll(options, additionalOptions);
  94         Collections.addAll(options,
  95                 CommandLineOptionTest.prepareBooleanFlag(
  96                         SEGMENTED_CODE_CACHE, segmented),
  97                 CommandLineOptionTest.prepareNumericFlag(
  98                         BlobType.All.sizeOptionName, reserved));
  99 
 100         if (segmented) {
 101             Collections.addAll(options,
 102                     CommandLineOptionTest.prepareNumericFlag(
 103                             BlobType.NonNMethod.sizeOptionName, nonNmethods),
 104                     CommandLineOptionTest.prepareNumericFlag(
 105                             BlobType.MethodNonProfiled.sizeOptionName,
 106                             nonProfiled),
 107                     CommandLineOptionTest.prepareNumericFlag(
 108                             BlobType.MethodProfiled.sizeOptionName, profiled));
 109         }
 110         return options.toArray(new String[options.size()]);
 111     }
 112 
 113     public CodeCacheOptions mapOptions(EnumSet<BlobType> involvedCodeHeaps) {
 114         if (involvedCodeHeaps.isEmpty()
 115                 || involvedCodeHeaps.equals(NON_SEGMENTED_HEAPS)
 116                 || involvedCodeHeaps.equals(ALL_SEGMENTED_HEAPS)) {
 117             return this;
 118         } else if (involvedCodeHeaps.equals(SEGMENTED_HEAPS_WO_PROFILED)) {
 119             return new CodeCacheOptions(reserved, nonNmethods,
 120                     profiled + nonProfiled, 0L);
 121         } else if (involvedCodeHeaps.equals(ONLY_NON_METHODS_HEAP)) {
 122             return new CodeCacheOptions(reserved, nonNmethods + profiled
 123                     + nonProfiled, 0L, 0L);
 124         } else {
 125             throw new Error("Test bug: unexpected set of code heaps involved "
 126                     + "into test.");
 127         }
 128     }
 129 }