src/share/vm/memory/genCollectedHeap.cpp

Print this page
rev 2869 : 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
Summary: Replaces calls to os::javaTimeMillis(), which does not guarantee montonicity, in GC code to os::javaTimeNanos() with a suitable conversion factor. os::javaTimeNanos() mostly guarantees montonicity depending on the underlying OS implementation and, as a result, a better alternative. Changes in OS files are to make use of the newly defined constants in globalDefinitions.hpp.
Reviewed-by:


1443     Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size);
1444   }
1445   return oop(result);
1446 }
1447 
1448 class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure {
1449   jlong _time;   // in ms
1450   jlong _now;    // in ms
1451 
1452  public:
1453   GenTimeOfLastGCClosure(jlong now) : _time(now), _now(now) { }
1454 
1455   jlong time() { return _time; }
1456 
1457   void do_generation(Generation* gen) {
1458     _time = MIN2(_time, gen->time_of_last_gc(_now));
1459   }
1460 };
1461 
1462 jlong GenCollectedHeap::millis_since_last_gc() {
1463   jlong now = os::javaTimeMillis();

1464   GenTimeOfLastGCClosure tolgc_cl(now);
1465   // iterate over generations getting the oldest
1466   // time that a generation was collected
1467   generation_iterate(&tolgc_cl, false);
1468   tolgc_cl.do_generation(perm_gen());
1469   // XXX Despite the assert above, since javaTimeMillis()
1470   // doesnot guarantee monotonically increasing return
1471   // values (note, i didn't say "strictly monotonic"),
1472   // we need to guard against getting back a time
1473   // later than now. This should be fixed by basing
1474   // on someting like gethrtime() which guarantees
1475   // monotonicity. Note that cond_wait() is susceptible
1476   // to a similar problem, because its interface is
1477   // based on absolute time in the form of the
1478   // system time's notion of UCT. See also 4506635
1479   // for yet another problem of similar nature. XXX
1480   jlong retVal = now - tolgc_cl.time();
1481   if (retVal < 0) {
1482     NOT_PRODUCT(warning("time warp: %d", retVal);)
1483     return 0;
1484   }
1485   return retVal;
1486 }


1443     Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size);
1444   }
1445   return oop(result);
1446 }
1447 
1448 class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure {
1449   jlong _time;   // in ms
1450   jlong _now;    // in ms
1451 
1452  public:
1453   GenTimeOfLastGCClosure(jlong now) : _time(now), _now(now) { }
1454 
1455   jlong time() { return _time; }
1456 
1457   void do_generation(Generation* gen) {
1458     _time = MIN2(_time, gen->time_of_last_gc(_now));
1459   }
1460 };
1461 
1462 jlong GenCollectedHeap::millis_since_last_gc() {
1463   // os::javaTimeMillis() does not guarantee monotonicity.
1464   jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
1465   GenTimeOfLastGCClosure tolgc_cl(now);
1466   // iterate over generations getting the oldest
1467   // time that a generation was collected
1468   generation_iterate(&tolgc_cl, false);
1469   tolgc_cl.do_generation(perm_gen());
1470   // XXX Since javaTimeNanos() mostly guarantees monotonically
1471   // increasing return values, depending upon the underlying
1472   // os-dependent implementation, we still need to guard against
1473   // getting back a time later than now. This should be fixed
1474   // by basing the implementation on something like gethrtime()
1475   // which does guarantee monotonicity.
1476   // Note that cond_wait() is susceptible to a similar problem,
1477   // because its interface is based on absolute time in the form
1478   // of the system time's notion of UCT. See also 4506635 for yet
1479   // another problem of similar nature. XXX

1480   jlong retVal = now - tolgc_cl.time();
1481   if (retVal < 0) {
1482     NOT_PRODUCT(warning("time warp: "INT64_FORMAT, retVal);)
1483     return 0;
1484   }
1485   return retVal;
1486 }