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, int position, int size>
30 class BitField {
31  public:
32   // Tells whether the provided value fits into the bit field.
IsValid(T value)33   static bool IsValid(T value) {
34     return (static_cast<uintptr_t>(value) & ~((kUintPtrTOne << size) - 1)) == 0;
35   }
36 
37   // Returns a uword mask of the bit field.
Mask()38   static uintptr_t Mask() {
39     return (kUintPtrTOne << size) - 1;
40   }
41 
42   // Returns a uword mask of the bit field which can be applied directly to
43   // the raw unshifted bits.
MaskInPlace()44   static uintptr_t MaskInPlace() {
45     return ((kUintPtrTOne << size) - 1) << position;
46   }
47 
48   // Returns the shift count needed to right-shift the bit field to
49   // the least-significant bits.
Shift()50   static int Shift() {
51     return position;
52   }
53 
54   // Returns the size of the bit field.
BitSize()55   static int BitSize() {
56     return size;
57   }
58 
59   // Returns a uword with the bit field value encoded.
Encode(T value)60   static uintptr_t Encode(T value) {
61     DCHECK(IsValid(value));
62     return static_cast<uintptr_t>(value) << position;
63   }
64 
65   // Extracts the bit field from the value.
Decode(uintptr_t value)66   static T Decode(uintptr_t value) {
67     return static_cast<T>((value >> position) & ((kUintPtrTOne << size) - 1));
68   }
69 
70   // Returns a uword with the bit field value encoded based on the
71   // original value. Only the bits corresponding to this bit field
72   // will be changed.
Update(T value,uintptr_t original)73   static uintptr_t Update(T value, uintptr_t original) {
74     DCHECK(IsValid(value));
75     return (static_cast<uintptr_t>(value) << position) |
76         (~MaskInPlace() & original);
77   }
78 };
79 
80 }  // namespace art
81 
82 #endif  // ART_RUNTIME_BASE_BIT_FIELD_H_
83