RFR(M): 8028128: Add a type safe alternative for working with counter based data

Markus Gronlund markus.gronlund at oracle.com
Wed Nov 20 01:32:56 PST 2013

Hi Per,


Thanks for taking a look!






From: Per Liden 
Sent: den 18 november 2013 13:22
To: Markus Gronlund; hotspot-runtime-dev at openjdk.java.net; hotspot-gc-dev at openjdk.java.net; serviceability-dev at openjdk.java.net serviceability-dev at openjdk.java.net
Subject: Re: RFR(M): 8028128: Add a type safe alternative for working with counter based data


Hi Markus,

Looks like a nice cleanup. Naming it always hard, so I'll avoid that topic ;) A few other minor comments, feel free to ignore.


[MG] i agree on the naming parts. I also agree that the current names are not the best possible. I have assumed they will change.


 101 class TicksToTimeHelper : public AllStatic {
 102  public:
 103   enum Unit {
 104     SECONDS = 1,
 105     MILLISECONDS = 1000
 106   };
 107   static double seconds(const Tickspan& span);
 108   static jlong milliseconds(const Tickspan& span);
 109 };

Do we really want a separate class for this instead of having Tickspan::seconds() and Tickspan::milliseconds()? If moved inside Tickspan, maybe value() should be ticks() to be consistent (and I guess Ticks::value() -> Ticks::ticks() would follow)?

[MG] In this particular case I would prefer to keep the convenience functions non-member, non-friends since a convenience member function really does not add anything extra that cannot be retrieved from outside the type. I also think that keeping the convenience functions outside/decoupled from the type itself increases encapsulation and increases flexibility - esp. for this case very much so where the convenience functions for at ticks/time representation is very much open ended; I just whacked together a seconds() and milliseconds(), but what about microseconds(), nanoseconds() and other timing convenience functions that might be needed further? I think keeping it outside increases the flexibility to add convenience functions without affecting the primary type.

  43 inline bool operator!=(const Tickspan& lhs, const Tickspan& rhs) {
  44   return !operator==(lhs,rhs);
  45 }

In many of the operators you have code like the example above. Is there a reason you want to spell it out like that instead of just "return !(lhs == rhs);"?

[MG] I use this way of writing to make it explicit that a particular non-member operator is implemented in terms of another non-member operator. This point of view might be considered a bit too "implementation" centric, but I have found it useful sometimes as an easy way to directly point to the implementation  - granted, for a case such as !(lhs == rhs) that might already be obvious..

145   void register_gc_phase_start(const char* name, const Ticks& time = Ticks::now());

There are quite a few places where you've added default values like the one above. But as far as I can tell most (I think I saw at least one exception in there) of these functions are either always called without the argument or always called with the argument. Seems a bit unnecessary to provide this flexibility when it's never used (as it opens up for incorrect use of the interface)?


[MG] Most of the default parameters are there in order to avoid polluting all the GC collectors with the knowledge about the Ticks/Tickspan types - I can encapsulate the usages only to gcTrace and gcTimer modules. You are right about this for the register_gc_phase_* functions though - they always pass a parameter, providing a default parameter for them might be a bit gratuitous. I will update the phase functions accordingly:


  void register_gc_phase_start(const char* name, const Ticks& time);

  void register_gc_phase_end(const Ticks& time);


Thanks Per!


I will send out an updated webrev.


On 2013-11-12 12:17, Markus Gronlund wrote:



Kindly asking for reviews for the following changeset:


Webrev: HYPERLINK "http://cr.openjdk.java.net/%7Emgronlun/8028128/webrev01/"http://cr.openjdk.java.net/~mgronlun/8028128/webrev01/ 


Bug: https://bugs.openjdk.java.net/browse/JDK-8028128




Currently, when working with counter based data, the primary data type representation in the VM are raw jlong's. jlong's are employed to represent both: 

1. a single instance in time, for example a "now" timestamp 
2. a time duration, a timespan, for example the duration between "now" - "then" 

Having a raw jlong type represent both of these shifts the responsibility to the programmer to always ensure the correct validity of the counter data, without any assistance either at compile time or at runtime. 

The event based tracing framework relies heavily on counter based data in order to keep track of time and timing related information and we have seen counter data errors where the representation sent to the tracing framework has submitted the wrong time, i.e. a timespan when a time instant was expected and vice versa. 

We should therefore add an alternative to jlongs for representing counter based data. We should enlist the help of the type system to enforce the correct data types at compile time as well as introduce strong runtime asserts in order to help with the correct usage of time and to reduce the number of potential bugs. 

I will therefore add two new types in src/share/vm/utilities: 

1. "Ticks" - represents a single counter based timestamp, a single instance in time.
2. "Tickspan" - represents a counter based duration, a timespan,  between two "Ticks" 


Please see the added files:


-          src/share/vm/utilities/ticks.hpp

-          src/share/vm/utilities/ticks.inline.hpp

-          src/share/vm/utilities/ticks.cpp


I have also updated some of the existing event based tracing "event sites" to employ usage of these new types as well as updated a few places in the event based tracing framework implementation to accommodate these types.


Testing completed:


nsk.stress.testlist (UTE/Aurora)

GC nightlies (Aurora)

gc/gctests/* (UTE/Aurora)

nsk.gc.testlist (UTE/Aurora)

SpecJBB2013 (no regression)

SpecJBB2005 (no regression)

Kitchensink (locally Windows) runs for +> 9 days (still running.)

Thanks in advance

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/serviceability-dev/attachments/20131120/2f8e54ad/attachment-0001.html 

More information about the serviceability-dev mailing list