[heap] Remove --log-gc.

Bug: 
Change-Id: I7b085f89f22de7ea55156d2942f3437bbf9c5af8
Reviewed-on: https://chromium-review.googlesource.com/836588
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Hannes Payer <hpayer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50227}
This commit is contained in:
Hannes Payer 2017-12-20 11:30:32 +01:00 committed by Commit Bot
parent ee78c7d715
commit 6e086610e0
9 changed files with 8 additions and 235 deletions

View File

@ -1115,8 +1115,6 @@ DEFINE_BOOL(log_all, false, "Log all events to the log file.")
DEFINE_BOOL(log_api, false, "Log API events to the log file.") DEFINE_BOOL(log_api, false, "Log API events to the log file.")
DEFINE_BOOL(log_code, false, DEFINE_BOOL(log_code, false,
"Log code events to the log file without profiling.") "Log code events to the log file without profiling.")
DEFINE_BOOL(log_gc, false,
"Log heap samples on garbage collection for the hp2ps tool.")
DEFINE_BOOL(log_handles, false, "Log global handle events.") DEFINE_BOOL(log_handles, false, "Log global handle events.")
DEFINE_BOOL(log_suspect, false, "Log suspect operations.") DEFINE_BOOL(log_suspect, false, "Log suspect operations.")
DEFINE_BOOL(log_source_code, false, "Log source code.") DEFINE_BOOL(log_source_code, false, "Log source code.")

View File

@ -363,24 +363,11 @@ void Heap::SetGCState(HeapState state) {
gc_state_ = state; gc_state_ = state;
} }
// TODO(1238405): Combine the infrastructure for --heap-stats and
// --log-gc to avoid the complicated preprocessor and flag testing.
void Heap::ReportStatisticsBeforeGC() { void Heap::ReportStatisticsBeforeGC() {
// Heap::ReportHeapStatistics will also log NewSpace statistics when
// compiled --log-gc is set. The following logic is used to avoid
// double logging.
#ifdef DEBUG #ifdef DEBUG
if (FLAG_heap_stats || FLAG_log_gc) new_space_->CollectStatistics();
if (FLAG_heap_stats) { if (FLAG_heap_stats) {
ReportHeapStatistics("Before GC");
} else if (FLAG_log_gc) {
new_space_->ReportStatistics();
}
if (FLAG_heap_stats || FLAG_log_gc) new_space_->ClearHistograms();
#else
if (FLAG_log_gc) {
new_space_->CollectStatistics(); new_space_->CollectStatistics();
new_space_->ReportStatistics(); ReportHeapStatistics("Before GC");
new_space_->ClearHistograms(); new_space_->ClearHistograms();
} }
#endif // DEBUG #endif // DEBUG
@ -444,20 +431,12 @@ void Heap::PrintShortHeapStatistics() {
total_gc_time_ms_); total_gc_time_ms_);
} }
// TODO(1238405): Combine the infrastructure for --heap-stats and
// --log-gc to avoid the complicated preprocessor and flag testing.
void Heap::ReportStatisticsAfterGC() { void Heap::ReportStatisticsAfterGC() {
// Similar to the before GC, we use some complicated logic to ensure that
// NewSpace statistics are logged exactly once when --log-gc is turned on.
#if defined(DEBUG) #if defined(DEBUG)
if (FLAG_heap_stats) { if (FLAG_heap_stats) {
new_space_->CollectStatistics(); new_space_->CollectStatistics();
ReportHeapStatistics("After GC"); ReportHeapStatistics("After GC");
} else if (FLAG_log_gc) {
new_space_->ReportStatistics();
} }
#else
if (FLAG_log_gc) new_space_->ReportStatistics();
#endif // DEBUG #endif // DEBUG
for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount); for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount);
++i) { ++i) {

View File

@ -154,17 +154,15 @@ void Scavenger::Process(OneshotBarrier* barrier) {
} }
void Scavenger::RecordCopiedObject(HeapObject* obj) { void Scavenger::RecordCopiedObject(HeapObject* obj) {
bool should_record = FLAG_log_gc;
#ifdef DEBUG #ifdef DEBUG
should_record = FLAG_heap_stats; if (FLAG_heap_stats) {
#endif
if (should_record) {
if (heap()->new_space()->Contains(obj)) { if (heap()->new_space()->Contains(obj)) {
heap()->new_space()->RecordAllocation(obj); heap()->new_space()->RecordAllocation(obj);
} else { } else {
heap()->new_space()->RecordPromotion(obj); heap()->new_space()->RecordPromotion(obj);
} }
} }
#endif
} }
void Scavenger::Finalize() { void Scavenger::Finalize() {

View File

@ -2638,8 +2638,7 @@ static void ReportHistogram(Isolate* isolate, bool print_spill) {
} }
#endif // DEBUG #endif // DEBUG
// Support for statistics gathering for --heap-stats.
// Support for statistics gathering for --heap-stats and --log-gc.
void NewSpace::ClearHistograms() { void NewSpace::ClearHistograms() {
for (int i = 0; i <= LAST_TYPE; i++) { for (int i = 0; i <= LAST_TYPE; i++) {
allocated_histogram_[i].clear(); allocated_histogram_[i].clear();
@ -2650,7 +2649,6 @@ void NewSpace::ClearHistograms() {
// Because the copying collector does not touch garbage objects, we iterate // Because the copying collector does not touch garbage objects, we iterate
// the new space before a collection to get a histogram of allocated objects. // the new space before a collection to get a histogram of allocated objects.
// This only happens when --log-gc flag is set.
void NewSpace::CollectStatistics() { void NewSpace::CollectStatistics() {
ClearHistograms(); ClearHistograms();
SemiSpaceIterator it(this); SemiSpaceIterator it(this);
@ -2658,34 +2656,6 @@ void NewSpace::CollectStatistics() {
RecordAllocation(obj); RecordAllocation(obj);
} }
static void DoReportStatistics(Isolate* isolate, HistogramInfo* info,
const char* description) {
LOG(isolate, HeapSampleBeginEvent("NewSpace", description));
// Lump all the string types together.
int string_number = 0;
int string_bytes = 0;
#define INCREMENT(type, size, name, camel_name) \
string_number += info[type].number(); \
string_bytes += info[type].bytes();
STRING_TYPE_LIST(INCREMENT)
#undef INCREMENT
if (string_number > 0) {
LOG(isolate,
HeapSampleItemEvent("STRING_TYPE", string_number, string_bytes));
}
// Then do the other types.
for (int i = FIRST_NONSTRING_TYPE; i <= LAST_TYPE; ++i) {
if (info[i].number() > 0) {
LOG(isolate, HeapSampleItemEvent(info[i].name(), info[i].number(),
info[i].bytes()));
}
}
LOG(isolate, HeapSampleEndEvent("NewSpace", description));
}
void NewSpace::ReportStatistics() { void NewSpace::ReportStatistics() {
#ifdef DEBUG #ifdef DEBUG
if (FLAG_heap_stats) { if (FLAG_heap_stats) {
@ -2703,12 +2673,6 @@ void NewSpace::ReportStatistics() {
PrintF("\n"); PrintF("\n");
} }
#endif // DEBUG #endif // DEBUG
if (FLAG_log_gc) {
Isolate* isolate = heap()->isolate();
DoReportStatistics(isolate, allocated_histogram_, "allocated");
DoReportStatistics(isolate, promoted_histogram_, "promoted");
}
} }

View File

@ -42,7 +42,6 @@ Log::Log(Logger* logger, const char* file_name)
if (FLAG_log_all) { if (FLAG_log_all) {
FLAG_log_api = true; FLAG_log_api = true;
FLAG_log_code = true; FLAG_log_code = true;
FLAG_log_gc = true;
FLAG_log_suspect = true; FLAG_log_suspect = true;
FLAG_log_handles = true; FLAG_log_handles = true;
FLAG_log_internal_timer_events = true; FLAG_log_internal_timer_events = true;

View File

@ -30,9 +30,9 @@ class Log {
void stop() { is_stopped_ = true; } void stop() { is_stopped_ = true; }
static bool InitLogAtStart() { static bool InitLogAtStart() {
return FLAG_log || FLAG_log_api || FLAG_log_code || FLAG_log_gc || return FLAG_log || FLAG_log_api || FLAG_log_code || FLAG_log_handles ||
FLAG_log_handles || FLAG_log_suspect || FLAG_ll_prof || FLAG_log_suspect || FLAG_ll_prof || FLAG_perf_basic_prof ||
FLAG_perf_basic_prof || FLAG_perf_prof || FLAG_log_source_code || FLAG_perf_prof || FLAG_log_source_code ||
FLAG_log_internal_timer_events || FLAG_prof_cpp || FLAG_trace_ic || FLAG_log_internal_timer_events || FLAG_prof_cpp || FLAG_trace_ic ||
FLAG_log_function_events; FLAG_log_function_events;
} }

View File

@ -1292,34 +1292,6 @@ void Logger::FunctionEvent(const char* reason, Script* script, int script_id,
msg.WriteToLogFile(); msg.WriteToLogFile();
} }
void Logger::HeapSampleBeginEvent(const char* space, const char* kind) {
if (!log_->IsEnabled() || !FLAG_log_gc) return;
Log::MessageBuilder msg(log_);
// Using non-relative system time in order to be able to synchronize with
// external memory profiling events (e.g. DOM memory size).
msg << "heap-sample-begin" << kNext << space << kNext << kind << kNext;
msg.Append("%.0f", V8::GetCurrentPlatform()->CurrentClockTimeMillis());
msg.WriteToLogFile();
}
void Logger::HeapSampleEndEvent(const char* space, const char* kind) {
if (!log_->IsEnabled() || !FLAG_log_gc) return;
Log::MessageBuilder msg(log_);
msg << "heap-sample-end" << kNext << space << kNext << kind;
msg.WriteToLogFile();
}
void Logger::HeapSampleItemEvent(const char* type, int number, int bytes) {
if (!log_->IsEnabled() || !FLAG_log_gc) return;
Log::MessageBuilder msg(log_);
msg << "heap-sample-item" << kNext << type << kNext << number << kNext
<< bytes;
msg.WriteToLogFile();
}
void Logger::RuntimeCallTimerEvent() { void Logger::RuntimeCallTimerEvent() {
RuntimeCallStats* stats = isolate_->counters()->runtime_call_stats(); RuntimeCallStats* stats = isolate_->counters()->runtime_call_stats();
RuntimeCallCounter* counter = stats->current_counter(); RuntimeCallCounter* counter = stats->current_counter();

View File

@ -37,7 +37,7 @@ namespace internal {
// //
// --log-all // --log-all
// Log all events to the file, default is off. This is the same as combining // Log all events to the file, default is off. This is the same as combining
// --log-api, --log-code, --log-gc, and --log-regexp. // --log-api, --log-code, and --log-regexp.
// //
// --log-api // --log-api
// Log API events to the logfile, default is off. --log-api implies --log. // Log API events to the logfile, default is off. --log-api implies --log.
@ -46,10 +46,6 @@ namespace internal {
// Log code (create, move, and delete) events to the logfile, default is off. // Log code (create, move, and delete) events to the logfile, default is off.
// --log-code implies --log. // --log-code implies --log.
// //
// --log-gc
// Log GC heap samples after each GC that can be processed by hp2ps, default
// is off. --log-gc implies --log.
//
// --log-regexp // --log-regexp
// Log creation and use of regular expressions, Default is off. // Log creation and use of regular expressions, Default is off.
// --log-regexp implies --log. // --log-regexp implies --log.
@ -207,19 +203,6 @@ class Logger : public CodeEventListener {
HeapObject* name_or_sfi = nullptr); HeapObject* name_or_sfi = nullptr);
void MapDetails(Map* map); void MapDetails(Map* map);
// ==== Events logged by --log-gc. ====
// Heap sampling events: start, end, and individual types.
void HeapSampleBeginEvent(const char* space, const char* kind);
void HeapSampleEndEvent(const char* space, const char* kind);
void HeapSampleItemEvent(const char* type, int number, int bytes);
void HeapSampleJSConstructorEvent(const char* constructor,
int number, int bytes);
void HeapSampleJSRetainersEvent(const char* constructor,
const char* event);
void HeapSampleJSProducerEvent(const char* constructor,
Address* stack);
void HeapSampleStats(const char* space, const char* kind,
intptr_t capacity, intptr_t used);
void SharedLibraryEvent(const std::string& library_path, uintptr_t start, void SharedLibraryEvent(const std::string& library_path, uintptr_t start,
uintptr_t end, intptr_t aslr_slide); uintptr_t end, intptr_t aslr_slide);

View File

@ -1,120 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2009 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This is an utility for converting V8 heap logs into .hp files that can
# be further processed using 'hp2ps' tool (bundled with GHC and Valgrind)
# to produce heap usage histograms.
# Sample usage:
# $ ./shell --log-gc script.js
# $ tools/process-heap-prof.py v8.log | hp2ps -c > script-heap-graph.ps
# ('-c' enables color, see hp2ps manual page for more options)
# or
# $ tools/process-heap-prof.py --js-cons-profile v8.log | hp2ps -c > script-heap-graph.ps
# to get JS constructor profile
import csv, sys, time, optparse
def ProcessLogFile(filename, options):
if options.js_cons_profile:
itemname = 'heap-js-cons-item'
else:
itemname = 'heap-sample-item'
first_call_time = None
sample_time = 0.0
sampling = False
try:
logfile = open(filename, 'rb')
try:
logreader = csv.reader(logfile)
print('JOB "v8"')
print('DATE "%s"' % time.asctime(time.localtime()))
print('SAMPLE_UNIT "seconds"')
print('VALUE_UNIT "bytes"')
for row in logreader:
if row[0] == 'heap-sample-begin' and row[1] == 'Heap':
sample_time = float(row[3])/1000.0
if first_call_time == None:
first_call_time = sample_time
sample_time -= first_call_time
print('BEGIN_SAMPLE %.2f' % sample_time)
sampling = True
elif row[0] == 'heap-sample-end' and row[1] == 'Heap':
print('END_SAMPLE %.2f' % sample_time)
sampling = False
elif row[0] == itemname and sampling:
print(row[1]),
if options.count:
print('%d' % (int(row[2]))),
if options.size:
print('%d' % (int(row[3]))),
print
finally:
logfile.close()
except:
sys.exit('can\'t open %s' % filename)
def BuildOptions():
result = optparse.OptionParser()
result.add_option("--js_cons_profile", help="Constructor profile",
default=False, action="store_true")
result.add_option("--size", help="Report object size",
default=False, action="store_true")
result.add_option("--count", help="Report object count",
default=False, action="store_true")
return result
def ProcessOptions(options):
if not options.size and not options.count:
options.size = True
return True
def Main():
parser = BuildOptions()
(options, args) = parser.parse_args()
if not ProcessOptions(options):
parser.print_help()
sys.exit();
if not args:
print "Missing logfile"
sys.exit();
ProcessLogFile(args[0], options)
if __name__ == '__main__':
sys.exit(Main())