1 /*
   2  * Copyright (c) 2012, 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 org.graalvm.compiler.debug;
  26 
  27 import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
  28 
  29 import java.util.concurrent.TimeUnit;
  30 
  31 import jdk.internal.vm.compiler.collections.Pair;
  32 
  33 final class TimerKeyImpl extends AccumulatedKey implements TimerKey {
  34     static class FlatTimer extends AbstractKey implements TimerKey {
  35         private TimerKeyImpl accm;
  36 
  37         FlatTimer(String nameFormat, Object nameArg1, Object nameArg2) {
  38             super(nameFormat, nameArg1, nameArg2);
  39         }
  40 
  41         @Override
  42         protected String createName(String format, Object arg1, Object arg2) {
  43             return super.createName(format, arg1, arg2) + FLAT_KEY_SUFFIX;
  44         }
  45 
  46         @Override
  47         public String toHumanReadableFormat(long value) {
  48             return valueToString(value);
  49         }
  50 
  51         @Override
  52         public TimeUnit getTimeUnit() {
  53             return accm.getTimeUnit();
  54         }
  55 
  56         @Override
  57         public DebugCloseable start(DebugContext debug) {
  58             return accm.start(debug);
  59         }
  60 
  61         @Override
  62         public Pair<String, String> toCSVFormat(long value) {
  63             return TimerKeyImpl.toCSVFormatHelper(value);
  64         }
  65 
  66         @Override
  67         public TimerKey doc(String doc) {
  68             throw new IllegalArgumentException("Cannot set documentation for derived key " + getName());
  69         }
  70 
  71         @Override
  72         public String getDocName() {
  73             return null;
  74         }
  75     }
  76 
  77     TimerKeyImpl(String nameFormat, Object nameArg1, Object nameArg2) {
  78         super(new FlatTimer(nameFormat, nameArg1, nameArg2), nameFormat, nameArg1, nameArg2);
  79         ((FlatTimer) flat).accm = this;
  80     }
  81 
  82     @Override
  83     public DebugCloseable start(DebugContext debug) {
  84         if (debug.isTimerEnabled(this)) {
  85             Timer result = new Timer(this, debug);
  86             debug.currentTimer = result;
  87             return result;
  88         } else {
  89             return VOID_CLOSEABLE;
  90         }
  91     }
  92 
  93     public static String valueToString(long value) {
  94         return String.format("%d.%d ms", value / 1000000, (value / 100000) % 10);
  95     }
  96 
  97     @Override
  98     public TimerKey getFlat() {
  99         return (FlatTimer) flat;
 100     }
 101 
 102     @Override
 103     public String toHumanReadableFormat(long value) {
 104         return valueToString(value);
 105     }
 106 
 107     @Override
 108     public TimeUnit getTimeUnit() {
 109         return TimeUnit.NANOSECONDS;
 110     }
 111 
 112     static final class Timer extends CloseableCounter implements DebugCloseable {
 113         final DebugContext debug;
 114 
 115         Timer(AccumulatedKey counter, DebugContext debug) {
 116             super(debug, debug.currentTimer, counter);
 117             this.debug = debug;
 118         }
 119 
 120         @Override
 121         public void close() {
 122             super.close();
 123             debug.currentTimer = parent;
 124         }
 125 
 126         @Override
 127         protected long getCounterValue() {
 128             return TimeSource.getTimeNS();
 129         }
 130 
 131     }
 132 
 133     @Override
 134     public Pair<String, String> toCSVFormat(long value) {
 135         return toCSVFormatHelper(value);
 136     }
 137 
 138     static Pair<String, String> toCSVFormatHelper(long value) {
 139         return Pair.create(Long.toString(value / 1000), "us");
 140     }
 141 
 142     @Override
 143     public TimerKey doc(String doc) {
 144         setDoc(doc);
 145         return this;
 146     }
 147 }