blob: 8337f968ace55603281b34647583ee522d64c758 [file] [log] [blame]
Andreas Gampe513061a2017-06-01 09:17:34 -07001/*
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
28namespace art {
29
30namespace mirror {
31class Object;
32} // namespace mirror
33
34class ArtMethod;
35class ShadowFrame;
36template <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.
42class PACKED(4) ManagedStack {
43 public:
44 ManagedStack()
45 : top_quick_frame_(nullptr), link_(nullptr), top_shadow_frame_(nullptr) {}
46
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
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
62 ManagedStack* GetLink() const {
63 return link_;
64 }
65
66 ArtMethod** GetTopQuickFrame() const {
67 return top_quick_frame_;
68 }
69
70 void SetTopQuickFrame(ArtMethod** top) {
71 DCHECK(top_shadow_frame_ == nullptr);
72 top_quick_frame_ = top;
73 }
74
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
82 ShadowFrame* GetTopShadowFrame() const {
83 return top_shadow_frame_;
84 }
85
86 void SetTopShadowFrame(ShadowFrame* top) {
87 DCHECK(top_quick_frame_ == nullptr);
88 top_shadow_frame_ = top;
89 }
90
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_