Files
sdk/runtime/vm/log.cc
T
Regis Crelier 7f57ebcfa1 Remove signature classes from the VM.
They were used as the class of closure instances and as the type class of
function types.
All closure instances now have class _Closure and function types are represented
by a new class FunctionType extending AbstractType.
Fix issue 24567 and add regression test.

R=asiva@google.com, rmacnak@google.com

Review URL: https://codereview.chromium.org/1584223006 .
2016-01-19 16:32:59 -08:00

173 lines
3.3 KiB
C++

// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "vm/log.h"
#include "vm/flags.h"
#include "vm/thread.h"
namespace dart {
DEFINE_FLAG(bool, force_log_flush, false, "Always flush log messages.");
DEFINE_FLAG(charp, isolate_log_filter, NULL,
"Log isolates whose name include the filter. "
"Default: service isolate log messages are suppressed "
"(specify 'vm-service' to log them).");
Log::Log(LogPrinter printer)
: printer_(printer),
manual_flush_(0),
buffer_(0) {
}
Log::~Log() {
// Did someone enable manual flushing and then forgot to Flush?
ASSERT(cursor() == 0);
}
Log* Log::Current() {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
if (isolate != NULL && Log::ShouldLogForIsolate(isolate)) {
OSThread* os_thread = thread->os_thread();
ASSERT(os_thread != NULL);
return os_thread->log();
} else {
return Log::NoOpLog();
}
}
void Log::Print(const char* format, ...) {
if (this == NoOpLog()) {
return;
}
va_list args;
va_start(args, format);
VPrint(format, args);
va_end(args);
}
void Log::VPrint(const char* format, va_list args) {
if (this == NoOpLog()) {
return;
}
// Measure.
va_list measure_args;
va_copy(measure_args, args);
intptr_t len = OS::VSNPrint(NULL, 0, format, measure_args);
va_end(measure_args);
// Print.
char* buffer = reinterpret_cast<char*>(malloc(len + 1));
va_list print_args;
va_copy(print_args, args);
OS::VSNPrint(buffer, (len + 1), format, print_args);
va_end(print_args);
// Append.
// NOTE: does not append the '\0' character.
for (intptr_t i = 0; i < len; i++) {
buffer_.Add(buffer[i]);
}
free(buffer);
if ((manual_flush_ == 0) || FLAG_force_log_flush) {
Flush();
}
}
void Log::Flush(const intptr_t cursor) {
if (this == NoOpLog()) {
return;
}
if (buffer_.is_empty()) {
return;
}
if (buffer_.length() <= cursor) {
return;
}
TerminateString();
const char* str = &buffer_[cursor];
ASSERT(str != NULL);
printer_("%s", str);
buffer_.TruncateTo(cursor);
}
void Log::Clear() {
if (this == NoOpLog()) {
return;
}
buffer_.TruncateTo(0);
}
intptr_t Log::cursor() const {
return buffer_.length();
}
bool Log::ShouldLogForIsolate(const Isolate* isolate) {
if (FLAG_isolate_log_filter == NULL) {
if (isolate->is_service_isolate()) {
// By default, do not log for the service isolate.
return false;
}
return true;
}
const char* name = isolate->name();
ASSERT(name != NULL);
if (strstr(name, FLAG_isolate_log_filter) == NULL) {
// Filter does not match, do not log for this isolate.
return false;
}
return true;
}
Log Log::noop_log_;
Log* Log::NoOpLog() {
return &noop_log_;
}
void Log::TerminateString() {
buffer_.Add('\0');
}
void Log::EnableManualFlush() {
manual_flush_++;
}
void Log::DisableManualFlush() {
manual_flush_--;
ASSERT(manual_flush_ >= 0);
if (manual_flush_ == 0) {
Flush();
}
}
void LogBlock::Initialize() {
log_->EnableManualFlush();
}
LogBlock::~LogBlock() {
log_->Flush(cursor_);
log_->DisableManualFlush();
}
} // namespace dart