/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Maintain a table of references. Used for internal local references, * JNI locals, JNI globals, and GC heap references. * * None of the table functions are synchronized. */ #ifndef _DALVIK_REFERENCETABLE #define _DALVIK_REFERENCETABLE /* * Table definition. * * The expected common operations are adding a new entry and removing a * recently-added entry (usually the most-recently-added entry). * * If "allocEntries" is not equal to "maxEntries", the table may expand when * entries are added, which means the memory may move. If you want to keep * pointers into "table" rather than offsets, use a fixed-size table. * * (This structure is still somewhat transparent; direct access to * table/nextEntry is allowed.) */ typedef struct ReferenceTable { Object** nextEntry; /* top of the list */ Object** table; /* bottom of the list */ int allocEntries; /* #of entries we have space for */ int maxEntries; /* max #of entries allowed */ } ReferenceTable; /* * Initialize a ReferenceTable. * * If "initialCount" != "maxCount", the table will expand as required. * * Returns "false" if table allocation fails. */ bool dvmInitReferenceTable(ReferenceTable* pRef, int initialCount, int maxCount); /* * Clears out the contents of a ReferenceTable, freeing allocated storage. * Does not free "pRef". * * You must call dvmInitReferenceTable() before you can re-use this table. */ void dvmClearReferenceTable(ReferenceTable* pRef); /* * Return the #of entries currently stored in the ReferenceTable. */ INLINE size_t dvmReferenceTableEntries(const ReferenceTable* pRef) { return pRef->nextEntry - pRef->table; } /* * Returns "true" if the table is full. The table is considered full if * we would need to expand it to add another entry. */ INLINE size_t dvmIsReferenceTableFull(const ReferenceTable* pRef) { return dvmReferenceTableEntries(pRef) == (size_t)pRef->allocEntries; } /* * Add a new entry. "obj" must be a valid non-NULL object reference * (though it's okay if it's not fully-formed, e.g. the result from * dvmMalloc doesn't have obj->clazz set). * * Returns "false" if the table is full. */ bool dvmAddToReferenceTable(ReferenceTable* pRef, Object* obj); /* * Determine if "obj" is present in "pRef". Stops searching when we hit * "bottom". To include the entire table, pass in "pRef->table" as the * bottom. * * Returns NULL if "obj" was not found. */ Object** dvmFindInReferenceTable(const ReferenceTable* pRef, Object** bottom, Object* obj); /* * Remove an existing entry. * * We stop searching for a match after examining the element at "bottom". * This is useful when entries are associated with a stack frame. * * Returns "false" if the entry was not found. */ bool dvmRemoveFromReferenceTable(ReferenceTable* pRef, Object** bottom, Object* obj); /* * Dump the contents of a reference table to the log file. */ void dvmDumpReferenceTable(const ReferenceTable* pRef, const char* descr); #endif /*_DALVIK_REFERENCETABLE*/