#include "compiler_ir.h"
+#include "base/dumpable.h"
#include "backend.h"
#include "frontend.h"
#include "mir_graph.h"
#include <cstdint>
#include "backend.h"
+#include "base/dumpable.h"
#include "compiler.h"
#include "compiler_internals.h"
#include "driver/compiler_driver.h"
(cu.enable_debug & (1 << kDebugVerbose));
}
- if (gVerboseMethods.size() != 0) {
- cu.verbose = false;
- for (size_t i = 0; i < gVerboseMethods.size(); ++i) {
- if (PrettyMethod(method_idx, dex_file).find(gVerboseMethods[i])
- != std::string::npos) {
- cu.verbose = true;
- break;
- }
- }
+ if (driver.GetCompilerOptions().HasVerboseMethods()) {
+ cu.verbose = driver.GetCompilerOptions().IsVerboseMethod(PrettyMethod(method_idx, dex_file));
}
if (cu.verbose) {
#ifndef ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
#define ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+
namespace art {
-class CompilerOptions {
+class CompilerOptions FINAL {
public:
enum CompilerFilter {
kVerifyNone, // Skip verification and compile nothing except JNI stubs.
implicit_null_checks_(false),
implicit_so_checks_(false),
implicit_suspend_checks_(false),
- compile_pic_(false)
+ compile_pic_(false),
#ifdef ART_SEA_IR_MODE
- , sea_ir_mode_(false)
+ sea_ir_mode_(false),
#endif
- {}
+ verbose_methods_(nullptr) {
+ }
CompilerOptions(CompilerFilter compiler_filter,
size_t huge_method_threshold,
bool implicit_null_checks,
bool implicit_so_checks,
bool implicit_suspend_checks,
- bool compile_pic
+ bool compile_pic,
#ifdef ART_SEA_IR_MODE
- , bool sea_ir_mode
+ bool sea_ir_mode,
#endif
+ const std::vector<std::string>* verbose_methods
) : // NOLINT(whitespace/parens)
compiler_filter_(compiler_filter),
huge_method_threshold_(huge_method_threshold),
implicit_null_checks_(implicit_null_checks),
implicit_so_checks_(implicit_so_checks),
implicit_suspend_checks_(implicit_suspend_checks),
- compile_pic_(compile_pic)
+ compile_pic_(compile_pic),
#ifdef ART_SEA_IR_MODE
- , sea_ir_mode_(sea_ir_mode)
+ sea_ir_mode_(sea_ir_mode),
#endif
- {}
+ verbose_methods_(verbose_methods) {
+ }
CompilerFilter GetCompilerFilter() const {
return compiler_filter_;
return implicit_null_checks_;
}
- void SetImplicitNullChecks(bool new_val) {
- implicit_null_checks_ = new_val;
- }
-
bool GetImplicitStackOverflowChecks() const {
return implicit_so_checks_;
}
- void SetImplicitStackOverflowChecks(bool new_val) {
- implicit_so_checks_ = new_val;
- }
-
bool GetImplicitSuspendChecks() const {
return implicit_suspend_checks_;
}
- void SetImplicitSuspendChecks(bool new_val) {
- implicit_suspend_checks_ = new_val;
- }
-
#ifdef ART_SEA_IR_MODE
- bool GetSeaIrMode();
+ bool GetSeaIrMode() const {
+ return sea_ir_mode_;
+ }
#endif
bool GetGenerateGDBInformation() const {
return compile_pic_;
}
+ bool HasVerboseMethods() const {
+ return verbose_methods_ != nullptr && !verbose_methods_->empty();
+ }
+
+ bool IsVerboseMethod(const std::string& pretty_method) const {
+ for (const std::string& cur_method : *verbose_methods_) {
+ if (pretty_method.find(cur_method) != std::string::npos) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private:
CompilerFilter compiler_filter_;
- size_t huge_method_threshold_;
- size_t large_method_threshold_;
- size_t small_method_threshold_;
- size_t tiny_method_threshold_;
- size_t num_dex_methods_threshold_;
- bool generate_gdb_information_;
- bool include_patch_information_;
+ const size_t huge_method_threshold_;
+ const size_t large_method_threshold_;
+ const size_t small_method_threshold_;
+ const size_t tiny_method_threshold_;
+ const size_t num_dex_methods_threshold_;
+ const bool generate_gdb_information_;
+ const bool include_patch_information_;
// When using a profile file only the top K% of the profiled samples will be compiled.
- double top_k_profile_threshold_;
- bool include_debug_symbols_;
- bool implicit_null_checks_;
- bool implicit_so_checks_;
- bool implicit_suspend_checks_;
- bool compile_pic_;
+ const double top_k_profile_threshold_;
+ const bool include_debug_symbols_;
+ const bool implicit_null_checks_;
+ const bool implicit_so_checks_;
+ const bool implicit_suspend_checks_;
+ const bool compile_pic_;
+
#ifdef ART_SEA_IR_MODE
- bool sea_ir_mode_;
+ const bool sea_ir_mode_;
#endif
+
+ // Vector of methods to have verbose output enabled for.
+ const std::vector<std::string>* const verbose_methods_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
};
} // namespace art
}
// Print detected errors on output stream `os`.
- void Dump(std::ostream& os) {
+ void Dump(std::ostream& os) const {
for (size_t i = 0, e = errors_.Size(); i < e; ++i) {
os << dump_prefix_ << errors_.Get(i) << std::endl;
}
private:
// String displayed before dumped errors.
- const char* dump_prefix_;
+ const char* const dump_prefix_;
DISALLOW_COPY_AND_ASSIGN(GraphChecker);
};
#include "optimization.h"
+#include "base/dumpable.h"
#include "graph_checker.h"
namespace art {
#include "register_allocator.h"
+#include <sstream>
+
#include "base/bit_vector-inl.h"
#include "code_generator.h"
#include "ssa_liveness_analysis.h"
#include <sys/utsname.h>
#endif
+#include "base/dumpable.h"
#include "base/stl_util.h"
#include "base/stringpiece.h"
#include "base/timing_logger.h"
int small_method_threshold = CompilerOptions::kDefaultSmallMethodThreshold;
int tiny_method_threshold = CompilerOptions::kDefaultTinyMethodThreshold;
int num_dex_methods_threshold = CompilerOptions::kDefaultNumDexMethodsThreshold;
+ std::vector<std::string> verbose_methods;
// Initialize ISA and ISA features to default values.
InstructionSet instruction_set = kRuntimeISA;
include_patch_information = true;
} else if (option == "--no-include-patch-information") {
include_patch_information = false;
+ } else if (option.starts_with("--verbose-methods=")) {
+ // TODO: rather than switch off compiler logging, make all VLOG(compiler) messages conditional
+ // on having verbost methods.
+ gLogVerbosity.compiler = false;
+ Split(option.substr(strlen("--verbose-methods=")).ToString(), ',', &verbose_methods);
} else {
Usage("Unknown argument %s", option.data());
}
PassDriverMEOpts::PrintPassOptions();
}
- std::unique_ptr<CompilerOptions> compiler_options(new CompilerOptions(compiler_filter,
- huge_method_threshold,
- large_method_threshold,
- small_method_threshold,
- tiny_method_threshold,
- num_dex_methods_threshold,
- generate_gdb_information,
- include_patch_information,
- top_k_profile_threshold,
- include_debug_symbols,
- implicit_null_checks,
- implicit_so_checks,
- implicit_suspend_checks,
- compile_pic
+ std::unique_ptr<CompilerOptions> compiler_options(
+ new CompilerOptions(compiler_filter,
+ huge_method_threshold,
+ large_method_threshold,
+ small_method_threshold,
+ tiny_method_threshold,
+ num_dex_methods_threshold,
+ generate_gdb_information,
+ include_patch_information,
+ top_k_profile_threshold,
+ include_debug_symbols,
+ implicit_null_checks,
+ implicit_so_checks,
+ implicit_suspend_checks,
+ compile_pic,
#ifdef ART_SEA_IR_MODE
- , compiler_options.sea_ir_ =
- true;
+ true,
#endif
+ verbose_methods.empty() ? nullptr : &verbose_methods
)); // NOLINT(whitespace/parens)
// Done with usage checks, enable watchdog if requested
#include <inttypes.h>
#include <iostream>
+#include <sstream>
#include "base/logging.h"
#include "base/stringprintf.h"
#include "disassembler_mips.h"
#include <iostream>
+#include <sstream>
#include "base/logging.h"
#include "base/stringprintf.h"
#include "disassembler_x86.h"
#include <iostream>
+#include <sstream>
#include "base/logging.h"
#include "base/stringprintf.h"
#include <string>
#include <vector>
+#include "base/dumpable.h"
#include "base/scoped_flock.h"
#include "base/stringpiece.h"
#include "base/stringprintf.h"
LIBART_TARGET_SRC_FILES := \
$(LIBART_COMMON_SRC_FILES) \
- base/logging_android.cc \
jdwp/jdwp_adb.cc \
monitor_android.cc \
runtime_android.cc \
LIBART_HOST_SRC_FILES := \
$(LIBART_COMMON_SRC_FILES) \
- base/logging_linux.cc \
monitor_linux.cc \
runtime_linux.cc \
thread_linux.cc
endif
endif
LOCAL_ADDITIONAL_DEPENDENCIES := art/build/Android.common_build.mk
-# LOCAL_ADDITIONAL_DEPENDENCIES += $$(LOCAL_PATH)/Android.mk
+ LOCAL_ADDITIONAL_DEPENDENCIES += $$(LOCAL_PATH)/Android.mk
ifeq ($$(art_target_or_host),target)
LOCAL_MODULE_TARGET_ARCH := $$(ART_TARGET_SUPPORTED_ARCH)
#include "bit_vector.h"
+#include <sstream>
+
#include "allocator.h"
#include "bit_vector-inl.h"
--- /dev/null
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_BASE_DUMPABLE_H_
+#define ART_RUNTIME_BASE_DUMPABLE_H_
+
+#include "base/macros.h"
+
+namespace art {
+
+// A convenience to allow any class with a "Dump(std::ostream& os)" member function
+// but without an operator<< to be used as if it had an operator<<. Use like this:
+//
+// os << Dumpable<MyType>(my_type_instance);
+//
+template<typename T>
+class Dumpable FINAL {
+ public:
+ explicit Dumpable(const T& value) : value_(value) {
+ }
+
+ void Dump(std::ostream& os) const {
+ value_.Dump(os);
+ }
+
+ private:
+ const T& value_;
+
+ DISALLOW_COPY_AND_ASSIGN(Dumpable);
+};
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const Dumpable<T>& rhs) {
+ rhs.Dump(os);
+ return os;
+}
+
+} // namespace art
+
+#endif // ART_RUNTIME_BASE_DUMPABLE_H_
#include "logging.h"
+#include <sstream>
+
#include "base/mutex.h"
#include "runtime.h"
#include "thread-inl.h"
#include "utils.h"
+// Headers for LogMessage::LogLine.
+#ifdef HAVE_ANDROID_OS
+#include "cutils/log.h"
+#else
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
namespace art {
LogVerbosity gLogVerbosity;
-std::vector<std::string> gVerboseMethods;
-
unsigned int gAborting = 0;
static LogSeverity gMinimumLogSeverity = INFO;
: "art";
}
-// Configure logging based on ANDROID_LOG_TAGS environment variable.
-// We need to parse a string that looks like
-//
-// *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i
-//
-// The tag (or '*' for the global level) comes first, followed by a colon
-// and a letter indicating the minimum priority level we're expected to log.
-// This can be used to reveal or conceal logs with specific tags.
void InitLogging(char* argv[]) {
if (gCmdLine.get() != nullptr) {
return;
// Stash the command line for later use. We can use /proc/self/cmdline on Linux to recover this,
// but we don't have that luxury on the Mac, and there are a couple of argv[0] variants that are
// commonly used.
- if (argv != NULL) {
+ if (argv != nullptr) {
gCmdLine.reset(new std::string(argv[0]));
- for (size_t i = 1; argv[i] != NULL; ++i) {
+ for (size_t i = 1; argv[i] != nullptr; ++i) {
gCmdLine->append(" ");
gCmdLine->append(argv[i]);
}
gProgramInvocationName.reset(new std::string(argv[0]));
const char* last_slash = strrchr(argv[0], '/');
- gProgramInvocationShortName.reset(new std::string((last_slash != NULL) ? last_slash + 1
+ gProgramInvocationShortName.reset(new std::string((last_slash != nullptr) ? last_slash + 1
: argv[0]));
} else {
- // TODO: fall back to /proc/self/cmdline when argv is NULL on Linux
+ // TODO: fall back to /proc/self/cmdline when argv is NULL on Linux.
gCmdLine.reset(new std::string("<unset>"));
}
const char* tags = getenv("ANDROID_LOG_TAGS");
- if (tags == NULL) {
+ if (tags == nullptr) {
return;
}
}
}
-LogMessageData::LogMessageData(const char* file, int line, LogSeverity severity, int error)
- : file(file),
- line_number(line),
- severity(severity),
- error(error) {
- const char* last_slash = strrchr(file, '/');
- file = (last_slash == NULL) ? file : last_slash + 1;
-}
+// This indirection greatly reduces the stack impact of having
+// lots of checks/logging in a function.
+class LogMessageData {
+ public:
+ LogMessageData(const char* file, unsigned int line, LogSeverity severity, int error)
+ : file_(file),
+ line_number_(line),
+ severity_(severity),
+ error_(error) {
+ const char* last_slash = strrchr(file, '/');
+ file = (last_slash == nullptr) ? file : last_slash + 1;
+ }
+
+ const char * GetFile() const {
+ return file_;
+ }
+ unsigned int GetLineNumber() const {
+ return line_number_;
+ }
+
+ LogSeverity GetSeverity() const {
+ return severity_;
+ }
+
+ int GetError() const {
+ return error_;
+ }
+
+ std::ostream& GetBuffer() {
+ return buffer_;
+ }
+
+ std::string ToString() const {
+ return buffer_.str();
+ }
+
+ private:
+ std::ostringstream buffer_;
+ const char* const file_;
+ const unsigned int line_number_;
+ const LogSeverity severity_;
+ const int error_;
+
+ DISALLOW_COPY_AND_ASSIGN(LogMessageData);
+};
+
+
+LogMessage::LogMessage(const char* file, unsigned int line, LogSeverity severity, int error)
+ : data_(new LogMessageData(file, line, severity, error)) {
+}
LogMessage::~LogMessage() {
- if (data_->severity < gMinimumLogSeverity) {
+ if (data_->GetSeverity() < gMinimumLogSeverity) {
return; // No need to format something we're not going to output.
}
// Finish constructing the message.
- if (data_->error != -1) {
- data_->buffer << ": " << strerror(data_->error);
+ if (data_->GetError() != -1) {
+ data_->GetBuffer() << ": " << strerror(data_->GetError());
}
- std::string msg(data_->buffer.str());
+ std::string msg(data_->ToString());
// Do the actual logging with the lock held.
{
MutexLock mu(Thread::Current(), *Locks::logging_lock_);
if (msg.find('\n') == std::string::npos) {
- LogLine(*data_, msg.c_str());
+ LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetSeverity(), msg.c_str());
} else {
msg += '\n';
size_t i = 0;
while (i < msg.size()) {
size_t nl = msg.find('\n', i);
msg[nl] = '\0';
- LogLine(*data_, &msg[i]);
+ LogLine(data_->GetFile(), data_->GetLineNumber(), data_->GetSeverity(), &msg[i]);
i = nl + 1;
}
}
}
// Abort if necessary.
- if (data_->severity == FATAL) {
+ if (data_->GetSeverity() == FATAL) {
Runtime::Abort();
}
}
+std::ostream& LogMessage::stream() {
+ return data_->GetBuffer();
+}
+
+#ifdef HAVE_ANDROID_OS
+static const android_LogPriority kLogSeverityToAndroidLogPriority[] = {
+ ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN,
+ ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, ANDROID_LOG_FATAL
+};
+COMPILE_ASSERT(arraysize(kLogSeverityToAndroidLogPriority) == INTERNAL_FATAL + 1,
+ mismatch_in_size_of_kLogSeverityToAndroidLogPriority_and_values_in_LogSeverity);
+#endif
+
+void LogMessage::LogLine(const char* file, unsigned int line, LogSeverity log_severity,
+ const char* message) {
+#ifdef HAVE_ANDROID_OS
+ const char* tag = ProgramInvocationShortName();
+ int priority = kLogSeverityToAndroidLogPriority[log_severity];
+ if (priority == ANDROID_LOG_FATAL) {
+ LOG_PRI(priority, tag, "%s:%u] %s", file, line, message);
+ } else {
+ LOG_PRI(priority, tag, "%s", message);
+ }
+#else
+ static const char* log_characters = "VDIWEFF";
+ CHECK_EQ(strlen(log_characters), INTERNAL_FATAL + 1U);
+ char severity = log_characters[log_severity];
+ fprintf(stderr, "%s %c %5d %5d %s:%u] %s\n",
+ ProgramInvocationShortName(), severity, getpid(), ::art::GetTid(), file, line, message);
+#endif
+}
+
} // namespace art
#ifndef ART_RUNTIME_BASE_LOGGING_H_
#define ART_RUNTIME_BASE_LOGGING_H_
-#include <cerrno>
-#include <cstring>
-#include <iostream> // NOLINT
+#include <iostream>
#include <memory>
-#include <sstream>
-#include <signal.h>
-#include <vector>
#include "base/macros.h"
-#include "log_severity.h"
+namespace art {
+
+enum LogSeverity {
+ VERBOSE,
+ DEBUG,
+ INFO,
+ WARNING,
+ ERROR,
+ FATAL,
+ INTERNAL_FATAL, // For Runtime::Abort.
+};
+
+// The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code,
+// and the "-verbose:" command line argument.
+struct LogVerbosity {
+ bool class_linker; // Enabled with "-verbose:class".
+ bool compiler;
+ bool gc;
+ bool heap;
+ bool jdwp;
+ bool jni;
+ bool monitor;
+ bool profiler;
+ bool signals;
+ bool startup;
+ bool third_party_jni; // Enabled with "-verbose:third-party-jni".
+ bool threads;
+ bool verifier;
+};
+
+// Global log verbosity setting, initialized by InitLogging.
+extern LogVerbosity gLogVerbosity;
+
+// 0 if not abort, non-zero if an abort is in progress. Used on fatal exit to prevents recursive
+// aborts. Global declaration allows us to disable some error checking to ensure fatal shutdown
+// makes forward progress.
+extern unsigned int gAborting;
+
+// Configure logging based on ANDROID_LOG_TAGS environment variable.
+// We need to parse a string that looks like
+//
+// *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i
+//
+// The tag (or '*' for the global level) comes first, followed by a colon
+// and a letter indicating the minimum priority level we're expected to log.
+// This can be used to reveal or conceal logs with specific tags.
+extern void InitLogging(char* argv[]);
+
+// Returns the command line used to invoke the current tool or nullptr if InitLogging hasn't been
+// performed.
+extern const char* GetCmdLine();
+
+// The command used to start the ART runtime, such as "/system/bin/dalvikvm". If InitLogging hasn't
+// been performed then just returns "art"
+extern const char* ProgramInvocationName();
+
+// A short version of the command used to start the ART runtime, such as "dalvikvm". If InitLogging
+// hasn't been performed then just returns "art"
+extern const char* ProgramInvocationShortName();
+
+// Logs a message to logcat on Android otherwise to stderr. If the severity is FATAL it also causes
+// an abort. For example: LOG(FATAL) << "We didn't expect to reach here";
+#define LOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, -1).stream()
+
+// A variant of LOG that also logs the current errno value. To be used when library calls fail.
+#define PLOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, errno).stream()
+
+// Marker that code is yet to be implemented.
+#define UNIMPLEMENTED(level) LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "
+
+// Is verbose logging enabled for the given module? Where the module is defined in LogVerbosity.
+#define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module)
+
+// Variant of LOG that logs when verbose logging is enabled for a module. For example,
+// VLOG(jni) << "A JNI operation was performed";
+#define VLOG(module) \
+ if (VLOG_IS_ON(module)) \
+ ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
+
+// Return the stream associated with logging for the given module.
+#define VLOG_STREAM(module) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
+
+// Check whether condition x holds and LOG(FATAL) if not. The value of the expression x is only
+// evaluated once. Extra logging can be appended using << after. For example,
+// CHECK(false == true) results in a log message of "Check failed: false == true".
#define CHECK(x) \
if (UNLIKELY(!(x))) \
- ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
+ ::art::LogMessage(__FILE__, __LINE__, ::art::FATAL, -1).stream() \
<< "Check failed: " #x << " "
+// Helper for CHECK_xx(x,y) macros.
#define CHECK_OP(LHS, RHS, OP) \
for (auto _values = ::art::MakeEagerEvaluator(LHS, RHS); \
UNLIKELY(!(_values.lhs OP _values.rhs)); /* empty */) \
- ::art::LogMessage(__FILE__, __LINE__, FATAL, -1).stream() \
+ ::art::LogMessage(__FILE__, __LINE__, ::art::FATAL, -1).stream() \
<< "Check failed: " << #LHS << " " << #OP << " " << #RHS \
<< " (" #LHS "=" << _values.lhs << ", " #RHS "=" << _values.rhs << ") "
+
+// Check whether a condition holds between x and y, LOG(FATAL) if not. The value of the expressions
+// x and y is evaluated once. Extra logging can be appended using << after. For example,
+// CHECK_NE(0 == 1, false) results in "Check failed: false != false (0==1=false, false=false) ".
#define CHECK_EQ(x, y) CHECK_OP(x, y, ==)
#define CHECK_NE(x, y) CHECK_OP(x, y, !=)
#define CHECK_LE(x, y) CHECK_OP(x, y, <=)
#define CHECK_GE(x, y) CHECK_OP(x, y, >=)
#define CHECK_GT(x, y) CHECK_OP(x, y, >)
+// Helper for CHECK_STRxx(s1,s2) macros.
#define CHECK_STROP(s1, s2, sense) \
if (UNLIKELY((strcmp(s1, s2) == 0) != sense)) \
- LOG(FATAL) << "Check failed: " \
- << "\"" << s1 << "\"" \
- << (sense ? " == " : " != ") \
- << "\"" << s2 << "\""
+ LOG(::art::FATAL) << "Check failed: " \
+ << "\"" << s1 << "\"" \
+ << (sense ? " == " : " != ") \
+ << "\"" << s2 << "\""
+// Check for string (const char*) equality between s1 and s2, LOG(FATAL) if not.
#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)
+// Perform the pthread function call(args), LOG(FATAL) on error.
#define CHECK_PTHREAD_CALL(call, args, what) \
do { \
int rc = call args; \
if (rc != 0) { \
errno = rc; \
- PLOG(FATAL) << # call << " failed for " << what; \
+ PLOG(::art::FATAL) << # call << " failed for " << what; \
} \
} while (false)
// n / 2;
// }
#define CHECK_CONSTEXPR(x, out, dummy) \
- (UNLIKELY(!(x))) ? (LOG(FATAL) << "Check failed: " << #x out, dummy) :
-
-#ifndef NDEBUG
-
-#define DCHECK(x) CHECK(x)
-#define DCHECK_EQ(x, y) CHECK_EQ(x, y)
-#define DCHECK_NE(x, y) CHECK_NE(x, y)
-#define DCHECK_LE(x, y) CHECK_LE(x, y)
-#define DCHECK_LT(x, y) CHECK_LT(x, y)
-#define DCHECK_GE(x, y) CHECK_GE(x, y)
-#define DCHECK_GT(x, y) CHECK_GT(x, y)
-#define DCHECK_STREQ(s1, s2) CHECK_STREQ(s1, s2)
-#define DCHECK_STRNE(s1, s2) CHECK_STRNE(s1, s2)
-#define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy)
-
-#else // NDEBUG
-
-#define DCHECK(condition) \
- while (false) \
- CHECK(condition)
-
-#define DCHECK_EQ(val1, val2) \
- while (false) \
- CHECK_EQ(val1, val2)
-
-#define DCHECK_NE(val1, val2) \
- while (false) \
- CHECK_NE(val1, val2)
-
-#define DCHECK_LE(val1, val2) \
- while (false) \
- CHECK_LE(val1, val2)
-
-#define DCHECK_LT(val1, val2) \
- while (false) \
- CHECK_LT(val1, val2)
-
-#define DCHECK_GE(val1, val2) \
- while (false) \
- CHECK_GE(val1, val2)
-
-#define DCHECK_GT(val1, val2) \
- while (false) \
- CHECK_GT(val1, val2)
-
-#define DCHECK_STREQ(str1, str2) \
- while (false) \
- CHECK_STREQ(str1, str2)
+ (UNLIKELY(!(x))) ? (LOG(::art::FATAL) << "Check failed: " << #x out, dummy) :
-#define DCHECK_STRNE(str1, str2) \
- while (false) \
- CHECK_STRNE(str1, str2)
-
-#define DCHECK_CONSTEXPR(x, out, dummy) \
- (false && (x)) ? (dummy) :
+// DCHECKs are debug variants of CHECKs only enabled in debug builds. Generally CHECK should be
+// used unless profiling identifies a CHECK as being in performance critical code.
+#if defined(NDEBUG)
+static constexpr bool kEnableDChecks = false;
+#else
+static constexpr bool kEnableDChecks = true;
#endif
-#define LOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, -1).stream()
-#define PLOG(severity) ::art::LogMessage(__FILE__, __LINE__, severity, errno).stream()
-
-#define LG LOG(INFO)
-
-#define UNIMPLEMENTED(level) LOG(level) << __PRETTY_FUNCTION__ << " unimplemented "
-
-#define VLOG_IS_ON(module) UNLIKELY(::art::gLogVerbosity.module)
-#define VLOG(module) if (VLOG_IS_ON(module)) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
-#define VLOG_STREAM(module) ::art::LogMessage(__FILE__, __LINE__, INFO, -1).stream()
-
-//
-// Implementation details beyond this point.
-//
-
-namespace art {
+#define DCHECK(x) if (::art::kEnableDChecks) CHECK(x)
+#define DCHECK_EQ(x, y) if (::art::kEnableDChecks) CHECK_EQ(x, y)
+#define DCHECK_NE(x, y) if (::art::kEnableDChecks) CHECK_NE(x, y)
+#define DCHECK_LE(x, y) if (::art::kEnableDChecks) CHECK_LE(x, y)
+#define DCHECK_LT(x, y) if (::art::kEnableDChecks) CHECK_LT(x, y)
+#define DCHECK_GE(x, y) if (::art::kEnableDChecks) CHECK_GE(x, y)
+#define DCHECK_GT(x, y) if (::art::kEnableDChecks) CHECK_GT(x, y)
+#define DCHECK_STREQ(s1, s2) if (::art::kEnableDChecks) CHECK_STREQ(s1, s2)
+#define DCHECK_STRNE(s1, s2) if (::art::kEnableDChecks) CHECK_STRNE(s1, s2)
+#if defined(NDEBUG)
+#define DCHECK_CONSTEXPR(x, out, dummy)
+#else
+#define DCHECK_CONSTEXPR(x, out, dummy) CHECK_CONSTEXPR(x, out, dummy)
+#endif
+// Temporary class created to evaluate the LHS and RHS, used with MakeEagerEvaluator to infer the
+// types of LHS and RHS.
template <typename LHS, typename RHS>
struct EagerEvaluator {
EagerEvaluator(LHS l, RHS r) : lhs(l), rhs(r) { }
RHS rhs;
};
-// We want char*s to be treated as pointers, not strings. If you want them treated like strings,
-// you'd need to use CHECK_STREQ and CHECK_STRNE anyway to compare the characters rather than their
-// addresses. We could express this more succinctly with std::remove_const, but this is quick and
-// easy to understand, and works before we have C++0x. We rely on signed/unsigned warnings to
+// Helper function for CHECK_xx.
+template <typename LHS, typename RHS>
+static inline EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) {
+ return EagerEvaluator<LHS, RHS>(lhs, rhs);
+}
+
+// Explicitly instantiate EagerEvalue for pointers so that char*s aren't treated as strings. To
+// compare strings use CHECK_STREQ and CHECK_STRNE. We rely on signed/unsigned warnings to
// protect you against combinations not explicitly listed below.
#define EAGER_PTR_EVALUATOR(T1, T2) \
template <> struct EagerEvaluator<T1, T2> { \
EAGER_PTR_EVALUATOR(signed char*, const signed char*);
EAGER_PTR_EVALUATOR(signed char*, signed char*);
-template <typename LHS, typename RHS>
-EagerEvaluator<LHS, RHS> MakeEagerEvaluator(LHS lhs, RHS rhs) {
- return EagerEvaluator<LHS, RHS>(lhs, rhs);
-}
-
-// This indirection greatly reduces the stack impact of having
-// lots of checks/logging in a function.
-struct LogMessageData {
- public:
- LogMessageData(const char* file, int line, LogSeverity severity, int error);
- std::ostringstream buffer;
- const char* const file;
- const int line_number;
- const LogSeverity severity;
- const int error;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(LogMessageData);
-};
+// Data for the log message, not stored in LogMessage to avoid increasing the stack size.
+class LogMessageData;
+// A LogMessage is a temporarily scoped object used by LOG and the unlikely part of a CHECK. The
+// destructor will abort if the severity is FATAL.
class LogMessage {
public:
- LogMessage(const char* file, int line, LogSeverity severity, int error)
- : data_(new LogMessageData(file, line, severity, error)) {
- }
+ LogMessage(const char* file, unsigned int line, LogSeverity severity, int error);
~LogMessage(); // TODO: enable LOCKS_EXCLUDED(Locks::logging_lock_).
- std::ostream& stream() {
- return data_->buffer;
- }
+ // Returns the stream associated with the message, the LogMessage performs output when it goes
+ // out of scope.
+ std::ostream& stream();
- private:
- static void LogLine(const LogMessageData& data, const char*);
+ // The routine that performs the actual logging.
+ static void LogLine(const char* file, unsigned int line, LogSeverity severity, const char* msg);
+ private:
const std::unique_ptr<LogMessageData> data_;
- friend void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context);
- friend class Mutex;
DISALLOW_COPY_AND_ASSIGN(LogMessage);
};
-// A convenience to allow any class with a "Dump(std::ostream& os)" member function
-// but without an operator<< to be used as if it had an operator<<. Use like this:
-//
-// os << Dumpable<MyType>(my_type_instance);
-//
-template<typename T>
-class Dumpable {
- public:
- explicit Dumpable(T& value) : value_(value) {
- }
-
- void Dump(std::ostream& os) const {
- value_.Dump(os);
- }
-
- private:
- T& value_;
-
- DISALLOW_COPY_AND_ASSIGN(Dumpable);
-};
-
-template<typename T>
-std::ostream& operator<<(std::ostream& os, const Dumpable<T>& rhs) {
- rhs.Dump(os);
- return os;
-}
-
-template<typename T>
-class ConstDumpable {
- public:
- explicit ConstDumpable(const T& value) : value_(value) {
- }
-
- void Dump(std::ostream& os) const {
- value_.Dump(os);
- }
-
- private:
- const T& value_;
-
- DISALLOW_COPY_AND_ASSIGN(ConstDumpable);
-};
-
-template<typename T>
-std::ostream& operator<<(std::ostream& os, const ConstDumpable<T>& rhs) {
- rhs.Dump(os);
- return os;
-}
-
-// Helps you use operator<< in a const char*-like context such as our various 'F' methods with
-// format strings.
-template<typename T>
-class ToStr {
- public:
- explicit ToStr(const T& value) {
- std::ostringstream os;
- os << value;
- s_ = os.str();
- }
-
- const char* c_str() const {
- return s_.c_str();
- }
-
- const std::string& str() const {
- return s_;
- }
-
- private:
- std::string s_;
- DISALLOW_COPY_AND_ASSIGN(ToStr);
-};
-
-// The members of this struct are the valid arguments to VLOG and VLOG_IS_ON in code,
-// and the "-verbose:" command line argument.
-struct LogVerbosity {
- bool class_linker; // Enabled with "-verbose:class".
- bool compiler;
- bool gc;
- bool heap;
- bool jdwp;
- bool jni;
- bool monitor;
- bool profiler;
- bool signals;
- bool startup;
- bool third_party_jni; // Enabled with "-verbose:third-party-jni".
- bool threads;
- bool verifier;
-};
-
-extern LogVerbosity gLogVerbosity;
-
-extern std::vector<std::string> gVerboseMethods;
-
-// Used on fatal exit. Prevents recursive aborts. Allows us to disable
-// some error checking to ensure fatal shutdown makes forward progress.
-extern unsigned int gAborting;
-
-extern void InitLogging(char* argv[]);
-
-extern const char* GetCmdLine();
-extern const char* ProgramInvocationName();
-extern const char* ProgramInvocationShortName();
-
} // namespace art
#endif // ART_RUNTIME_BASE_LOGGING_H_
+++ /dev/null
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "logging.h"
-
-#include <unistd.h>
-
-#include <iostream>
-
-#include "base/stringprintf.h"
-#include "cutils/log.h"
-
-namespace art {
-
-static const int kLogSeverityToAndroidLogPriority[] = {
- ANDROID_LOG_VERBOSE, ANDROID_LOG_DEBUG, ANDROID_LOG_INFO, ANDROID_LOG_WARN,
- ANDROID_LOG_ERROR, ANDROID_LOG_FATAL, ANDROID_LOG_FATAL
-};
-
-void LogMessage::LogLine(const LogMessageData& data, const char* message) {
- const char* tag = ProgramInvocationShortName();
- int priority = kLogSeverityToAndroidLogPriority[data.severity];
- if (priority == ANDROID_LOG_FATAL) {
- LOG_PRI(priority, tag, "%s:%d] %s", data.file, data.line_number, message);
- } else {
- LOG_PRI(priority, tag, "%s", message);
- }
-}
-
-} // namespace art
if (this != Locks::logging_lock_) {
LOG(FATAL) << "Unexpected state_ in unlock " << cur_state << " for " << name_;
} else {
- LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
- LogMessage::LogLine(data, StringPrintf("Unexpected state_ %d in unlock for %s",
- cur_state, name_).c_str());
+ LogMessage::LogLine(__FILE__, __LINE__, INTERNAL_FATAL,
+ StringPrintf("Unexpected state_ %d in unlock for %s",
+ cur_state, name_).c_str());
_exit(1);
}
}
* limitations under the License.
*/
-#include "logging.h"
+#ifndef ART_RUNTIME_BASE_TO_STR_H_
+#define ART_RUNTIME_BASE_TO_STR_H_
-#include <sys/types.h>
-#include <unistd.h>
+#include <sstream>
-#include <cstdio>
-#include <cstring>
-#include <iostream>
+namespace art {
-#include "base/stringprintf.h"
-#include "utils.h"
+// Helps you use operator<< in a const char*-like context such as our various 'F' methods with
+// format strings.
+template<typename T>
+class ToStr {
+ public:
+ explicit ToStr(const T& value) {
+ std::ostringstream os;
+ os << value;
+ s_ = os.str();
+ }
-namespace art {
+ const char* c_str() const {
+ return s_.c_str();
+ }
-void LogMessage::LogLine(const LogMessageData& data, const char* message) {
- char severity = "VDIWEFF"[data.severity];
- fprintf(stderr, "%s %c %5d %5d %s:%d] %s\n",
- ProgramInvocationShortName(), severity, getpid(), ::art::GetTid(),
- data.file, data.line_number, message);
-}
+ const std::string& str() const {
+ return s_;
+ }
+
+ private:
+ std::string s_;
+ DISALLOW_COPY_AND_ASSIGN(ToStr);
+};
} // namespace art
+
+#endif // ART_RUNTIME_BASE_TO_STR_H_
struct stat st;
int result = TEMP_FAILURE_RETRY(fstat(Fd(), &st));
if (result == -1) {
- PLOG(WARNING) << "Failed to stat file '" << GetPath() << "'";
+ PLOG(::art::WARNING) << "Failed to stat file '" << GetPath() << "'";
return false;
}
file_size_ = st.st_size;
mapped_file_ = mmap(NULL, file_size_, PROT_READ, MAP_PRIVATE, Fd(), 0);
} while (mapped_file_ == MAP_FAILED && errno == EINTR);
if (mapped_file_ == MAP_FAILED) {
- PLOG(WARNING) << "Failed to mmap file '" << GetPath() << "' of size "
- << file_size_ << " bytes to memory";
+ PLOG(::art::WARNING) << "Failed to mmap file '" << GetPath() << "' of size "
+ << file_size_ << " bytes to memory";
return false;
}
map_mode_ = kMapReadOnly;
int result = TEMP_FAILURE_RETRY(ftruncate(Fd(), file_size));
#endif
if (result == -1) {
- PLOG(ERROR) << "Failed to truncate file '" << GetPath()
- << "' to size " << file_size;
+ PLOG(::art::ERROR) << "Failed to truncate file '" << GetPath() << "' to size " << file_size;
return false;
}
file_size_ = file_size;
mmap(NULL, file_size_, PROT_READ | PROT_WRITE, MAP_SHARED, Fd(), 0);
} while (mapped_file_ == MAP_FAILED && errno == EINTR);
if (mapped_file_ == MAP_FAILED) {
- PLOG(WARNING) << "Failed to mmap file '" << GetPath() << "' of size "
+ PLOG(::art::WARNING) << "Failed to mmap file '" << GetPath() << "' of size "
<< file_size_ << " bytes to memory";
return false;
}
CHECK(IsMapped());
int result = TEMP_FAILURE_RETRY(munmap(mapped_file_, file_size_));
if (result == -1) {
- PLOG(WARNING) << "Failed unmap file '" << GetPath() << "' of size "
- << file_size_;
+ PLOG(::art::WARNING) << "Failed unmap file '" << GetPath() << "' of size " << file_size_;
return false;
} else {
mapped_file_ = NULL;
#include <zlib.h>
#include "base/logging.h"
+#include "base/to_str.h"
#include "class_linker.h"
#include "class_linker-inl.h"
#include "dex_file-inl.h"
int main(int argc, char **argv) {
art::InitLogging(argv);
- LOG(INFO) << "Running main() from common_runtime_test.cc...";
+ LOG(::art::INFO) << "Running main() from common_runtime_test.cc...";
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
#include <string.h>
#include <sys/file.h>
#include <sys/stat.h>
+
#include <memory>
+#include <sstream>
#include "base/logging.h"
#include "base/stringprintf.h"
#include <inttypes.h>
#include <iomanip>
+#include <sstream>
#include "base/stringprintf.h"
#include "dex_file-inl.h"
InvokeType invoke_type = it.GetInvokeType();
uint32_t method_idx = it.GetMemberIndex();
if (false) {
- LG << invoke_type << " " << PrettyMethod(method_idx, dex_file);
+ LOG(INFO) << invoke_type << " " << PrettyMethod(method_idx, dex_file);
}
it.Next();
}
#include "base/logging.h"
+namespace art {
+
// Architecture dependent flags for the ELF header.
#define EF_ARM_EABI_VER5 0x05000000
#define EF_MIPS_ABI_O32 0x00001000
}
}
+} // namespace art
+
#endif // ART_RUNTIME_ELF_UTILS_H_
uint64_t fpr_result)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
// Compute address of return PC and sanity check that it currently holds 0.
- uint32_t return_pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, Runtime::kRefsOnly);
+ size_t return_pc_offset = GetCalleeSaveReturnPcOffset(kRuntimeISA, Runtime::kRefsOnly);
uintptr_t* return_pc = reinterpret_cast<uintptr_t*>(reinterpret_cast<uint8_t*>(sp) +
return_pc_offset);
CHECK_EQ(*return_pc, 0U);
*/
#include "entrypoints/entrypoint_utils-inl.h"
+#include "mirror/art_method-inl.h"
#include "mirror/object-inl.h"
#include "thread-inl.h"
#include "verify_object-inl.h"
static void art_heap_corruption(const char* function) {
- LOG(FATAL) << "Corrupt heap detected in: " << function;
+ LOG(::art::FATAL) << "Corrupt heap detected in: " << function;
}
static void art_heap_usage_error(const char* function, void* p) {
- LOG(FATAL) << "Incorrect use of function '" << function << "' argument " << p << " not expected";
+ LOG(::art::FATAL) << "Incorrect use of function '" << function << "' argument " << p << " not expected";
}
#include "globals.h"
int rc = madvise(start, length, MADV_DONTNEED);
if (UNLIKELY(rc != 0)) {
errno = rc;
- PLOG(FATAL) << "madvise failed during heap trimming";
+ PLOG(::art::FATAL) << "madvise failed during heap trimming";
}
size_t* reclaimed = reinterpret_cast<size_t*>(arg);
*reclaimed += length;
#include <map>
#include <list>
+#include <sstream>
#include <vector>
namespace art {
#include "garbage_collector.h"
+#include "base/dumpable.h"
#include "base/histogram-inl.h"
#include "base/logging.h"
#include "base/mutex-inl.h"
if (iterations == 0) {
return;
}
- os << ConstDumpable<CumulativeLogger>(logger);
+ os << Dumpable<CumulativeLogger>(logger);
const uint64_t total_ns = logger.GetTotalNs();
double seconds = NsToMs(logger.GetTotalNs()) / 1000.0;
const uint64_t freed_bytes = GetTotalFreedBytes();
#include "semi_space-inl.h"
+#include <climits>
#include <functional>
#include <numeric>
-#include <climits>
+#include <sstream>
#include <vector>
#include "base/logging.h"
#include <vector>
#include "base/allocator.h"
+#include "base/dumpable.h"
#include "base/histogram-inl.h"
#include "base/stl_util.h"
#include "common_throws.h"
<< percent_free << "% free, " << PrettySize(current_heap_size) << "/"
<< PrettySize(total_memory) << ", " << "paused " << pause_string.str()
<< " total " << PrettyDuration((duration / 1000) * 1000);
- VLOG(heap) << ConstDumpable<TimingLogger>(*current_gc_iteration_.GetTimings());
+ VLOG(heap) << Dumpable<TimingLogger>(*current_gc_iteration_.GetTimings());
}
FinishGC(self, gc_type);
// Inform DDMS that a GC completed.
#include <random>
+#include "base/macros.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "base/scoped_flock.h"
#include <sys/uio.h>
+#include <sstream>
+
#include "arch/context.h"
#include "atomic.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "debugger.h"
#include "dex_file-inl.h"
+#include "entrypoints/quick/quick_entrypoints.h"
#include "entrypoints/quick/quick_alloc_entrypoints.h"
#include "entrypoints/runtime_asm_entrypoints.h"
#include "gc_root-inl.h"
#include "mirror/object_array-inl.h"
#include "mirror/object-inl.h"
#include "nth_caller_visitor.h"
-#if !defined(ART_USE_PORTABLE_COMPILER)
-#include "entrypoints/quick/quick_entrypoints.h"
-#endif
#include "os.h"
#include "scoped_thread_state_change.h"
#include "thread.h"
#include <math.h>
+#include <sstream>
+
#include "base/logging.h"
#include "class_linker-inl.h"
#include "common_throws.h"
#include <dlfcn.h>
+#include "base/dumpable.h"
#include "base/mutex.h"
#include "base/stl_util.h"
#include "check_jni.h"
os << "JNIWeakGlobalRefType";
return os;
default:
- LOG(FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
- return os;
+ LOG(::art::FATAL) << "jobjectRefType[" << static_cast<int>(rhs) << "]";
+ UNREACHABLE();
}
}
+++ /dev/null
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_LOG_SEVERITY_H_
-#define ART_RUNTIME_LOG_SEVERITY_H_
-
-typedef int LogSeverity;
-
-const int VERBOSE = 0, DEBUG = 1, INFO = 2, WARNING = 3, ERROR = 4, FATAL = 5;
-const int INTERNAL_FATAL = 6; // For Runtime::Abort.
-
-#endif // ART_RUNTIME_LOG_SEVERITY_H_
*/
#include "mem_map.h"
-#include "thread-inl.h"
-#include <inttypes.h>
#include <backtrace/BacktraceMap.h>
+#include <inttypes.h>
+
#include <memory>
+#include <sstream>
// See CreateStartPos below.
#ifdef __BIONIC__
#include "base/stringprintf.h"
#include "ScopedFd.h"
+#include "thread-inl.h"
#include "utils.h"
#define USE_ASHMEM 1
#ifndef ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_
#define ART_RUNTIME_NATIVE_SCOPED_FAST_NATIVE_OBJECT_ACCESS_H_
-#include "mirror/art_method.h"
+#include "mirror/art_method-inl.h"
#include "scoped_thread_state_change.h"
namespace art {
#include "parsed_options.h"
+#include <sstream>
+
#ifdef HAVE_ANDROID_OS
#include "cutils/properties.h"
#endif
return false;
}
}
- } else if (StartsWith(option, "-verbose-methods:")) {
- gLogVerbosity.compiler = false;
- Split(option.substr(strlen("-verbose-methods:")), ',', &gVerboseMethods);
} else if (StartsWith(option, "-Xlockprofthreshold:")) {
if (!ParseUnsignedInteger(option, ':', &lock_profiling_threshold_)) {
return false;
#include "arch/x86_64/registers_x86_64.h"
#include "asm_support.h"
#include "atomic.h"
+#include "base/dumpable.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "debugger.h"
}
struct AbortState {
- void Dump(std::ostream& os) {
+ void Dump(std::ostream& os) const {
if (gAborting > 1) {
os << "Runtime aborting --- recursively, so no thread-specific detail!\n";
return;
}
// No thread-safety analysis as we do explicitly test for holding the mutator lock.
- void DumpThread(std::ostream& os, Thread* self) NO_THREAD_SAFETY_ANALYSIS {
+ void DumpThread(std::ostream& os, Thread* self) const NO_THREAD_SAFETY_ANALYSIS {
DCHECK(Locks::mutator_lock_->IsExclusiveHeld(self) || Locks::mutator_lock_->IsSharedHeld(self));
self->Dump(os);
if (self->IsExceptionPending()) {
}
}
- void DumpAllThreads(std::ostream& os, Thread* self) {
+ void DumpAllThreads(std::ostream& os, Thread* self) const {
Runtime* runtime = Runtime::Current();
if (runtime != nullptr) {
ThreadList* thread_list = runtime->GetThreadList();
struct sigaction old_action;
void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
- static bool handlingUnexpectedSignal = false;
- if (handlingUnexpectedSignal) {
- LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
- LogMessage::LogLine(data, "HandleUnexpectedSignal reentered\n");
+ static bool handling_unexpected_signal = false;
+ if (handling_unexpected_signal) {
+ LogMessage::LogLine(__FILE__, __LINE__, INTERNAL_FATAL, "HandleUnexpectedSignal reentered\n");
_exit(1);
}
- handlingUnexpectedSignal = true;
+ handling_unexpected_signal = true;
gAborting++; // set before taking any locks
MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_);
#include <sys/utsname.h>
#include <inttypes.h>
+#include <sstream>
+
+#include "base/dumpable.h"
#include "base/logging.h"
#include "base/mutex.h"
#include "base/stringprintf.h"
static constexpr bool kDumpHeapObjectOnSigsevg = false;
struct Backtrace {
- void Dump(std::ostream& os) {
+ void Dump(std::ostream& os) const {
DumpNativeStack(os, GetTid(), "\t");
}
};
struct OsInfo {
- void Dump(std::ostream& os) {
+ void Dump(std::ostream& os) const {
utsname info;
uname(&info);
// Linux 2.6.38.8-gg784 (x86_64)
}
struct UContext {
- explicit UContext(void* raw_context) : context(reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext) {}
+ explicit UContext(void* raw_context) :
+ context(reinterpret_cast<ucontext_t*>(raw_context)->uc_mcontext) {
+ }
- void Dump(std::ostream& os) {
+ void Dump(std::ostream& os) const {
// TODO: support non-x86 hosts (not urgent because this code doesn't run on targets).
#if defined(__APPLE__) && defined(__i386__)
DumpRegister32(os, "eax", context->__ss.__eax);
#endif
}
- void DumpRegister32(std::ostream& os, const char* name, uint32_t value) {
+ void DumpRegister32(std::ostream& os, const char* name, uint32_t value) const {
os << StringPrintf(" %6s: 0x%08x", name, value);
}
- void DumpRegister64(std::ostream& os, const char* name, uint64_t value) {
+ void DumpRegister64(std::ostream& os, const char* name, uint64_t value) const {
os << StringPrintf(" %6s: 0x%016" PRIx64, name, value);
}
- void DumpX86Flags(std::ostream& os, uint32_t flags) {
+ void DumpX86Flags(std::ostream& os, uint32_t flags) const {
os << " [";
if ((flags & (1 << 0)) != 0) {
os << " CF";
void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) {
static bool handlingUnexpectedSignal = false;
if (handlingUnexpectedSignal) {
- LogMessageData data(__FILE__, __LINE__, INTERNAL_FATAL, -1);
- LogMessage::LogLine(data, "HandleUnexpectedSignal reentered\n");
+ LogMessage::LogLine(__FILE__, __LINE__, INTERNAL_FATAL, "HandleUnexpectedSignal reentered\n");
_exit(1);
}
handlingUnexpectedSignal = true;
#include <sys/types.h>
#include <unistd.h>
+#include <sstream>
+
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
#include "gc/heap.h"
#include <cerrno>
#include <iostream>
#include <list>
+#include <sstream>
#include "arch/context.h"
#include "base/mutex.h"
+#include "base/to_str.h"
#include "class_linker-inl.h"
#include "class_linker.h"
#include "debugger.h"
#include "thread.h"
+#include <signal.h>
+
namespace art {
void Thread::SetNativePriority(int) {
#include <sys/types.h>
#include <unistd.h>
+#include <sstream>
+
#include "base/mutex.h"
#include "base/mutex-inl.h"
#include "base/timing_logger.h"
VLOG(threads) << "Resume(" << reinterpret_cast<void*>(thread) << ") complete";
}
-static void ThreadSuspendByPeerWarning(Thread* self, int level, const char* message, jobject peer) {
+static void ThreadSuspendByPeerWarning(Thread* self, LogSeverity severity, const char* message,
+ jobject peer) {
JNIEnvExt* env = self->GetJniEnv();
ScopedLocalRef<jstring>
scoped_name_string(env, (jstring)env->GetObjectField(peer,
WellKnownClasses::java_lang_Thread_name));
ScopedUtfChars scoped_name_chars(env, scoped_name_string.get());
if (scoped_name_chars.c_str() == NULL) {
- LOG(level) << message << ": " << peer;
+ LOG(severity) << message << ": " << peer;
env->ExceptionClear();
} else {
- LOG(level) << message << ": " << peer << ":" << scoped_name_chars.c_str();
+ LOG(severity) << message << ": " << peer << ":" << scoped_name_chars.c_str();
}
}
}
}
-static void ThreadSuspendByThreadIdWarning(int level, const char* message, uint32_t thread_id) {
- LOG(level) << StringPrintf("%s: %d", message, thread_id);
+static void ThreadSuspendByThreadIdWarning(LogSeverity severity, const char* message,
+ uint32_t thread_id) {
+ LOG(severity) << StringPrintf("%s: %d", message, thread_id);
}
Thread* ThreadList::SuspendThreadByThreadId(uint32_t thread_id, bool debug_suspension,
#include <stdlib.h>
+#include <sstream>
+
#include "base/logging.h"
#include "mirror/class.h"
#include "ScopedLocalRef.h"