diff options
author | 2012-03-03 22:35:16 -0800 | |
---|---|---|
committer | 2012-03-04 23:04:23 -0800 | |
commit | a8a9c3490776ab897a15bebd31119c94ede5c19a (patch) | |
tree | 71f4bea1ffafb679209f18aee242ca41c3fd7ed2 | |
parent | a33cb99eeb65cb91ba29bfc31d7794b761781e74 (diff) |
Initial runtime support routines for ART LLVM.
Change-Id: Id5bb87685e1a95444bdd7a676f68b378e1b88d3f
-rw-r--r-- | build/Android.common.mk | 3 | ||||
-rw-r--r-- | src/compiler_llvm/runtime_support_llvm.cc | 145 | ||||
-rw-r--r-- | src/compiler_llvm/runtime_support_llvm.h | 20 | ||||
-rw-r--r-- | src/compiler_llvm/utils_llvm.cc | 19 | ||||
-rw-r--r-- | src/runtime_support.cc | 2 | ||||
-rw-r--r-- | src/stack_indirect_reference_table.h | 7 |
6 files changed, 176 insertions, 20 deletions
diff --git a/build/Android.common.mk b/build/Android.common.mk index 73c5a00de8..7680f06853 100644 --- a/build/Android.common.mk +++ b/build/Android.common.mk @@ -200,6 +200,7 @@ LIBART_COMMON_SRC_FILES := \ src/reference_table.cc \ src/reflection.cc \ src/runtime.cc \ + src/runtime_support.cc \ src/signal_catcher.cc \ src/space.cc \ src/stack.cc \ @@ -211,7 +212,6 @@ LIBART_COMMON_SRC_FILES := \ src/thread.cc \ src/thread_list.cc \ src/trace.cc \ - src/runtime_support.cc \ src/utf.cc \ src/utils.cc \ src/zip_archive.cc @@ -227,6 +227,7 @@ LIBART_COMMON_SRC_FILES += \ src/compiler_llvm/ir_builder.cc \ src/compiler_llvm/jni_compiler.cc \ src/compiler_llvm/method_compiler.cc \ + src/compiler_llvm/runtime_support_llvm.cc \ src/compiler_llvm/upcall_compiler.cc \ src/compiler_llvm/utils_llvm.cc else diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc new file mode 100644 index 0000000000..e3a981e355 --- /dev/null +++ b/src/compiler_llvm/runtime_support_llvm.cc @@ -0,0 +1,145 @@ +// Copyright 2012 Google Inc. All Rights Reserved. + +#include "class_linker.h" +#include "dex_verifier.h" +#include "object.h" +#include "object_utils.h" +#include "runtime_support_llvm.h" +#include "thread.h" + +#include <stdint.h> + +namespace art { + +//---------------------------------------------------------------------------- +// Thread +//---------------------------------------------------------------------------- + +void art_push_shadow_frame_from_code(void* new_shadow_frame) { + Thread* thread = Thread::Current(); + thread->PushSirt( + static_cast<StackIndirectReferenceTable*>(new_shadow_frame) + ); +} + +void art_pop_shadow_frame_from_code() { + Thread* thread = Thread::Current(); + thread->PopSirt(); +} + + +//---------------------------------------------------------------------------- +// Exception +//---------------------------------------------------------------------------- + +static std::string MethodNameFromIndex(const Method* method, + uint32_t ref, + verifier::VerifyErrorRefType ref_type, + bool access) { + CHECK_EQ(static_cast<int>(ref_type), + static_cast<int>(verifier::VERIFY_ERROR_REF_METHOD)); + + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + const DexFile& dex_file = + class_linker->FindDexFile(method->GetDeclaringClass()->GetDexCache()); + + const DexFile::MethodId& id = dex_file.GetMethodId(ref); + std::string class_name( + PrettyDescriptor(dex_file.GetMethodDeclaringClassDescriptor(id)) + ); + const char* method_name = dex_file.StringDataByIdx(id.name_idx_); + if (!access) { + return class_name + "." + method_name; + } + + std::string result; + result += "tried to access method "; + result += class_name + "." + method_name + ":" + + dex_file.CreateMethodSignature(id.proto_idx_, NULL); + result += " from class "; + result += PrettyDescriptor(method->GetDeclaringClass()); + return result; +} + +bool art_is_exception_pending_from_code() { + return Thread::Current()->IsExceptionPending(); +} + +void art_throw_div_zero_from_code() { + Thread* thread = Thread::Current(); + thread->ThrowNewException("Ljava/lang/ArithmeticException;", + "divide by zero"); +} + +void art_throw_array_bounds_from_code(int32_t length, int32_t index) { + Thread* thread = Thread::Current(); + thread->ThrowNewExceptionF("Ljava/lang/ArrayIndexOutOfBoundsException;", + "length=%d; index=%d", length, index); +} + +void art_throw_no_such_method_from_code(int32_t method_idx) { + Thread* thread = Thread::Current(); + // We need the calling method as context for the method_idx + Frame frame = thread->GetTopOfStack(); + frame.Next(); + Method* method = frame.GetMethod(); + thread->ThrowNewException("Ljava/lang/NoSuchMethodError;", + MethodNameFromIndex(method, + method_idx, + verifier::VERIFY_ERROR_REF_METHOD, + false).c_str()); +} + +void art_throw_null_pointer_exception_from_code() { + Thread* thread = Thread::Current(); + thread->ThrowNewException("Ljava/lang/NullPointerException;", NULL); +} + +void art_throw_stack_overflow_from_code(void*) { + Thread* thread = Thread::Current(); + thread->ThrowNewExceptionF("Ljava/lang/StackOverflowError;", + "stack size %zdkb; default stack size: %zdkb", + thread->GetStackSize() / KB, + Runtime::Current()->GetDefaultStackSize() / KB); +} + +void art_throw_exception_from_code(Object* exception) { + Thread* thread = Thread::Current(); + thread->SetException(static_cast<Throwable*>(exception)); +} + +int32_t art_find_catch_block_from_code(Object* exception, int32_t dex_pc) { + Class* exception_type = exception->GetClass(); + Method* current_method = Thread::Current()->GetCurrentMethod(); + MethodHelper mh(current_method); + const DexFile::CodeItem* code_item = mh.GetCodeItem(); + int iter_index = 0; + // Iterate over the catch handlers associated with dex_pc + for (CatchHandlerIterator it(*code_item, dex_pc); it.HasNext(); it.Next()) { + uint16_t iter_type_idx = it.GetHandlerTypeIndex(); + // Catch all case + if (iter_type_idx == DexFile::kDexNoIndex16) { + return iter_index; + } + // Does this catch exception type apply? + Class* iter_exception_type = mh.GetDexCacheResolvedType(iter_type_idx); + if (iter_exception_type == NULL) { + // The verifier should take care of resolving all exception classes early + LOG(WARNING) << "Unresolved exception class when finding catch block: " + << mh.GetTypeDescriptorFromTypeIdx(iter_type_idx); + } else if (iter_exception_type->IsAssignableFrom(exception_type)) { + return iter_index; + } + ++iter_index; + } + // Handler not found + return -1; +} + +void art_test_suspend_from_code() { +} + +void art_set_current_thread_from_code(void* thread_object_addr) { +} + +} // namespace art diff --git a/src/compiler_llvm/runtime_support_llvm.h b/src/compiler_llvm/runtime_support_llvm.h new file mode 100644 index 0000000000..548222a9a5 --- /dev/null +++ b/src/compiler_llvm/runtime_support_llvm.h @@ -0,0 +1,20 @@ +// Copyright 2012 Google Inc. All Rights Reserved. + +#ifndef ART_SRC_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_H_ +#define ART_SRC_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_H_ + +namespace art { + +void art_push_shadow_frame_from_code(void* new_shadow_frame); + +void art_pop_shadow_frame_from_code(); + +bool art_is_exception_pending_from_code(); + +void art_test_suspend_from_code(); + +void art_set_current_thread_from_code(void* thread_object_addr); + +} // namespace art + +#endif // ART_SRC_COMPILER_LLVM_RUNTIME_SUPPORT_LLVM_H_ diff --git a/src/compiler_llvm/utils_llvm.cc b/src/compiler_llvm/utils_llvm.cc index 405d7e20ad..93fad37557 100644 --- a/src/compiler_llvm/utils_llvm.cc +++ b/src/compiler_llvm/utils_llvm.cc @@ -26,6 +26,8 @@ #include "object.h" #include "object_utils.h" +#include "runtime_support_llvm.h" + namespace art { std::string MangleForLLVM(const std::string& s) { @@ -105,23 +107,6 @@ std::string LLVMStubName(const Method* m) { return stub_name; } -// TODO: Remove these when art_llvm.ll runtime support is ready. -void art_push_shadow_frame_from_code(void* frame) { -} - -void art_pop_shadow_frame_from_code() { -} - -int art_is_exception_pending_from_code() { - return 0; -} - -void art_test_suspend_from_code() { -} - -void art_set_current_thread_from_code(void* thread_object_addr) { -} - // Linker's call back function. Added some for debugging. void* find_sym(void* context, char const* name) { struct func_entry_t { diff --git a/src/runtime_support.cc b/src/runtime_support.cc index de07c0c3bb..607542e816 100644 --- a/src/runtime_support.cc +++ b/src/runtime_support.cc @@ -323,7 +323,7 @@ static std::string FieldNameFromIndex(const Method* method, uint32_t ref, } static std::string MethodNameFromIndex(const Method* method, uint32_t ref, - verifier::VerifyErrorRefType ref_type, bool access) { + verifier::VerifyErrorRefType ref_type, bool access) { CHECK_EQ(static_cast<int>(ref_type), static_cast<int>(verifier::VERIFY_ERROR_REF_METHOD)); ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); diff --git a/src/stack_indirect_reference_table.h b/src/stack_indirect_reference_table.h index 5f372947e2..77cbddc718 100644 --- a/src/stack_indirect_reference_table.h +++ b/src/stack_indirect_reference_table.h @@ -88,8 +88,13 @@ class StackIndirectReferenceTable { private: StackIndirectReferenceTable() {} - size_t number_of_references_; StackIndirectReferenceTable* link_; +#if defined(ART_USE_LLVM_COMPILER) + Object* method_; + uint32_t line_num_; +#endif + + size_t number_of_references_; // number_of_references_ are available if this is allocated and filled in by jni_compiler. Object* references_[1]; |