blob: 5f372947e20f3ac7eb35866c550992a33b180fba [file] [log] [blame]
Elliott Hughes68e76522011-10-05 13:22:16 -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_SRC_STACK_INDIRECT_REFERENCE_TABLE_H_
18#define ART_SRC_STACK_INDIRECT_REFERENCE_TABLE_H_
19
Ian Rogers169c9a72011-11-13 20:13:17 -080020#include "logging.h"
Elliott Hughes68e76522011-10-05 13:22:16 -070021#include "macros.h"
Ian Rogers169c9a72011-11-13 20:13:17 -080022#include "thread.h"
23
24namespace art {
Elliott Hughes68e76522011-10-05 13:22:16 -070025
26class Object;
27
Brian Carlstrom40381fb2011-10-19 14:13:40 -070028// Stack allocated indirect reference table. It can allocated within
29// the bridge frame between managed and native code backed by stack
30// storage or manually allocated by SirtRef to hold one reference.
Elliott Hughes68e76522011-10-05 13:22:16 -070031class StackIndirectReferenceTable {
Elliott Hughesff17f1f2012-01-24 18:12:29 -080032 public:
33 explicit StackIndirectReferenceTable(Object* object) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -070034 number_of_references_ = 1;
35 references_[0] = object;
36 Thread::Current()->PushSirt(this);
37 }
38
39 ~StackIndirectReferenceTable() {
40 StackIndirectReferenceTable* sirt = Thread::Current()->PopSirt();
41 CHECK_EQ(this, sirt);
42 }
43
Elliott Hughes68e76522011-10-05 13:22:16 -070044 // Number of references contained within this SIRT
Brian Carlstrom40381fb2011-10-19 14:13:40 -070045 size_t NumberOfReferences() const {
Elliott Hughes68e76522011-10-05 13:22:16 -070046 return number_of_references_;
47 }
48
49 // Link to previous SIRT or NULL
Brian Carlstrom40381fb2011-10-19 14:13:40 -070050 StackIndirectReferenceTable* GetLink() const {
Elliott Hughes68e76522011-10-05 13:22:16 -070051 return link_;
52 }
53
Brian Carlstrom40381fb2011-10-19 14:13:40 -070054 void SetLink(StackIndirectReferenceTable* sirt) {
55 DCHECK_NE(this, sirt);
56 link_ = sirt;
57 }
58
59 Object* GetReference(size_t i) const {
60 DCHECK_LT(i, number_of_references_);
61 return references_[i];
62 }
63
64 void SetReference(size_t i, Object* object) {
65 DCHECK_LT(i, number_of_references_);
66 references_[i] = object;
67 }
68
69 bool Contains(Object** sirt_entry) const {
70 // A SIRT should always contain something. One created by the
71 // jni_compiler should have a jobject/jclass as a native method is
72 // passed in a this pointer or a class
73 DCHECK_GT(number_of_references_, 0U);
74 return ((&references_[0] <= sirt_entry)
75 && (sirt_entry <= (&references_[number_of_references_ - 1])));
Elliott Hughes68e76522011-10-05 13:22:16 -070076 }
77
78 // Offset of length within SIRT, used by generated code
79 static size_t NumberOfReferencesOffset() {
80 return OFFSETOF_MEMBER(StackIndirectReferenceTable, number_of_references_);
81 }
82
83 // Offset of link within SIRT, used by generated code
84 static size_t LinkOffset() {
85 return OFFSETOF_MEMBER(StackIndirectReferenceTable, link_);
86 }
87
Elliott Hughesff17f1f2012-01-24 18:12:29 -080088 private:
Elliott Hughes68e76522011-10-05 13:22:16 -070089 StackIndirectReferenceTable() {}
90
91 size_t number_of_references_;
92 StackIndirectReferenceTable* link_;
93
Brian Carlstrom40381fb2011-10-19 14:13:40 -070094 // number_of_references_ are available if this is allocated and filled in by jni_compiler.
95 Object* references_[1];
Elliott Hughes68e76522011-10-05 13:22:16 -070096
97 DISALLOW_COPY_AND_ASSIGN(StackIndirectReferenceTable);
98};
99
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700100template<class T>
101class SirtRef {
Elliott Hughesff17f1f2012-01-24 18:12:29 -0800102 public:
103 explicit SirtRef(T* object) : sirt_(object) {}
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700104 ~SirtRef() {}
105
106 T& operator*() const { return *get(); }
107 T* operator->() const { return get(); }
108 T* get() const {
109 return down_cast<T*>(sirt_.GetReference(0));
110 }
111
112 void reset(T* object = NULL) {
113 sirt_.SetReference(0, object);
114 }
115
Elliott Hughesff17f1f2012-01-24 18:12:29 -0800116 private:
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700117 StackIndirectReferenceTable sirt_;
118
119 DISALLOW_COPY_AND_ASSIGN(SirtRef);
120};
121
Elliott Hughes68e76522011-10-05 13:22:16 -0700122} // namespace art
123
124#endif // ART_SRC_STACK_INDIRECT_REFERENCE_TABLE_H_