--- a/src/hotspot/share/utilities/ticks.hpp Tue May 15 11:28:29 2018 -0700
+++ b/src/hotspot/share/utilities/ticks.hpp Tue May 15 20:24:34 2018 +0200
@@ -1,116 +1,249 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
+* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* This code is free software; you can redistribute it and/or modify it
+* under the terms of the GNU General Public License version 2 only, as
+* published by the Free Software Foundation.
+*
+* This code is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+* version 2 for more details (a copy is included in the LICENSE file that
+* accompanied this code).
+*
+* You should have received a copy of the GNU General Public License version
+* 2 along with this work; if not, write to the Free Software Foundation,
+* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+*
+* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+* or visit www.oracle.com if you need additional information or have any
+* questions.
+*
+*/
#ifndef SHARE_VM_UTILITIES_TICKS_HPP
#define SHARE_VM_UTILITIES_TICKS_HPP
+#include "jni.h"
#include "memory/allocation.hpp"
-#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
-class Ticks;
+// Time sources
+class ElapsedCounterSource {
+ public:
+ typedef jlong Type;
+ static uint64_t frequency();
+ static Type now();
+ static double seconds(Type value);
+ static uint64_t milliseconds(Type value);
+ static uint64_t microseconds(Type value);
+ static uint64_t nanoseconds(Type value);
+};
-class Tickspan {
- friend class Ticks;
- friend Tickspan operator-(const Ticks& end, const Ticks& start);
+// Not guaranteed to be synchronized across hardware threads and
+// therefore software threads, and can be updated asynchronously
+// by software. now() can jump backwards as well as jump forward
+// when threads query different cores/sockets.
+// Very much not recommended for general use. Caveat emptor.
+class FastUnorderedElapsedCounterSource {
+ public:
+ typedef jlong Type;
+ static uint64_t frequency();
+ static Type now();
+ static double seconds(Type value);
+ static uint64_t milliseconds(Type value);
+ static uint64_t microseconds(Type value);
+ static uint64_t nanoseconds(Type value);
+};
- private:
- jlong _span_ticks;
-
- Tickspan(const Ticks& end, const Ticks& start);
-
+template <typename T1, typename T2>
+class PairRep {
public:
- Tickspan() : _span_ticks(0) {}
-
- Tickspan& operator+=(const Tickspan& rhs) {
- _span_ticks += rhs._span_ticks;
- return *this;
- }
+ T1 val1;
+ T2 val2;
- Tickspan& operator-=(const Tickspan& rhs) {
- _span_ticks -= rhs._span_ticks;
- return *this;
+ PairRep() : val1((T1)0), val2((T2)0) {}
+ void operator+=(const PairRep& rhs) {
+ val1 += rhs.val1;
+ val2 += rhs.val2;
+ }
+ void operator-=(const PairRep& rhs) {
+ val1 -= rhs.val1;
+ val2 -= rhs.val2;
}
+ bool operator==(const PairRep& rhs) const {
+ return val1 == rhs.val1;
+ }
+ bool operator!=(const PairRep& rhs) const {
+ return !operator==(rhs);
+ }
+ bool operator<(const PairRep& rhs) const {
+ return val1 < rhs.val1;
+ }
+ bool operator>(const PairRep& rhs) const {
+ return val1 > rhs.val1;
+ }
+};
- jlong value() const {
- return _span_ticks;
- }
+template <typename T1, typename T2>
+PairRep<T1, T2> operator-(const PairRep<T1, T2>& lhs, const PairRep<T1, T2>& rhs) {
+ PairRep<T1, T2> temp(lhs);
+ temp -= rhs;
+ return temp;
+}
+
+typedef PairRep<ElapsedCounterSource::Type, FastUnorderedElapsedCounterSource::Type> CompositeTime;
+class CompositeElapsedCounterSource {
+ public:
+ typedef CompositeTime Type;
+ static uint64_t frequency();
+ static Type now();
+ static double seconds(Type value);
+ static uint64_t milliseconds(Type value);
+ static uint64_t microseconds(Type value);
+ static uint64_t nanoseconds(Type value);
};
-class Ticks {
- private:
- jlong _stamp_ticks;
-
+template <typename TimeSource>
+class Representation {
+ public:
+ typedef typename TimeSource::Type Type;
+ protected:
+ Type _rep;
+ Representation(const Representation<TimeSource>& end, const Representation<TimeSource>& start) : _rep(end._rep - start._rep) {}
+ Representation() : _rep() {}
public:
- Ticks() : _stamp_ticks(0) {
- assert((_stamp_ticks = invalid_time_stamp) == invalid_time_stamp,
- "initial unstamped time value assignment");
+ void operator+=(const Representation<TimeSource>& rhs) {
+ _rep += rhs._rep;
+ }
+ void operator-=(const Representation<TimeSource>& rhs) {
+ _rep -= rhs._rep;
+ }
+ bool operator==(const Representation<TimeSource>& rhs) const {
+ return _rep == rhs._rep;
+ }
+ bool operator!=(const Representation<TimeSource>& rhs) const {
+ return !operator==(rhs);
+ }
+ bool operator<(const Representation<TimeSource>& rhs) const {
+ return _rep < rhs._rep;
+ }
+ bool operator>(const Representation<TimeSource>& rhs) const {
+ return _rep > rhs._rep;
+ }
+ bool operator<=(const Representation<TimeSource>& rhs) const {
+ return !operator>(rhs);
+ }
+ bool operator>=(const Representation<TimeSource>& rhs) const {
+ return !operator<(rhs);
+ }
+ double seconds() const {
+ return TimeSource::seconds(_rep);
+ }
+ uint64_t milliseconds() const {
+ return TimeSource::milliseconds(_rep);
+ }
+ uint64_t microseconds() const {
+ return TimeSource::microseconds(_rep);
+ }
+ uint64_t nanoseconds() const {
+ return TimeSource::nanoseconds(_rep);
}
+};
- Ticks& operator+=(const Tickspan& span) {
- _stamp_ticks += span.value();
- return *this;
+template <typename TimeSource>
+class CounterRepresentation : public Representation<TimeSource> {
+ protected:
+ CounterRepresentation(const CounterRepresentation& end, const CounterRepresentation& start) : Representation<TimeSource>(end, start) {}
+ explicit CounterRepresentation(jlong value) : Representation<TimeSource>() {
+ this->_rep = value;
+ }
+ public:
+ CounterRepresentation() : Representation<TimeSource>() {}
+ typename TimeSource::Type value() const { return this->_rep; }
+ operator typename TimeSource::Type() { return value(); }
+};
+
+template <typename TimeSource>
+class CompositeCounterRepresentation : public Representation<TimeSource> {
+ protected:
+ CompositeCounterRepresentation(const CompositeCounterRepresentation& end, const CompositeCounterRepresentation& start) :
+ Representation<TimeSource>(end, start) {}
+ explicit CompositeCounterRepresentation(jlong value) : Representation<TimeSource>() {
+ this->_rep.val1 = value;
+ this->_rep.val2 = value;
}
+ public:
+ CompositeCounterRepresentation() : Representation<TimeSource>() {}
+ ElapsedCounterSource::Type value() const { return this->_rep.val1; }
+ FastUnorderedElapsedCounterSource::Type ft_value() const { return this->_rep.val2; }
+};
- Ticks& operator-=(const Tickspan& span) {
- _stamp_ticks -= span.value();
+template <template <typename> class, typename>
+class TimeInstant;
+
+template <template <typename> class Rep, typename TimeSource>
+class TimeInterval : public Rep<TimeSource> {
+ template <template <typename> class, typename>
+ friend class TimeInstant;
+ TimeInterval(const TimeInstant<Rep, TimeSource>& end, const TimeInstant<Rep, TimeSource>& start) : Rep<TimeSource>(end, start) {}
+ public:
+ TimeInterval() : Rep<TimeSource>() {}
+ TimeInterval<Rep, TimeSource> operator+(const TimeInterval<Rep, TimeSource>& rhs) const {
+ TimeInterval<Rep, TimeSource> temp(*this);
+ temp += rhs;
+ return temp;
+ }
+ TimeInterval<Rep, TimeSource> operator-(const TimeInterval<Rep, TimeSource>& rhs) const {
+ TimeInterval<Rep, TimeSource> temp(*this);
+ temp -= rhs;
+ return temp;
+ }
+};
+
+template <template <typename> class Rep, typename TimeSource>
+class TimeInstant : public Rep<TimeSource> {
+ public:
+ TimeInstant() : Rep<TimeSource>() {}
+ TimeInstant<Rep, TimeSource>& operator+=(const TimeInterval<Rep, TimeSource>& rhs) {
+ Rep<TimeSource>::operator+=(rhs);
return *this;
}
-
- void stamp();
-
- jlong value() const {
- return _stamp_ticks;
+ TimeInstant<Rep, TimeSource>& operator-=(const TimeInterval<Rep, TimeSource>& rhs) {
+ Rep<TimeSource>::operator-=(rhs);
+ return *this;
+ }
+ TimeInterval<Rep, TimeSource> operator+(const TimeInstant<Rep, TimeSource>& end) const {
+ return TimeInterval<Rep, TimeSource>(end, *this);
+ }
+ TimeInterval<Rep, TimeSource> operator-(const TimeInstant<Rep, TimeSource>& start) const {
+ return TimeInterval<Rep, TimeSource>(*this, start);
}
-
- static const Ticks now();
-
-#ifdef ASSERT
- static const jlong invalid_time_stamp;
-#endif
-
-#ifndef PRODUCT
- // only for internal use by GC VM tests
+ void stamp() {
+ this->_rep = TimeSource::now();
+ }
+ static TimeInstant<Rep, TimeSource> now() {
+ TimeInstant<Rep, TimeSource> temp;
+ temp.stamp();
+ return temp;
+ }
+ private:
+ TimeInstant(jlong ticks) : Rep<TimeSource>(ticks) {}
+ friend class GranularTimer;
+ friend class ObjectSample;
+ // GC VM tests
friend class TimePartitionPhasesIteratorTest;
friend class GCTimerTest;
-
- private:
- // implicit type conversion
- Ticks(int ticks) : _stamp_ticks(ticks) {}
-
-#endif // !PRODUCT
-
};
-class TicksToTimeHelper : public AllStatic {
- public:
- enum Unit {
- SECONDS = 1,
- MILLISECONDS = 1000
- };
- static double seconds(const Tickspan& span);
- static jlong milliseconds(const Tickspan& span);
-};
+#if INCLUDE_JFR
+typedef TimeInstant<CompositeCounterRepresentation, CompositeElapsedCounterSource> Ticks;
+typedef TimeInterval<CompositeCounterRepresentation, CompositeElapsedCounterSource> Tickspan;
+#else
+typedef TimeInstant<CounterRepresentation, ElapsedCounterSource> Ticks;
+typedef TimeInterval<CounterRepresentation, ElapsedCounterSource> Tickspan;
+#endif
#endif // SHARE_VM_UTILITIES_TICKS_HPP