summaryrefslogtreecommitdiff
path: root/runtime/utils.h
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/utils.h')
-rw-r--r--runtime/utils.h67
1 files changed, 56 insertions, 11 deletions
diff --git a/runtime/utils.h b/runtime/utils.h
index 3e618247d0..3690f86a80 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -26,11 +26,15 @@
#include <vector>
#include "arch/instruction_set.h"
+#include "base/casts.h"
#include "base/logging.h"
#include "base/mutex.h"
+#include "base/stringpiece.h"
#include "globals.h"
#include "primitive.h"
+class BacktraceMap;
+
namespace art {
class ArtField;
@@ -220,12 +224,19 @@ std::string GetSchedulerGroupName(pid_t tid);
void SetThreadName(const char* thread_name);
// Dumps the native stack for thread 'tid' to 'os'.
-void DumpNativeStack(std::ostream& os, pid_t tid, const char* prefix = "",
- ArtMethod* current_method = nullptr, void* ucontext = nullptr)
+void DumpNativeStack(std::ostream& os,
+ pid_t tid,
+ BacktraceMap* map = nullptr,
+ const char* prefix = "",
+ ArtMethod* current_method = nullptr,
+ void* ucontext = nullptr)
NO_THREAD_SAFETY_ANALYSIS;
// Dumps the kernel stack for thread 'tid' to 'os'. Note that this is only available on linux-x86.
-void DumpKernelStack(std::ostream& os, pid_t tid, const char* prefix = "", bool include_count = true);
+void DumpKernelStack(std::ostream& os,
+ pid_t tid,
+ const char* prefix = "",
+ bool include_count = true);
// Find $ANDROID_ROOT, /system, or abort.
const char* GetAndroidRoot();
@@ -271,23 +282,21 @@ bool Exec(std::vector<std::string>& arg_vector, std::string* error_msg);
class VoidFunctor {
public:
template <typename A>
- inline void operator() (A a) const {
- UNUSED(a);
+ inline void operator() (A a ATTRIBUTE_UNUSED) const {
}
template <typename A, typename B>
- inline void operator() (A a, B b) const {
- UNUSED(a, b);
+ inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED) const {
}
template <typename A, typename B, typename C>
- inline void operator() (A a, B b, C c) const {
- UNUSED(a, b, c);
+ inline void operator() (A a ATTRIBUTE_UNUSED, B b ATTRIBUTE_UNUSED, C c ATTRIBUTE_UNUSED) const {
}
};
-template <typename Alloc>
-void Push32(std::vector<uint8_t, Alloc>* buf, int32_t data) {
+template <typename Vector>
+void Push32(Vector* buf, int32_t data) {
+ static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
buf->push_back(data & 0xff);
buf->push_back((data >> 8) & 0xff);
buf->push_back((data >> 16) & 0xff);
@@ -305,6 +314,42 @@ static inline constexpr bool ValidPointerSize(size_t pointer_size) {
void DumpMethodCFG(ArtMethod* method, std::ostream& os) SHARED_REQUIRES(Locks::mutator_lock_);
void DumpMethodCFG(const DexFile* dex_file, uint32_t dex_method_idx, std::ostream& os);
+static inline const void* EntryPointToCodePointer(const void* entry_point) {
+ uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
+ // TODO: Make this Thumb2 specific. It is benign on other architectures as code is always at
+ // least 2 byte aligned.
+ code &= ~0x1;
+ return reinterpret_cast<const void*>(code);
+}
+
+using UsageFn = void (*)(const char*, ...);
+
+template <typename T>
+static void ParseUintOption(const StringPiece& option,
+ const std::string& option_name,
+ T* out,
+ UsageFn Usage,
+ bool is_long_option = true) {
+ std::string option_prefix = option_name + (is_long_option ? "=" : "");
+ DCHECK(option.starts_with(option_prefix));
+ const char* value_string = option.substr(option_prefix.size()).data();
+ int64_t parsed_integer_value = 0;
+ if (!ParseInt(value_string, &parsed_integer_value)) {
+ Usage("Failed to parse %s '%s' as an integer", option_name.c_str(), value_string);
+ }
+ if (parsed_integer_value < 0) {
+ Usage("%s passed a negative value %d", option_name.c_str(), parsed_integer_value);
+ }
+ *out = dchecked_integral_cast<T>(parsed_integer_value);
+}
+
+void ParseDouble(const std::string& option,
+ char after_char,
+ double min,
+ double max,
+ double* parsed_value,
+ UsageFn Usage);
+
} // namespace art
#endif // ART_RUNTIME_UTILS_H_