9e19d236ca
fields in a thread (i.e fields that are not Dart VM related) - Split the Thread structure to be a pure Dart per thread structure and add a pointer to os_thread which points to the OSThread structure - Change Schedule/UnSchedule to set the Dart Thread structure as the TLS of the thread when it is inside the Dart world and reset the TLS back to the OSThread strcuture when is exits the Dart World. - Moved the stack_base and few stack size related functions to OSThread from Isolate R=johnmccutchan@google.com, zra@google.com Review URL: https://codereview.chromium.org/1439483003 .
172 lines
3.3 KiB
C++
172 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.");
|
|
|
|
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
|