Add AllocStackTrace(). Move InternalStackTrace to managed heap.
Replaces trace.method and trace.pc with IntArray and ObjectArray<Method>.
Exception_tests pass.
Change-Id: I54431bbf8031b186fdd360ec27a31b11c8eff052
diff --git a/src/class_linker.h b/src/class_linker.h
index c85fb4e..b62433c 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -126,6 +126,11 @@
const DexFile& FindDexFile(const DexCache* dex_cache) const;
DexCache* FindDexCache(const DexFile& dex_file) const;
+ template <class T>
+ ObjectArray<T>* AllocObjectArray(size_t length) {
+ return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
+ }
+
ObjectArray<StackTraceElement>* AllocStackTraceElementArray(size_t length);
private:
@@ -153,10 +158,6 @@
DexCache* AllocDexCache(const DexFile& dex_file);
Field* AllocField();
Method* AllocMethod();
- template <class T>
- ObjectArray<T>* AllocObjectArray(size_t length) {
- return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
- }
CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
Class* CreatePrimitiveClass(const char* descriptor);
diff --git a/src/exception_test.cc b/src/exception_test.cc
index 4337d7a..a1a101d 100644
--- a/src/exception_test.cc
+++ b/src/exception_test.cc
@@ -148,18 +148,18 @@
Thread* thread = Thread::Current();
thread->SetTopOfStack(fake_stack);
- Thread::InternalStackTrace* traces = thread->GetStackTrace(2);
- ObjectArray<StackTraceElement>* trace_array = thread->GetStackTraceElement(2, traces);
- delete[] traces;
+ ObjectArray<StackTraceElement>* trace_array = thread->AllocStackTrace(2);
ASSERT_TRUE(trace_array->Get(0) != NULL);
- EXPECT_STREQ("java.lang.MyClass", trace_array->Get(0)->GetDeclaringClass()->ToModifiedUtf8().c_str());
+ EXPECT_STREQ("java.lang.MyClass",
+ trace_array->Get(0)->GetDeclaringClass()->ToModifiedUtf8().c_str());
EXPECT_STREQ("MyClass.java", trace_array->Get(0)->GetFileName()->ToModifiedUtf8().c_str());
EXPECT_STREQ("g", trace_array->Get(0)->GetMethodName()->ToModifiedUtf8().c_str());
EXPECT_EQ(22u, trace_array->Get(0)->GetLineNumber());
ASSERT_TRUE(trace_array->Get(1) != NULL);
- EXPECT_STREQ("java.lang.MyClass", trace_array->Get(1)->GetDeclaringClass()->ToModifiedUtf8().c_str());
+ EXPECT_STREQ("java.lang.MyClass",
+ trace_array->Get(1)->GetDeclaringClass()->ToModifiedUtf8().c_str());
EXPECT_STREQ("MyClass.java", trace_array->Get(1)->GetFileName()->ToModifiedUtf8().c_str());
EXPECT_STREQ("f", trace_array->Get(1)->GetMethodName()->ToModifiedUtf8().c_str());
EXPECT_EQ(7u, trace_array->Get(1)->GetLineNumber());
diff --git a/src/thread.cc b/src/thread.cc
index 717c6f7..2e7b6a9 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -316,33 +316,44 @@
return result;
}
-// TODO: Replaces trace.method and trace.pc with IntArray nad
-// ObjectArray<Method>.
-Thread::InternalStackTrace* Thread::GetStackTrace(uint16_t length) {
+// TODO: Compute length
+bool Thread::WalkStack(uint16_t length,
+ ObjectArray<Method>* method_trace,
+ IntArray* pc_trace) {
Frame frame = Thread::Current()->GetTopOfStack();
- InternalStackTrace *traces = new InternalStackTrace[length];
+
for (uint16_t i = 0; i < length && frame.HasNext(); ++i, frame.Next()) {
- traces[i].method = frame.GetMethod();
- traces[i].pc = frame.GetPC();
+ method_trace->Set(i, (Method*) frame.GetMethod());
+ pc_trace->Set(i, frame.GetPC());
}
- return traces;
+ return true;
}
-ObjectArray<StackTraceElement>* Thread::GetStackTraceElement(uint16_t length, InternalStackTrace *raw_trace) {
+ObjectArray<StackTraceElement>* Thread::AllocStackTrace(uint16_t length) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+
+ ObjectArray<Method>* method_trace = class_linker->AllocObjectArray<Method>(length);
+ IntArray* pc_trace = IntArray::Alloc(length);
+
+ WalkStack(length, method_trace, pc_trace);
+
ObjectArray<StackTraceElement>* java_traces = class_linker->AllocStackTraceElementArray(length);
for (uint16_t i = 0; i < length; ++i) {
// Prepare parameter for StackTraceElement(String cls, String method, String file, int line)
- const Method* method = raw_trace[i].method;
+ const Method* method = method_trace->Get(i);
const Class* klass = method->GetDeclaringClass();
const DexFile& dex_file = class_linker->FindDexFile(klass->GetDexCache());
- String* readable_descriptor = String::AllocFromModifiedUtf8(PrettyDescriptor(klass->GetDescriptor()).c_str());
+ String* readable_descriptor = String::AllocFromModifiedUtf8(
+ PrettyDescriptor(klass->GetDescriptor()).c_str()
+ );
StackTraceElement* obj =
StackTraceElement::Alloc(readable_descriptor,
- method->GetName(), String::AllocFromModifiedUtf8(klass->source_file_),
- dex_file.GetLineNumFromPC(method, method->ToDexPC(raw_trace[i].pc)));
+ method->GetName(),
+ String::AllocFromModifiedUtf8(klass->source_file_),
+ dex_file.GetLineNumFromPC(method,
+ method->ToDexPC(pc_trace->Get(i))));
java_traces->Set(i, obj);
}
return java_traces;
diff --git a/src/thread.h b/src/thread.h
index 8b64249..85abf2f 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -29,6 +29,8 @@
class Throwable;
class StackTraceElement;
template<class T> class ObjectArray;
+template<class T> class PrimitiveArray;
+typedef PrimitiveArray<int32_t> IntArray;
class Mutex {
public:
@@ -398,15 +400,8 @@
class_loader_override_ = class_loader_override;
}
- struct InternalStackTrace {
- const Method* method;
- uintptr_t pc;
- };
-
- // Get the top length frames information
- InternalStackTrace* GetStackTrace(uint16_t length);
-
- ObjectArray<StackTraceElement>* GetStackTraceElement(uint16_t length, InternalStackTrace *raw_trace);
+ // Allocate stack trace
+ ObjectArray<StackTraceElement>* AllocStackTrace(uint16_t length);
private:
Thread()
@@ -427,6 +422,8 @@
void InitCpu();
void InitFunctionPointers();
+ bool WalkStack(uint16_t length, ObjectArray<Method>* method_trace, IntArray* pc_trace);
+
// Managed thread id.
uint32_t id_;