1 /* 2 * Copyright (C) 2014 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_RUNTIME_BASE_BIT_FIELD_H_ 18 #define ART_RUNTIME_BASE_BIT_FIELD_H_ 19 20 #include "globals.h" 21 #include "logging.h" 22 23 namespace art { 24 25 static constexpr uintptr_t kUintPtrTOne = 1U; 26 27 // BitField is a template for encoding and decoding a bit field inside 28 // an unsigned machine word. 29 template<typename T, size_t kPosition, size_t kSize> 30 class BitField { 31 public: 32 typedef T value_type; 33 static constexpr size_t position = kPosition; 34 static constexpr size_t size = kSize; 35 36 static_assert(position < sizeof(uintptr_t) * kBitsPerByte, "Invalid position."); 37 static_assert(size != 0u, "Invalid size."); 38 static_assert(size <= sizeof(uintptr_t) * kBitsPerByte, "Invalid size."); 39 static_assert(size + position <= sizeof(uintptr_t) * kBitsPerByte, "Invalid position + size."); 40 41 // Tells whether the provided value fits into the bit field. IsValid(T value)42 static bool IsValid(T value) { 43 return (static_cast<uintptr_t>(value) & ~((kUintPtrTOne << size) - 1)) == 0; 44 } 45 46 // Returns a uword mask of the bit field. Mask()47 static uintptr_t Mask() { 48 return (kUintPtrTOne << size) - 1; 49 } 50 51 // Returns a uword mask of the bit field which can be applied directly to 52 // the raw unshifted bits. MaskInPlace()53 static uintptr_t MaskInPlace() { 54 return ((kUintPtrTOne << size) - 1) << position; 55 } 56 57 // Returns the shift count needed to right-shift the bit field to 58 // the least-significant bits. Shift()59 static int Shift() { 60 return position; 61 } 62 63 // Returns the size of the bit field. BitSize()64 static int BitSize() { 65 return size; 66 } 67 68 // Returns a uword with the bit field value encoded. Encode(T value)69 static uintptr_t Encode(T value) { 70 DCHECK(IsValid(value)); 71 return static_cast<uintptr_t>(value) << position; 72 } 73 74 // Extracts the bit field from the value. Decode(uintptr_t value)75 static T Decode(uintptr_t value) { 76 return static_cast<T>((value >> position) & ((kUintPtrTOne << size) - 1)); 77 } 78 79 // Returns a uword with the bit field value encoded based on the 80 // original value. Only the bits corresponding to this bit field 81 // will be changed. Update(T value,uintptr_t original)82 static uintptr_t Update(T value, uintptr_t original) { 83 DCHECK(IsValid(value)); 84 return (static_cast<uintptr_t>(value) << position) | 85 (~MaskInPlace() & original); 86 } 87 }; 88 89 } // namespace art 90 91 #endif // ART_RUNTIME_BASE_BIT_FIELD_H_ 92