[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:
parent
ee78c7d715
commit
6e086610e0
@ -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.")
|
||||||
|
@ -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) {
|
||||||
|
@ -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() {
|
||||||
|
@ -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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
28
src/log.cc
28
src/log.cc
@ -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();
|
||||||
|
19
src/log.h
19
src/log.h
@ -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);
|
||||||
|
@ -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())
|
|
Loading…
Reference in New Issue
Block a user