diff options
author | 2012-03-15 03:10:03 +0800 | |
---|---|---|
committer | 2012-03-26 20:49:44 -0700 | |
commit | f7ad17e108b9357d7c94c6218a8521140a667f3d (patch) | |
tree | 79ab38c8ff414cd3ccd81782b14de88406f761be | |
parent | eeb7edf786abf6dbcfc37964af8854caafda6b0b (diff) |
Split shadow stack from SIRT.
(cherry picked from commit 4455f868a9a6553827ccbe1d25e29cf528a74422)
Change-Id: I4f467cf5be812c600dc5fdb56a9236fe144bd380
-rw-r--r-- | src/asm_support.h | 2 | ||||
-rw-r--r-- | src/compiler_llvm/runtime_support_llvm.cc | 7 | ||||
-rw-r--r-- | src/shadow_frame.h | 70 | ||||
-rw-r--r-- | src/stack_indirect_reference_table.h | 4 | ||||
-rw-r--r-- | src/thread.cc | 27 | ||||
-rw-r--r-- | src/thread.h | 10 |
6 files changed, 111 insertions, 9 deletions
diff --git a/src/asm_support.h b/src/asm_support.h index d5bc370104..d9e57d17bf 100644 --- a/src/asm_support.h +++ b/src/asm_support.h @@ -35,7 +35,7 @@ #elif defined(__i386__) // Offset of field Thread::self_ verified in InitCpu -#define THREAD_SELF_OFFSET 108 +#define THREAD_SELF_OFFSET 112 #endif #endif // ART_SRC_ASM_SUPPORT_H_ diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc index 54c6cbe684..b6ca288e70 100644 --- a/src/compiler_llvm/runtime_support_llvm.cc +++ b/src/compiler_llvm/runtime_support_llvm.cc @@ -6,6 +6,7 @@ #include "object_utils.h" #include "runtime_support_common.h" #include "runtime_support_llvm.h" +#include "shadow_frame.h" #include "thread.h" #include "thread_list.h" @@ -49,14 +50,12 @@ void art_test_suspend_from_code() { void art_push_shadow_frame_from_code(void* new_shadow_frame) { Thread* thread = Thread::Current(); - thread->PushSirt( - static_cast<StackIndirectReferenceTable*>(new_shadow_frame) - ); + thread->PushShadowFrame(static_cast<ShadowFrame*>(new_shadow_frame)); } void art_pop_shadow_frame_from_code() { Thread* thread = Thread::Current(); - thread->PopSirt(); + thread->PopShadowFrame(); } diff --git a/src/shadow_frame.h b/src/shadow_frame.h new file mode 100644 index 0000000000..533d92493c --- /dev/null +++ b/src/shadow_frame.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2012 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_SRC_SHADOW_FRAME_H_ +#define ART_SRC_SHADOW_FRAME_H_ + +#include "logging.h" +#include "macros.h" + +namespace art { + +class Object; + +class ShadowFrame { + public: + // Number of references contained within this shadow frame + uint32_t NumberOfReferences() const { + return number_of_references_; + } + + // Link to previous shadow frame or NULL + ShadowFrame* GetLink() const { + return link_; + } + + void SetLink(ShadowFrame* frame) { + DCHECK_NE(this, frame); + link_ = frame; + } + + Object* GetReference(size_t i) const { + DCHECK_LT(i, number_of_references_); + return references_[i]; + } + + void SetReference(size_t i, Object* object) { + DCHECK_LT(i, number_of_references_); + references_[i] = object; + } + + private: + // ShadowFrame should be allocated by the generated code directly. + // We should not create new shadow stack in the runtime support function. + ~ShadowFrame() {} + + uint32_t number_of_references_; + ShadowFrame* link_; + Object* method_; + uint32_t line_num_; + Object* references_[]; + + DISALLOW_IMPLICIT_CONSTRUCTORS(ShadowFrame); +}; + +} // namespace art + +#endif // ART_SRC_SHADOW_FRAME_H_ diff --git a/src/stack_indirect_reference_table.h b/src/stack_indirect_reference_table.h index 5c6bc0a734..5f372947e2 100644 --- a/src/stack_indirect_reference_table.h +++ b/src/stack_indirect_reference_table.h @@ -90,10 +90,6 @@ class StackIndirectReferenceTable { size_t number_of_references_; StackIndirectReferenceTable* link_; -#if defined(ART_USE_LLVM_COMPILER) - Object* method_; - uint32_t line_num_; -#endif // number_of_references_ are available if this is allocated and filled in by jni_compiler. Object* references_[1]; diff --git a/src/thread.cc b/src/thread.cc index 1b5dea04ec..f3e1092726 100644 --- a/src/thread.cc +++ b/src/thread.cc @@ -43,6 +43,7 @@ #include "runtime_support.h" #include "ScopedLocalRef.h" #include "scoped_jni_thread_state.h" +#include "shadow_frame.h" #include "space.h" #include "stack.h" #include "stack_indirect_reference_table.h" @@ -954,6 +955,7 @@ Thread::Thread() stack_end_(NULL), native_to_managed_record_(NULL), top_sirt_(NULL), + top_shadow_frame_(NULL), jni_env_(NULL), state_(Thread::kNative), self_(NULL), @@ -1092,6 +1094,18 @@ void Thread::SirtVisitRoots(Heap::RootVisitor* visitor, void* arg) { } } +void Thread::ShadowFrameVisitRoots(Heap::RootVisitor* visitor, void* arg) { + for (ShadowFrame* cur = top_shadow_frame_; cur; cur = cur->GetLink()) { + size_t num_refs = cur->NumberOfReferences(); + for (size_t j = 0; j < num_refs; j++) { + Object* object = cur->GetReference(j); + if (object != NULL) { + visitor(object, arg); + } + } + } +} + Object* Thread::DecodeJObject(jobject obj) { DCHECK(CanAccessDirectReferences()); if (obj == NULL) { @@ -1270,6 +1284,18 @@ uintptr_t DemanglePc(uintptr_t pc) { return pc; } +void Thread::PushShadowFrame(ShadowFrame* frame) { + frame->SetLink(top_shadow_frame_); + top_shadow_frame_ = frame; +} + +ShadowFrame* Thread::PopShadowFrame() { + CHECK(top_shadow_frame_ != NULL); + ShadowFrame* frame = top_shadow_frame_; + top_shadow_frame_ = frame->GetLink(); + return frame; +} + void Thread::PushSirt(StackIndirectReferenceTable* sirt) { sirt->SetLink(top_sirt_); top_sirt_ = sirt; @@ -1754,6 +1780,7 @@ void Thread::VisitRoots(Heap::RootVisitor* visitor, void* arg) { jni_env_->monitors.VisitRoots(visitor, arg); SirtVisitRoots(visitor, arg); + ShadowFrameVisitRoots(visitor, arg); // Cheat and steal the long jump context. Assume that we are not doing a GC during exception // delivery. diff --git a/src/thread.h b/src/thread.h index 8a0c1affe4..6f91b31980 100644 --- a/src/thread.h +++ b/src/thread.h @@ -50,6 +50,7 @@ class Method; class Monitor; class Object; class Runtime; +class ShadowFrame; class StackIndirectReferenceTable; class StackTraceElement; class StaticStorageBase; @@ -272,6 +273,8 @@ class PACKED Thread { void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg); + void ShadowFrameVisitRoots(Heap::RootVisitor* visitor, void* arg); + // Convert a jobject into a Object* Object* DecodeJObject(jobject obj); @@ -405,6 +408,9 @@ class PACKED Thread { return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_pc_)); } + void PushShadowFrame(ShadowFrame* frame); + ShadowFrame* PopShadowFrame(); + void PushSirt(StackIndirectReferenceTable* sirt); StackIndirectReferenceTable* PopSirt(); @@ -539,6 +545,10 @@ class PACKED Thread { // Top of linked list of stack indirect reference tables or NULL for none StackIndirectReferenceTable* top_sirt_; + // Top of linked list of shadow stack or NULL for none + // Some backend may require shadow frame to ease the GC work. + ShadowFrame* top_shadow_frame_; + // Every thread may have an associated JNI environment JNIEnvExt* jni_env_; |