blob: 681405f0818552afd0bd3dc96cc583bd0d029da9 [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
Elliott Hughes0f3c5532012-03-30 14:51:51 -070020#include "casts.h"
Ian Rogers169c9a72011-11-13 20:13:17 -080021#include "logging.h"
Elliott Hughes68e76522011-10-05 13:22:16 -070022#include "macros.h"
Ian Rogers169c9a72011-11-13 20:13:17 -080023#include "thread.h"
24
25namespace art {
Elliott Hughes68e76522011-10-05 13:22:16 -070026
27class Object;
28
Brian Carlstrom40381fb2011-10-19 14:13:40 -070029// Stack allocated indirect reference table. It can allocated within
30// the bridge frame between managed and native code backed by stack
31// storage or manually allocated by SirtRef to hold one reference.
Elliott Hughes68e76522011-10-05 13:22:16 -070032class StackIndirectReferenceTable {
Elliott Hughesff17f1f2012-01-24 18:12:29 -080033 public:
34 explicit StackIndirectReferenceTable(Object* object) {
Brian Carlstrom40381fb2011-10-19 14:13:40 -070035 number_of_references_ = 1;
36 references_[0] = object;
37 Thread::Current()->PushSirt(this);
38 }
39
40 ~StackIndirectReferenceTable() {
41 StackIndirectReferenceTable* sirt = Thread::Current()->PopSirt();
42 CHECK_EQ(this, sirt);
43 }
44
Elliott Hughes68e76522011-10-05 13:22:16 -070045 // Number of references contained within this SIRT
Brian Carlstrom40381fb2011-10-19 14:13:40 -070046 size_t NumberOfReferences() const {
Elliott Hughes68e76522011-10-05 13:22:16 -070047 return number_of_references_;
48 }
49
50 // Link to previous SIRT or NULL
Brian Carlstrom40381fb2011-10-19 14:13:40 -070051 StackIndirectReferenceTable* GetLink() const {
Elliott Hughes68e76522011-10-05 13:22:16 -070052 return link_;
53 }
54
Brian Carlstrom40381fb2011-10-19 14:13:40 -070055 void SetLink(StackIndirectReferenceTable* sirt) {
56 DCHECK_NE(this, sirt);
57 link_ = sirt;
58 }
59
60 Object* GetReference(size_t i) const {
61 DCHECK_LT(i, number_of_references_);
62 return references_[i];
63 }
64
65 void SetReference(size_t i, Object* object) {
66 DCHECK_LT(i, number_of_references_);
67 references_[i] = object;
68 }
69
70 bool Contains(Object** sirt_entry) const {
71 // A SIRT should always contain something. One created by the
72 // jni_compiler should have a jobject/jclass as a native method is
73 // passed in a this pointer or a class
74 DCHECK_GT(number_of_references_, 0U);
75 return ((&references_[0] <= sirt_entry)
76 && (sirt_entry <= (&references_[number_of_references_ - 1])));
Elliott Hughes68e76522011-10-05 13:22:16 -070077 }
78
79 // Offset of length within SIRT, used by generated code
80 static size_t NumberOfReferencesOffset() {
81 return OFFSETOF_MEMBER(StackIndirectReferenceTable, number_of_references_);
82 }
83
84 // Offset of link within SIRT, used by generated code
85 static size_t LinkOffset() {
86 return OFFSETOF_MEMBER(StackIndirectReferenceTable, link_);
87 }
88
Elliott Hughesff17f1f2012-01-24 18:12:29 -080089 private:
Elliott Hughes68e76522011-10-05 13:22:16 -070090 StackIndirectReferenceTable() {}
91
Shih-wei Liao3ad8b9d2012-03-04 23:41:35 -080092 size_t number_of_references_;
Elliott Hughes68e76522011-10-05 13:22:16 -070093 StackIndirectReferenceTable* link_;
Shih-wei Liaoa8a9c342012-03-03 22:35:16 -080094
Brian Carlstrom40381fb2011-10-19 14:13:40 -070095 // number_of_references_ are available if this is allocated and filled in by jni_compiler.
96 Object* references_[1];
Elliott Hughes68e76522011-10-05 13:22:16 -070097
98 DISALLOW_COPY_AND_ASSIGN(StackIndirectReferenceTable);
99};
100
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700101template<class T>
102class SirtRef {
Elliott Hughesff17f1f2012-01-24 18:12:29 -0800103 public:
104 explicit SirtRef(T* object) : sirt_(object) {}
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700105 ~SirtRef() {}
106
107 T& operator*() const { return *get(); }
108 T* operator->() const { return get(); }
109 T* get() const {
110 return down_cast<T*>(sirt_.GetReference(0));
111 }
112
113 void reset(T* object = NULL) {
114 sirt_.SetReference(0, object);
115 }
116
Elliott Hughesff17f1f2012-01-24 18:12:29 -0800117 private:
Brian Carlstrom40381fb2011-10-19 14:13:40 -0700118 StackIndirectReferenceTable sirt_;
119
120 DISALLOW_COPY_AND_ASSIGN(SirtRef);
121};
122
Elliott Hughes68e76522011-10-05 13:22:16 -0700123} // namespace art
124
125#endif // ART_SRC_STACK_INDIRECT_REFERENCE_TABLE_H_