This commit is contained in:
Jesper Wilhelmsson 2016-02-22 19:46:37 +01:00
commit e76fbbafb5
65 changed files with 1062 additions and 608 deletions

View file

@ -409,6 +409,7 @@ static AliasedLoggingFlag const aliased_logging_flags[] = {
{ "TraceClassResolution", LogLevel::Info, true, LogTag::_classresolve },
{ "TraceExceptions", LogLevel::Info, true, LogTag::_exceptions },
{ "TraceMonitorInflation", LogLevel::Debug, true, LogTag::_monitorinflation },
{ "TraceBiasedLocking", LogLevel::Info, true, LogTag::_biasedlocking },
{ NULL, LogLevel::Off, false, LogTag::__NO_TAG }
};

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2016, 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
@ -23,6 +23,8 @@
*/
#include "precompiled.hpp"
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "oops/klass.inline.hpp"
#include "oops/markOop.hpp"
#include "oops/oop.inline.hpp"
@ -60,9 +62,7 @@ class VM_EnableBiasedLocking: public VM_Operation {
// Indicate that future instances should enable it as well
_biased_locking_enabled = true;
if (TraceBiasedLocking) {
tty->print_cr("Biased locking enabled");
}
log_info(biasedlocking)("Biased locking enabled");
}
bool allow_nested_vm_operations() const { return false; }
@ -144,14 +144,14 @@ static GrowableArray<MonitorInfo*>* get_or_compute_monitor_info(JavaThread* thre
return info;
}
static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread) {
markOop mark = obj->mark();
if (!mark->has_bias_pattern()) {
if (TraceBiasedLocking) {
if (log_is_enabled(Info, biasedlocking)) {
ResourceMark rm;
tty->print_cr(" (Skipping revocation of object of type %s because it's no longer biased)",
obj->klass()->external_name());
log_info(biasedlocking)(" (Skipping revocation of object of type %s "
"because it's no longer biased)",
obj->klass()->external_name());
}
return BiasedLocking::NOT_BIASED;
}
@ -160,10 +160,29 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_
markOop biased_prototype = markOopDesc::biased_locking_prototype()->set_age(age);
markOop unbiased_prototype = markOopDesc::prototype()->set_age(age);
if (TraceBiasedLocking && (Verbose || !is_bulk)) {
// Log at "info" level if not bulk, else "trace" level
if (!is_bulk) {
ResourceMark rm;
tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT,
p2i((void *)obj), (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
log_info(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark "
INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT
" , allow rebias %d , requesting thread " INTPTR_FORMAT,
p2i((void *)obj),
(intptr_t) mark,
obj->klass()->external_name(),
(intptr_t) obj->klass()->prototype_header(),
(allow_rebias ? 1 : 0),
(intptr_t) requesting_thread);
} else {
ResourceMark rm;
log_trace(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark "
INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT
" , allow rebias %d , requesting thread " INTPTR_FORMAT,
p2i((void *)obj),
(intptr_t) mark,
obj->klass()->external_name(),
(intptr_t) obj->klass()->prototype_header(),
(allow_rebias ? 1 : 0),
(intptr_t) requesting_thread);
}
JavaThread* biased_thread = mark->biased_locker();
@ -174,8 +193,11 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_
if (!allow_rebias) {
obj->set_mark(unbiased_prototype);
}
if (TraceBiasedLocking && (Verbose || !is_bulk)) {
tty->print_cr(" Revoked bias of anonymously-biased object");
// Log at "info" level if not bulk, else "trace" level
if (!is_bulk) {
log_info(biasedlocking)(" Revoked bias of anonymously-biased object");
} else {
log_trace(biasedlocking)(" Revoked bias of anonymously-biased object");
}
return BiasedLocking::BIAS_REVOKED;
}
@ -198,8 +220,11 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_
} else {
obj->set_mark(unbiased_prototype);
}
if (TraceBiasedLocking && (Verbose || !is_bulk)) {
tty->print_cr(" Revoked bias of object biased toward dead thread");
// Log at "info" level if not bulk, else "trace" level
if (!is_bulk) {
log_info(biasedlocking)(" Revoked bias of object biased toward dead thread");
} else {
log_trace(biasedlocking)(" Revoked bias of object biased toward dead thread");
}
return BiasedLocking::BIAS_REVOKED;
}
@ -214,21 +239,17 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_
for (int i = 0; i < cached_monitor_info->length(); i++) {
MonitorInfo* mon_info = cached_monitor_info->at(i);
if (mon_info->owner() == obj) {
if (TraceBiasedLocking && Verbose) {
tty->print_cr(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
p2i((void *) mon_info->owner()),
p2i((void *) obj));
}
log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") == obj (" PTR_FORMAT ")",
p2i((void *) mon_info->owner()),
p2i((void *) obj));
// Assume recursive case and fix up highest lock later
markOop mark = markOopDesc::encode((BasicLock*) NULL);
highest_lock = mon_info->lock();
highest_lock->set_displaced_header(mark);
} else {
if (TraceBiasedLocking && Verbose) {
tty->print_cr(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
p2i((void *) mon_info->owner()),
p2i((void *) obj));
}
log_trace(biasedlocking)(" mon_info->owner (" PTR_FORMAT ") != obj (" PTR_FORMAT ")",
p2i((void *) mon_info->owner()),
p2i((void *) obj));
}
}
if (highest_lock != NULL) {
@ -240,12 +261,18 @@ static BiasedLocking::Condition revoke_bias(oop obj, bool allow_rebias, bool is_
// ordering (e.g. ppc).
obj->release_set_mark(markOopDesc::encode(highest_lock));
assert(!obj->mark()->has_bias_pattern(), "illegal mark state: stack lock used bias bit");
if (TraceBiasedLocking && (Verbose || !is_bulk)) {
tty->print_cr(" Revoked bias of currently-locked object");
// Log at "info" level if not bulk, else "trace" level
if (!is_bulk) {
log_info(biasedlocking)(" Revoked bias of currently-locked object");
} else {
log_trace(biasedlocking)(" Revoked bias of currently-locked object");
}
} else {
if (TraceBiasedLocking && (Verbose || !is_bulk)) {
tty->print_cr(" Revoked bias of currently-unlocked object");
// Log at "info" level if not bulk, else "trace" level
if (!is_bulk) {
log_info(biasedlocking)(" Revoked bias of currently-unlocked object");
} else {
log_trace(biasedlocking)(" Revoked bias of currently-unlocked object");
}
if (allow_rebias) {
obj->set_mark(biased_prototype);
@ -326,12 +353,12 @@ static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
JavaThread* requesting_thread) {
assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
if (TraceBiasedLocking) {
tty->print_cr("* Beginning bulk revocation (kind == %s) because of object "
INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(bulk_rebias ? "rebias" : "revoke"),
p2i((void *) o), (intptr_t) o->mark(), o->klass()->external_name());
}
log_info(biasedlocking)("* Beginning bulk revocation (kind == %s) because of object "
INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s",
(bulk_rebias ? "rebias" : "revoke"),
p2i((void *) o),
(intptr_t) o->mark(),
o->klass()->external_name());
jlong cur_time = os::javaTimeMillis();
o->klass()->set_last_biased_lock_bulk_revocation_time(cur_time);
@ -377,9 +404,9 @@ static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
// adjust the header of the given object to revoke its bias.
revoke_bias(o, attempt_rebias_of_object && klass->prototype_header()->has_bias_pattern(), true, requesting_thread);
} else {
if (TraceBiasedLocking) {
if (log_is_enabled(Info, biasedlocking)) {
ResourceMark rm;
tty->print_cr("* Disabling biased locking for type %s", klass->external_name());
log_info(biasedlocking)("* Disabling biased locking for type %s", klass->external_name());
}
// Disable biased locking for this data type. Not only will this
@ -407,9 +434,7 @@ static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
revoke_bias(o, false, true, requesting_thread);
}
if (TraceBiasedLocking) {
tty->print_cr("* Ending bulk revocation");
}
log_info(biasedlocking)("* Ending bulk revocation");
BiasedLocking::Condition status_code = BiasedLocking::BIAS_REVOKED;
@ -420,9 +445,7 @@ static BiasedLocking::Condition bulk_revoke_or_rebias_at_safepoint(oop o,
klass->prototype_header()->bias_epoch());
o->set_mark(new_mark);
status_code = BiasedLocking::BIAS_REVOKED_AND_REBIASED;
if (TraceBiasedLocking) {
tty->print_cr(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
}
log_info(biasedlocking)(" Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
}
assert(!o->mark()->has_bias_pattern() ||
@ -485,16 +508,12 @@ public:
virtual void doit() {
if (_obj != NULL) {
if (TraceBiasedLocking) {
tty->print_cr("Revoking bias with potentially per-thread safepoint:");
}
log_info(biasedlocking)("Revoking bias with potentially per-thread safepoint:");
_status_code = revoke_bias((*_obj)(), false, false, _requesting_thread);
clean_up_cached_monitor_info();
return;
} else {
if (TraceBiasedLocking) {
tty->print_cr("Revoking bias with global safepoint:");
}
log_info(biasedlocking)("Revoking bias with global safepoint:");
BiasedLocking::revoke_at_safepoint(_objs);
}
}
@ -608,9 +627,7 @@ BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attem
// can come in with a CAS to steal the bias of an object that has a
// stale epoch.
ResourceMark rm;
if (TraceBiasedLocking) {
tty->print_cr("Revoking bias by walking my own stack:");
}
log_info(biasedlocking)("Revoking bias by walking my own stack:");
BiasedLocking::Condition cond = revoke_bias(obj(), false, false, (JavaThread*) THREAD);
((JavaThread*) THREAD)->set_cached_monitor_info(NULL);
assert(cond == BIAS_REVOKED, "why not?");

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -403,25 +403,20 @@ void Flag::print_on(outputStream* st, bool withComments, bool printRanges) {
st->cr();
} else if (!is_bool() && !is_ccstr()) {
st->print("%9s %-50s ", _type, _name);
if (printRanges) {
CommandLineFlagRangeList::print(_name, st, true);
st->print("%9s %-50s ", _type, _name);
CommandLineFlagRangeList::print(_name, st, true);
st->print(" %-20s", " ");
print_kind(st);
st->print(" %-20s", " ");
print_kind(st);
#ifndef PRODUCT
if (withComments) {
st->print("%s", _doc);
}
if (withComments) {
st->print("%s", _doc);
}
#endif
st->cr();
}
st->cr();
}
}
@ -1255,8 +1250,6 @@ void CommandLineFlags::verify() {
#endif // PRODUCT
#define ONLY_PRINT_PRODUCT_FLAGS
void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool printRanges) {
// Print the flags sorted by name
// note: this method is called before the thread structure is in place
@ -1281,9 +1274,6 @@ void CommandLineFlags::printFlags(outputStream* out, bool withComments, bool pri
for (size_t i = 0; i < length; i++) {
if (array[i]->is_unlocked()) {
#ifdef ONLY_PRINT_PRODUCT_FLAGS
if (!array[i]->is_notproduct() && !array[i]->is_develop())
#endif // ONLY_PRINT_PRODUCT_FLAGS
array[i]->print_on(out, withComments, printRanges);
}
}

View file

@ -1482,18 +1482,12 @@ public:
develop(bool, TraceCompiledIC, false, \
"Trace changes of compiled IC") \
\
develop(bool, TraceStartupTime, false, \
"Trace setup time") \
\
develop(bool, TraceProtectionDomainVerification, false, \
"Trace protection domain verification") \
\
develop(bool, TraceClearedExceptions, false, \
"Print when an exception is forcibly cleared") \
\
product(bool, TraceBiasedLocking, false, \
"Trace biased locking in JVM") \
\
/* gc */ \
\
product(bool, UseSerialGC, false, \

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2016, 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_RUNTIME_LOG_TIMER_HPP
#define SHARE_VM_RUNTIME_LOG_TIMER_HPP
#include "logging/log.hpp"
#include "runtime/timer.hpp"
// TraceStartupTime is used for tracing the execution time of a block with logging
// Usage:
// { TraceStartupTime t("block time")
// some_code();
// }
//
class TraceStartupTime : public TraceTime {
public:
TraceStartupTime(const char* s) : TraceTime(s, log_is_enabled(Info, startuptime), LogTag::_startuptime) {}
};
#endif // SHARE_VM_RUNTIME_LOG_TIMER_HPP

View file

@ -152,7 +152,6 @@ class os: AllStatic {
static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned);
// Get summary strings for system information in buffer provided
static bool get_host_name(char* buf, size_t buflen) PRODUCT_RETURN_(return false;); // true if available
static void get_summary_cpu_info(char* buf, size_t buflen);
static void get_summary_os_info(char* buf, size_t buflen);
@ -595,6 +594,9 @@ class os: AllStatic {
// Write to stream
static int log_vsnprintf(char* buf, size_t len, const char* fmt, va_list args) ATTRIBUTE_PRINTF(3, 0);
// Get host name in buffer provided
static bool get_host_name(char* buf, size_t buflen);
// Print out system information; they are called by fatal error handler.
// Output format may be different on different platforms.
static void print_os_info(outputStream* st);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -28,9 +28,9 @@
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/interfaceSupport.hpp"
#include "runtime/logTimer.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/timer.hpp"
#include "utilities/copy.hpp"
#ifdef COMPILER2
#include "opto/runtime.hpp"
@ -183,7 +183,7 @@ extern void StubGenerator_generate(CodeBuffer* code, bool all); // only interfac
void StubRoutines::initialize1() {
if (_code1 == NULL) {
ResourceMark rm;
TraceTime timer("StubRoutines generation 1", TraceStartupTime);
TraceStartupTime timer("StubRoutines generation 1");
_code1 = BufferBlob::create("StubRoutines (1)", code_size1);
if (_code1 == NULL) {
vm_exit_out_of_memory(code_size1, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (1)");
@ -276,7 +276,7 @@ static void test_safefetchN() {
void StubRoutines::initialize2() {
if (_code2 == NULL) {
ResourceMark rm;
TraceTime timer("StubRoutines generation 2", TraceStartupTime);
TraceStartupTime timer("StubRoutines generation 2");
_code2 = BufferBlob::create("StubRoutines (2)", code_size2);
if (_code2 == NULL) {
vm_exit_out_of_memory(code_size2, OOM_MALLOC_ERROR, "CodeCache: no room for StubRoutines (2)");

View file

@ -67,6 +67,7 @@
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniPeriodicChecker.hpp"
#include "runtime/logTimer.hpp"
#include "runtime/memprofiler.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/objectMonitor.hpp"
@ -169,11 +170,10 @@ void* Thread::allocate(size_t size, bool throw_excpt, MEMFLAGS flags) {
assert(((uintptr_t) aligned_addr + (uintptr_t) size) <=
((uintptr_t) real_malloc_addr + (uintptr_t) aligned_size),
"JavaThread alignment code overflowed allocated storage");
if (TraceBiasedLocking) {
if (aligned_addr != real_malloc_addr) {
tty->print_cr("Aligned thread " INTPTR_FORMAT " to " INTPTR_FORMAT,
p2i(real_malloc_addr), p2i(aligned_addr));
}
if (aligned_addr != real_malloc_addr) {
log_info(biasedlocking)("Aligned thread " INTPTR_FORMAT " to " INTPTR_FORMAT,
p2i(real_malloc_addr),
p2i(aligned_addr));
}
((Thread*) aligned_addr)->_real_malloc_address = real_malloc_addr;
return aligned_addr;
@ -3341,7 +3341,7 @@ void Threads::threads_do(ThreadClosure* tc) {
}
void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
TraceTime timer("Initialize java.lang classes", TraceStartupTime);
TraceStartupTime timer("Initialize java.lang classes");
if (EagerXrunInit && Arguments::init_libraries_at_startup()) {
create_vm_init_libraries();
@ -3388,6 +3388,8 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
}
void Threads::initialize_jsr292_core_classes(TRAPS) {
TraceStartupTime timer("Initialize java.lang.invoke classes");
initialize_class(vmSymbols::java_lang_invoke_MethodHandle(), CHECK);
initialize_class(vmSymbols::java_lang_invoke_MemberName(), CHECK);
initialize_class(vmSymbols::java_lang_invoke_MethodHandleNatives(), CHECK);
@ -3457,7 +3459,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
HOTSPOT_VM_INIT_BEGIN();
// Timing (must come after argument parsing)
TraceTime timer("Create VM", TraceStartupTime);
TraceStartupTime timer("Create VM");
// Initialize the os module after parsing the args
jint os_init_2_result = os::init_2();
@ -3542,8 +3544,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
JvmtiExport::transition_pending_onload_raw_monitors();
// Create the VMThread
{ TraceTime timer("Start VMThread", TraceStartupTime);
VMThread::create();
{ TraceStartupTime timer("Start VMThread");
VMThread::create();
Thread* vmthread = VMThread::vm_thread();
if (!os::create_thread(vmthread, os::vm_thread)) {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -23,6 +23,7 @@
*/
#include "precompiled.hpp"
#include "logging/log.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/timer.hpp"
#include "utilities/ostream.hpp"
@ -114,14 +115,15 @@ jlong TimeStamp::ticks_since_update() const {
}
TraceTime::TraceTime(const char* title,
bool doit) {
bool doit,
LogTagType tag) {
_active = doit;
_verbose = true;
_tag = tag;
_title = title;
if (_active) {
_accum = NULL;
tty->print("[%s", title);
tty->flush();
_t.start();
}
}
@ -129,14 +131,14 @@ TraceTime::TraceTime(const char* title,
TraceTime::TraceTime(const char* title,
elapsedTimer* accumulator,
bool doit,
bool verbose) {
_active = doit;
_verbose = verbose;
bool verbose,
LogTagType tag) {
_active = doit;
_verbose = verbose;
_tag = tag;
_title = title;
if (_active) {
if (_verbose) {
tty->print("[%s", title);
tty->flush();
}
_accum = accumulator;
_t.start();
}
@ -147,8 +149,15 @@ TraceTime::~TraceTime() {
_t.stop();
if (_accum!=NULL) _accum->add(_t);
if (_verbose) {
tty->print_cr(", %3.7f secs]", _t.seconds());
tty->flush();
switch (_tag) {
case LogTag::_startuptime :
log_info(startuptime)("%s, %3.7f secs", _title, _t.seconds());
break;
case LogTag::__NO_TAG :
default :
tty->print_cr("[%s, %3.7f secs]", _title, _t.seconds());
tty->flush();
}
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2016, 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
@ -25,6 +25,7 @@
#ifndef SHARE_VM_RUNTIME_TIMER_HPP
#define SHARE_VM_RUNTIME_TIMER_HPP
#include "logging/logTag.hpp"
#include "utilities/globalDefinitions.hpp"
// Timers for simple measurement.
@ -85,14 +86,19 @@ class TraceTime: public StackObj {
bool _verbose; // report every timing
elapsedTimer _t; // timer
elapsedTimer* _accum; // accumulator
const char* _title; // name of timer
LogTagType _tag; // stream to print to
public:
// Constructors
TraceTime(const char* title,
bool doit = true);
bool doit = true,
LogTagType tag = LogTag::__NO_TAG);
TraceTime(const char* title,
elapsedTimer* accumulator,
bool doit = true,
bool verbose = false);
bool verbose = false,
LogTagType tag = LogTag::__NO_TAG);
~TraceTime();
// Accessors