| Index: runtime/vm/log.cc
|
| diff --git a/runtime/vm/log.cc b/runtime/vm/log.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..784077ca89628cdf4864a3655dcb7a4da2e9cbdb
|
| --- /dev/null
|
| +++ b/runtime/vm/log.cc
|
| @@ -0,0 +1,126 @@
|
| +// 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.");
|
| +
|
| +Log::Log(LogPrinter printer)
|
| + : printer_(printer),
|
| + manual_flush_(0),
|
| + buffer_(0) {
|
| +}
|
| +
|
| +
|
| +void Log::Print(const char* format, ...) {
|
| + if (this == NoOpLog()) {
|
| + return;
|
| + }
|
| + // Measure.
|
| + va_list args;
|
| + va_start(args, format);
|
| + intptr_t len = OS::VSNPrint(NULL, 0, format, args);
|
| + va_end(args);
|
| +
|
| + // Print string to buffer.
|
| + char* buffer = reinterpret_cast<char*>(malloc(len + 1));
|
| + va_list args2;
|
| + va_start(args2, format);
|
| + OS::VSNPrint(buffer, (len + 1), format, args2);
|
| + va_end(args2);
|
| +
|
| + // 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_(str);
|
| + buffer_.TruncateTo(cursor);
|
| +}
|
| +
|
| +
|
| +void Log::Clear() {
|
| + if (this == NoOpLog()) {
|
| + return;
|
| + }
|
| + buffer_.TruncateTo(0);
|
| +}
|
| +
|
| +
|
| +intptr_t Log::cursor() const {
|
| + return buffer_.length();
|
| +}
|
| +
|
| +
|
| +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();
|
| + }
|
| +}
|
| +
|
| +
|
| +LogBlock::LogBlock(Thread* thread, Log* log)
|
| + : StackResource(thread->isolate()),
|
| + log_(log), cursor_(log->cursor()) {
|
| + CommonConstructor();
|
| +}
|
| +
|
| +
|
| +LogBlock::LogBlock(Isolate* isolate)
|
| + : StackResource(isolate),
|
| + log_(isolate->Log()), cursor_(isolate->Log()->cursor()) {
|
| + CommonConstructor();
|
| +}
|
| +
|
| +
|
| +LogBlock::LogBlock(Thread* thread)
|
| + : StackResource(thread->isolate()),
|
| + log_(thread->isolate()->Log()),
|
| + cursor_(thread->isolate()->Log()->cursor()) {
|
| + CommonConstructor();
|
| +}
|
| +
|
| +} // namespace dart
|
|
|