diff options
Diffstat (limited to 'runtime/gc_map.h')
-rw-r--r-- | runtime/gc_map.h | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/runtime/gc_map.h b/runtime/gc_map.h new file mode 100644 index 0000000..473b39a --- /dev/null +++ b/runtime/gc_map.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2012 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. + */ + +#ifndef ART_SRC_GC_MAP_H_ +#define ART_SRC_GC_MAP_H_ + +#include <stdint.h> + +#include "base/logging.h" +#include "base/macros.h" + +namespace art { + +// Lightweight wrapper for native PC offset to reference bit maps. +class NativePcOffsetToReferenceMap { + public: + NativePcOffsetToReferenceMap(const uint8_t* data) : data_(data) { + CHECK(data_ != NULL); + } + + // The number of entries in the table. + size_t NumEntries() const { + return data_[2] | (data_[3] << 8); + } + + // Return address of bitmap encoding what are live references. + const uint8_t* GetBitMap(size_t index) const { + size_t entry_offset = index * EntryWidth(); + return &Table()[entry_offset + NativeOffsetWidth()]; + } + + // Get the native PC encoded in the table at the given index. + uintptr_t GetNativePcOffset(size_t index) const { + size_t entry_offset = index * EntryWidth(); + uintptr_t result = 0; + for (size_t i = 0; i < NativeOffsetWidth(); ++i) { + result |= Table()[entry_offset + i] << (i * 8); + } + return result; + } + + // Does the given offset have an entry? + bool HasEntry(uintptr_t native_pc_offset) { + for (size_t i = 0; i < NumEntries(); ++i) { + if (GetNativePcOffset(i) == native_pc_offset) { + return true; + } + } + return false; + } + + // Finds the bitmap associated with the native pc offset. + const uint8_t* FindBitMap(uintptr_t native_pc_offset) { + size_t num_entries = NumEntries(); + size_t index = Hash(native_pc_offset) % num_entries; + size_t misses = 0; + while (GetNativePcOffset(index) != native_pc_offset) { + index = (index + 1) % num_entries; + misses++; + DCHECK_LT(misses, num_entries) << "Failed to find offset: " << native_pc_offset; + } + return GetBitMap(index); + } + + static uint32_t Hash(uint32_t native_offset) { + uint32_t hash = native_offset; + hash ^= (hash >> 20) ^ (hash >> 12); + hash ^= (hash >> 7) ^ (hash >> 4); + return hash; + } + + // The number of bytes used to encode registers. + size_t RegWidth() const { + return (static_cast<size_t>(data_[0]) | (static_cast<size_t>(data_[1]) << 8)) >> 3; + } + + private: + // Skip the size information at the beginning of data. + const uint8_t* Table() const { + return data_ + 4; + } + + // Number of bytes used to encode a native offset. + size_t NativeOffsetWidth() const { + return data_[0] & 7; + } + + // The width of an entry in the table. + size_t EntryWidth() const { + return NativeOffsetWidth() + RegWidth(); + } + + const uint8_t* const data_; // The header and table data +}; + +} // namespace art + +#endif // ART_SRC_GC_MAP_H_ |