1/*
2 * Copyright (C) 2008 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 * Maintain a table of references.  Used for internal local references,
18 * JNI locals, JNI globals, and GC heap references.
19 *
20 * None of the table functions are synchronized.
21 */
22#ifndef _DALVIK_REFERENCETABLE
23#define _DALVIK_REFERENCETABLE
24
25/*
26 * Table definition.
27 *
28 * The expected common operations are adding a new entry and removing a
29 * recently-added entry (usually the most-recently-added entry).
30 *
31 * If "allocEntries" is not equal to "maxEntries", the table may expand when
32 * entries are added, which means the memory may move.  If you want to keep
33 * pointers into "table" rather than offsets, use a fixed-size table.
34 *
35 * (This structure is still somewhat transparent; direct access to
36 * table/nextEntry is allowed.)
37 */
38typedef struct ReferenceTable {
39    Object**        table;              /* top of the list */
40    Object**        nextEntry;          /* bottom of the list */
41
42    int             allocEntries;       /* #of entries we have space for */
43    int             maxEntries;         /* max #of entries allowed */
44} ReferenceTable;
45
46/*
47 * Initialize a ReferenceTable.
48 *
49 * If "initialCount" != "maxCount", the table will expand as required.
50 *
51 * Returns "false" if table allocation fails.
52 */
53bool dvmInitReferenceTable(ReferenceTable* pRef, int initialCount,
54    int maxCount);
55
56/*
57 * Clears out the contents of a ReferenceTable, freeing allocated storage.
58 * Does not free "pRef".
59 *
60 * You must call dvmInitReferenceTable() before you can re-use this table.
61 */
62void dvmClearReferenceTable(ReferenceTable* pRef);
63
64/*
65 * Return the #of entries currently stored in the ReferenceTable.
66 */
67INLINE size_t dvmReferenceTableEntries(const ReferenceTable* pRef)
68{
69    return pRef->nextEntry - pRef->table;
70}
71
72/*
73 * Returns "true" if the table is full.  The table is considered full if
74 * we would need to expand it to add another entry.
75 */
76INLINE size_t dvmIsReferenceTableFull(const ReferenceTable* pRef)
77{
78    return dvmReferenceTableEntries(pRef) == (size_t)pRef->allocEntries;
79}
80
81/*
82 * Add a new entry.  "obj" must be a valid non-NULL object reference
83 * (though it's okay if it's not fully-formed, e.g. the result from
84 * dvmMalloc doesn't have obj->clazz set).
85 *
86 * Returns "false" if the table is full.
87 */
88bool dvmAddToReferenceTable(ReferenceTable* pRef, Object* obj);
89
90/*
91 * Determine if "obj" is present in "pRef".  Stops searching when we hit "top".
92 * To include the entire table, pass in "pRef->table" as the top.
93 *
94 * Returns NULL if "obj" was not found.
95 */
96Object** dvmFindInReferenceTable(const ReferenceTable* pRef, Object** top,
97    Object* obj);
98
99/*
100 * Remove an existing entry.
101 *
102 * We stop searching for a match after examining the element at "top".  This
103 * is useful when entries are associated with a stack frame.
104 *
105 * Returns "false" if the entry was not found.
106 */
107bool dvmRemoveFromReferenceTable(ReferenceTable* pRef, Object** top,
108    Object* obj);
109
110/*
111 * Dump the contents of a reference table to the log file.
112 */
113void dvmDumpReferenceTable(const ReferenceTable* pRef, const char* descr);
114
115#endif /*_DALVIK_REFERENCETABLE*/
116