summaryrefslogtreecommitdiffstats
path: root/runtime/gc
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2015-04-16 11:50:30 -0700
committerDan Albert <danalbert@google.com>2015-04-28 11:10:23 -0700
commite48b29b2b99a6b4eceacdbdd60838ad7e789be79 (patch)
treeaa4e00bace4103991707e42c6240b62d9ada68ae /runtime/gc
parent97c96f5aab22f75dd54089bdc194588a4b5a2e8d (diff)
downloadart-e48b29b2b99a6b4eceacdbdd60838ad7e789be79.zip
art-e48b29b2b99a6b4eceacdbdd60838ad7e789be79.tar.gz
art-e48b29b2b99a6b4eceacdbdd60838ad7e789be79.tar.bz2
Prevent undefined behavior in RosAlloc.
In cases where remain == 0, the 32-bit value would be left shifted 32-bits, which is undefined behavior. Change-Id: I6277279341b168536f928ce87375c395a1aa865c
Diffstat (limited to 'runtime/gc')
-rw-r--r--runtime/gc/allocator/rosalloc.cc7
1 files changed, 4 insertions, 3 deletions
diff --git a/runtime/gc/allocator/rosalloc.cc b/runtime/gc/allocator/rosalloc.cc
index 85234dc..49c7fda 100644
--- a/runtime/gc/allocator/rosalloc.cc
+++ b/runtime/gc/allocator/rosalloc.cc
@@ -1042,10 +1042,11 @@ inline size_t RosAlloc::Run::MarkFreeBitMapShared(void* ptr, uint32_t* free_bit_
inline uint32_t RosAlloc::Run::GetBitmapLastVectorMask(size_t num_slots, size_t num_vec) {
const size_t kBitsPerVec = 32;
- DCHECK_GE(num_slots * kBitsPerVec, num_vec);
+ DCHECK_GE(num_vec * kBitsPerVec, num_slots);
+ DCHECK_NE(num_vec, 0U);
size_t remain = num_vec * kBitsPerVec - num_slots;
- DCHECK_NE(remain, kBitsPerVec);
- return ((1U << remain) - 1) << (kBitsPerVec - remain);
+ DCHECK_LT(remain, kBitsPerVec);
+ return ((1U << remain) - 1) << ((kBitsPerVec - remain) & 0x1F);
}
inline bool RosAlloc::Run::IsAllFree() {