1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ART_RUNTIME_MANAGED_STACK_H_ 18 #define ART_RUNTIME_MANAGED_STACK_H_ 19 20 #include <cstring> 21 #include <stdint.h> 22 #include <string> 23 24 #include "base/logging.h" 25 #include "base/macros.h" 26 #include "base/mutex.h" 27 28 namespace art { 29 30 namespace mirror { 31 class Object; 32 } // namespace mirror 33 34 class ArtMethod; 35 class ShadowFrame; 36 template <typename T> class StackReference; 37 38 // The managed stack is used to record fragments of managed code stacks. Managed code stacks 39 // may either be shadow frames or lists of frames using fixed frame sizes. Transition records are 40 // necessary for transitions between code using different frame layouts and transitions into native 41 // code. 42 class PACKED(4) ManagedStack { 43 public: ManagedStack()44 ManagedStack() 45 : top_quick_frame_(nullptr), link_(nullptr), top_shadow_frame_(nullptr) {} 46 PushManagedStackFragment(ManagedStack * fragment)47 void PushManagedStackFragment(ManagedStack* fragment) { 48 // Copy this top fragment into given fragment. 49 memcpy(fragment, this, sizeof(ManagedStack)); 50 // Clear this fragment, which has become the top. 51 memset(this, 0, sizeof(ManagedStack)); 52 // Link our top fragment onto the given fragment. 53 link_ = fragment; 54 } 55 PopManagedStackFragment(const ManagedStack & fragment)56 void PopManagedStackFragment(const ManagedStack& fragment) { 57 DCHECK(&fragment == link_); 58 // Copy this given fragment back to the top. 59 memcpy(this, &fragment, sizeof(ManagedStack)); 60 } 61 GetLink()62 ManagedStack* GetLink() const { 63 return link_; 64 } 65 GetTopQuickFrame()66 ArtMethod** GetTopQuickFrame() const { 67 return top_quick_frame_; 68 } 69 SetTopQuickFrame(ArtMethod ** top)70 void SetTopQuickFrame(ArtMethod** top) { 71 DCHECK(top_shadow_frame_ == nullptr); 72 top_quick_frame_ = top; 73 } 74 TopQuickFrameOffset()75 static size_t TopQuickFrameOffset() { 76 return OFFSETOF_MEMBER(ManagedStack, top_quick_frame_); 77 } 78 79 ALWAYS_INLINE ShadowFrame* PushShadowFrame(ShadowFrame* new_top_frame); 80 ALWAYS_INLINE ShadowFrame* PopShadowFrame(); 81 GetTopShadowFrame()82 ShadowFrame* GetTopShadowFrame() const { 83 return top_shadow_frame_; 84 } 85 SetTopShadowFrame(ShadowFrame * top)86 void SetTopShadowFrame(ShadowFrame* top) { 87 DCHECK(top_quick_frame_ == nullptr); 88 top_shadow_frame_ = top; 89 } 90 TopShadowFrameOffset()91 static size_t TopShadowFrameOffset() { 92 return OFFSETOF_MEMBER(ManagedStack, top_shadow_frame_); 93 } 94 95 size_t NumJniShadowFrameReferences() const REQUIRES_SHARED(Locks::mutator_lock_); 96 97 bool ShadowFramesContain(StackReference<mirror::Object>* shadow_frame_entry) const; 98 99 private: 100 ArtMethod** top_quick_frame_; 101 ManagedStack* link_; 102 ShadowFrame* top_shadow_frame_; 103 }; 104 105 } // namespace art 106 107 #endif // ART_RUNTIME_MANAGED_STACK_H_ 108