Header library to remove dependence on runtime/
Add a new header library to remove libdexfile and others' dependence on
runtime (typically runtime/base) includes in libdexfile. Also a small step
to tease dexlayout and profman away from relying on these as well.
Bug: 22322814
Test: make -j 50 checkbuild
make -j 50 test-art-host-gtest
Change-Id: I38e2fe399a75f4bc6318c77a71954c00ea73ec2b
diff --git a/runtime/Android.bp b/runtime/Android.bp
index 46e0ee4..c017c5f 100644
--- a/runtime/Android.bp
+++ b/runtime/Android.bp
@@ -46,7 +46,6 @@
"base/safe_copy.cc",
"base/scoped_arena_allocator.cc",
"base/scoped_flock.cc",
- "base/stringpiece.cc",
"base/time_utils.cc",
"base/timing_logger.cc",
"base/unix_file/fd_file.cc",
@@ -196,7 +195,6 @@
"os_linux.cc",
"parsed_options.cc",
"plugin.cc",
- "primitive.cc",
"quick_exception_handler.cc",
"read_barrier.cc",
"reference_table.cc",
@@ -408,6 +406,7 @@
],
header_libs: [
"art_cmdlineparser_headers",
+ "art_libartbase_headers",
"libnativehelper_header_only",
"jni_platform_headers",
],
@@ -443,7 +442,6 @@
"arch/instruction_set.h",
"base/allocator.h",
"base/callee_save_type.h",
- "base/enums.h",
"base/mutex.h",
"base/unix_file/fd_file.h",
"class_status.h",
@@ -545,10 +543,8 @@
"base/bit_field_test.cc",
"base/bit_string_test.cc",
"base/bit_struct_test.cc",
- "base/bit_utils_test.cc",
"base/bit_vector_test.cc",
"base/file_utils_test.cc",
- "base/hash_set_test.cc",
"base/hex_dump_test.cc",
"base/histogram_test.cc",
"base/logging_test.cc",
@@ -599,7 +595,6 @@
"jdwp/jdwp_options_test.cc",
"java_vm_ext_test.cc",
"jit/profile_compilation_info_test.cc",
- "leb128_test.cc",
"mem_map_test.cc",
"memory_region_test.cc",
"method_handles_test.cc",
@@ -613,7 +608,6 @@
"oat_file_assistant_test.cc",
"parsed_options_test.cc",
"prebuilt_tools_test.cc",
- "primitive_test.cc",
"reference_table_test.cc",
"runtime_callbacks_test.cc",
"subtype_check_info_test.cc",
diff --git a/runtime/art_field-inl.h b/runtime/art_field-inl.h
index 99634a0..384581f 100644
--- a/runtime/art_field-inl.h
+++ b/runtime/art_field-inl.h
@@ -23,12 +23,12 @@
#include "class_linker.h"
#include "dex/dex_file-inl.h"
+#include "dex/primitive.h"
#include "gc/accounting/card_table-inl.h"
#include "gc_root-inl.h"
#include "jvalue.h"
#include "mirror/dex_cache-inl.h"
#include "mirror/object-inl.h"
-#include "primitive.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"
diff --git a/runtime/art_field.h b/runtime/art_field.h
index 0eeeef2..29d71af 100644
--- a/runtime/art_field.h
+++ b/runtime/art_field.h
@@ -21,10 +21,10 @@
#include "dex/dex_file_types.h"
#include "dex/modifiers.h"
+#include "dex/primitive.h"
#include "gc_root.h"
#include "obj_ptr.h"
#include "offsets.h"
-#include "primitive.h"
#include "read_barrier_option.h"
namespace art {
diff --git a/runtime/art_method-inl.h b/runtime/art_method-inl.h
index 8b48aa2..145eb67 100644
--- a/runtime/art_method-inl.h
+++ b/runtime/art_method-inl.h
@@ -28,6 +28,7 @@
#include "dex/dex_file_annotations.h"
#include "dex/dex_file_types.h"
#include "dex/invoke_type.h"
+#include "dex/primitive.h"
#include "gc_root-inl.h"
#include "intrinsics_enum.h"
#include "jit/profiling_info.h"
@@ -38,7 +39,6 @@
#include "mirror/string.h"
#include "oat.h"
#include "obj_ptr-inl.h"
-#include "primitive.h"
#include "quick/quick_method_frame_info.h"
#include "read_barrier-inl.h"
#include "runtime-inl.h"
diff --git a/runtime/art_method.h b/runtime/art_method.h
index 21ee8f1..013856f 100644
--- a/runtime/art_method.h
+++ b/runtime/art_method.h
@@ -32,10 +32,10 @@
#include "dex/dex_file.h"
#include "dex/dex_instruction_iterator.h"
#include "dex/modifiers.h"
+#include "dex/primitive.h"
#include "gc_root.h"
#include "obj_ptr.h"
#include "offsets.h"
-#include "primitive.h"
#include "read_barrier_option.h"
namespace art {
diff --git a/runtime/base/arena_allocator.h b/runtime/base/arena_allocator.h
index beaba67..060b6fa 100644
--- a/runtime/base/arena_allocator.h
+++ b/runtime/base/arena_allocator.h
@@ -20,11 +20,11 @@
#include <stddef.h>
#include <stdint.h>
-#include "bit_utils.h"
+#include "base/bit_utils.h"
+#include "base/macros.h"
+#include "base/memory_tool.h"
#include "dchecked_vector.h"
#include "debug_stack.h"
-#include "macros.h"
-#include "memory_tool.h"
#include "mutex.h"
namespace art {
diff --git a/runtime/base/arena_containers.h b/runtime/base/arena_containers.h
index dcdb92b..4f57212 100644
--- a/runtime/base/arena_containers.h
+++ b/runtime/base/arena_containers.h
@@ -26,9 +26,9 @@
#include "arena_allocator.h"
#include "base/dchecked_vector.h"
-#include "hash_map.h"
-#include "hash_set.h"
-#include "safe_map.h"
+#include "base/hash_map.h"
+#include "base/hash_set.h"
+#include "base/safe_map.h"
namespace art {
diff --git a/runtime/base/arena_object.h b/runtime/base/arena_object.h
index 06884c2..d01e346 100644
--- a/runtime/base/arena_object.h
+++ b/runtime/base/arena_object.h
@@ -20,7 +20,7 @@
#include <android-base/logging.h>
#include "arena_allocator.h"
-#include "macros.h"
+#include "base/macros.h"
#include "scoped_arena_allocator.h"
namespace art {
diff --git a/runtime/base/bit_struct.h b/runtime/base/bit_struct.h
index b207459..7eb63c6 100644
--- a/runtime/base/bit_struct.h
+++ b/runtime/base/bit_struct.h
@@ -17,8 +17,8 @@
#ifndef ART_RUNTIME_BASE_BIT_STRUCT_H_
#define ART_RUNTIME_BASE_BIT_STRUCT_H_
+#include "base/bit_utils.h"
#include "bit_struct_detail.h"
-#include "bit_utils.h"
//
// Zero-cost, type-safe, well-defined "structs" of bit fields.
diff --git a/runtime/base/bit_struct_detail.h b/runtime/base/bit_struct_detail.h
index 912f51c..24f6c4c 100644
--- a/runtime/base/bit_struct_detail.h
+++ b/runtime/base/bit_struct_detail.h
@@ -17,7 +17,7 @@
#ifndef ART_RUNTIME_BASE_BIT_STRUCT_DETAIL_H_
#define ART_RUNTIME_BASE_BIT_STRUCT_DETAIL_H_
-#include "bit_utils.h"
+#include "base/bit_utils.h"
#include "globals.h"
#include <type_traits>
diff --git a/runtime/base/bit_utils.h b/runtime/base/bit_utils.h
deleted file mode 100644
index d2a99f1..0000000
--- a/runtime/base/bit_utils.h
+++ /dev/null
@@ -1,504 +0,0 @@
-/*
- * Copyright (C) 2015 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_RUNTIME_BASE_BIT_UTILS_H_
-#define ART_RUNTIME_BASE_BIT_UTILS_H_
-
-#include <limits>
-#include <type_traits>
-
-#include <android-base/logging.h>
-
-#include "base/stl_util_identity.h"
-
-namespace art {
-
-// Like sizeof, but count how many bits a type takes. Pass type explicitly.
-template <typename T>
-constexpr size_t BitSizeOf() {
- static_assert(std::is_integral<T>::value, "T must be integral");
- using unsigned_type = typename std::make_unsigned<T>::type;
- static_assert(sizeof(T) == sizeof(unsigned_type), "Unexpected type size mismatch!");
- static_assert(std::numeric_limits<unsigned_type>::radix == 2, "Unexpected radix!");
- return std::numeric_limits<unsigned_type>::digits;
-}
-
-// Like sizeof, but count how many bits a type takes. Infers type from parameter.
-template <typename T>
-constexpr size_t BitSizeOf(T /*x*/) {
- return BitSizeOf<T>();
-}
-
-template<typename T>
-constexpr int CLZ(T x) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- static_assert(std::is_unsigned<T>::value, "T must be unsigned");
- static_assert(std::numeric_limits<T>::radix == 2, "Unexpected radix!");
- static_assert(sizeof(T) == sizeof(uint64_t) || sizeof(T) <= sizeof(uint32_t),
- "Unsupported sizeof(T)");
- DCHECK_NE(x, 0u);
- constexpr bool is_64_bit = (sizeof(T) == sizeof(uint64_t));
- constexpr size_t adjustment =
- is_64_bit ? 0u : std::numeric_limits<uint32_t>::digits - std::numeric_limits<T>::digits;
- return is_64_bit ? __builtin_clzll(x) : __builtin_clz(x) - adjustment;
-}
-
-// Similar to CLZ except that on zero input it returns bitwidth and supports signed integers.
-template<typename T>
-constexpr int JAVASTYLE_CLZ(T x) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- using unsigned_type = typename std::make_unsigned<T>::type;
- return (x == 0) ? BitSizeOf<T>() : CLZ(static_cast<unsigned_type>(x));
-}
-
-template<typename T>
-constexpr int CTZ(T x) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- // It is not unreasonable to ask for trailing zeros in a negative number. As such, do not check
- // that T is an unsigned type.
- static_assert(sizeof(T) == sizeof(uint64_t) || sizeof(T) <= sizeof(uint32_t),
- "Unsupported sizeof(T)");
- DCHECK_NE(x, static_cast<T>(0));
- return (sizeof(T) == sizeof(uint64_t)) ? __builtin_ctzll(x) : __builtin_ctz(x);
-}
-
-// Similar to CTZ except that on zero input it returns bitwidth and supports signed integers.
-template<typename T>
-constexpr int JAVASTYLE_CTZ(T x) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- using unsigned_type = typename std::make_unsigned<T>::type;
- return (x == 0) ? BitSizeOf<T>() : CTZ(static_cast<unsigned_type>(x));
-}
-
-// Return the number of 1-bits in `x`.
-template<typename T>
-constexpr int POPCOUNT(T x) {
- return (sizeof(T) == sizeof(uint32_t)) ? __builtin_popcount(x) : __builtin_popcountll(x);
-}
-
-// Swap bytes.
-template<typename T>
-constexpr T BSWAP(T x) {
- if (sizeof(T) == sizeof(uint16_t)) {
- return __builtin_bswap16(x);
- } else if (sizeof(T) == sizeof(uint32_t)) {
- return __builtin_bswap32(x);
- } else {
- return __builtin_bswap64(x);
- }
-}
-
-// Find the bit position of the most significant bit (0-based), or -1 if there were no bits set.
-template <typename T>
-constexpr ssize_t MostSignificantBit(T value) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- static_assert(std::is_unsigned<T>::value, "T must be unsigned");
- static_assert(std::numeric_limits<T>::radix == 2, "Unexpected radix!");
- return (value == 0) ? -1 : std::numeric_limits<T>::digits - 1 - CLZ(value);
-}
-
-// Find the bit position of the least significant bit (0-based), or -1 if there were no bits set.
-template <typename T>
-constexpr ssize_t LeastSignificantBit(T value) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- static_assert(std::is_unsigned<T>::value, "T must be unsigned");
- return (value == 0) ? -1 : CTZ(value);
-}
-
-// How many bits (minimally) does it take to store the constant 'value'? i.e. 1 for 1, 3 for 5, etc.
-template <typename T>
-constexpr size_t MinimumBitsToStore(T value) {
- return static_cast<size_t>(MostSignificantBit(value) + 1);
-}
-
-template <typename T>
-constexpr T RoundUpToPowerOfTwo(T x) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- static_assert(std::is_unsigned<T>::value, "T must be unsigned");
- // NOTE: Undefined if x > (1 << (std::numeric_limits<T>::digits - 1)).
- return (x < 2u) ? x : static_cast<T>(1u) << (std::numeric_limits<T>::digits - CLZ(x - 1u));
-}
-
-// Return highest possible N - a power of two - such that val >= N.
-template <typename T>
-constexpr T TruncToPowerOfTwo(T val) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- static_assert(std::is_unsigned<T>::value, "T must be unsigned");
- return (val != 0) ? static_cast<T>(1u) << (BitSizeOf<T>() - CLZ(val) - 1u) : 0;
-}
-
-template<typename T>
-constexpr bool IsPowerOfTwo(T x) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- // TODO: assert unsigned. There is currently many uses with signed values.
- return (x & (x - 1)) == 0;
-}
-
-template<typename T>
-constexpr int WhichPowerOf2(T x) {
- static_assert(std::is_integral<T>::value, "T must be integral");
- // TODO: assert unsigned. There is currently many uses with signed values.
- DCHECK((x != 0) && IsPowerOfTwo(x));
- return CTZ(x);
-}
-
-// For rounding integers.
-// Note: Omit the `n` from T type deduction, deduce only from the `x` argument.
-template<typename T>
-constexpr T RoundDown(T x, typename Identity<T>::type n) WARN_UNUSED;
-
-template<typename T>
-constexpr T RoundDown(T x, typename Identity<T>::type n) {
- DCHECK(IsPowerOfTwo(n));
- return (x & -n);
-}
-
-template<typename T>
-constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) WARN_UNUSED;
-
-template<typename T>
-constexpr T RoundUp(T x, typename std::remove_reference<T>::type n) {
- return RoundDown(x + n - 1, n);
-}
-
-// For aligning pointers.
-template<typename T>
-inline T* AlignDown(T* x, uintptr_t n) WARN_UNUSED;
-
-template<typename T>
-inline T* AlignDown(T* x, uintptr_t n) {
- return reinterpret_cast<T*>(RoundDown(reinterpret_cast<uintptr_t>(x), n));
-}
-
-template<typename T>
-inline T* AlignUp(T* x, uintptr_t n) WARN_UNUSED;
-
-template<typename T>
-inline T* AlignUp(T* x, uintptr_t n) {
- return reinterpret_cast<T*>(RoundUp(reinterpret_cast<uintptr_t>(x), n));
-}
-
-template<int n, typename T>
-constexpr bool IsAligned(T x) {
- static_assert((n & (n - 1)) == 0, "n is not a power of two");
- return (x & (n - 1)) == 0;
-}
-
-template<int n, typename T>
-inline bool IsAligned(T* x) {
- return IsAligned<n>(reinterpret_cast<const uintptr_t>(x));
-}
-
-template<typename T>
-inline bool IsAlignedParam(T x, int n) {
- return (x & (n - 1)) == 0;
-}
-
-template<typename T>
-inline bool IsAlignedParam(T* x, int n) {
- return IsAlignedParam(reinterpret_cast<const uintptr_t>(x), n);
-}
-
-#define CHECK_ALIGNED(value, alignment) \
- CHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<const void*>(value)
-
-#define DCHECK_ALIGNED(value, alignment) \
- DCHECK(::art::IsAligned<alignment>(value)) << reinterpret_cast<const void*>(value)
-
-#define CHECK_ALIGNED_PARAM(value, alignment) \
- CHECK(::art::IsAlignedParam(value, alignment)) << reinterpret_cast<const void*>(value)
-
-#define DCHECK_ALIGNED_PARAM(value, alignment) \
- DCHECK(::art::IsAlignedParam(value, alignment)) << reinterpret_cast<const void*>(value)
-
-inline uint16_t Low16Bits(uint32_t value) {
- return static_cast<uint16_t>(value);
-}
-
-inline uint16_t High16Bits(uint32_t value) {
- return static_cast<uint16_t>(value >> 16);
-}
-
-inline uint32_t Low32Bits(uint64_t value) {
- return static_cast<uint32_t>(value);
-}
-
-inline uint32_t High32Bits(uint64_t value) {
- return static_cast<uint32_t>(value >> 32);
-}
-
-// Check whether an N-bit two's-complement representation can hold value.
-template <typename T>
-inline bool IsInt(size_t N, T value) {
- if (N == BitSizeOf<T>()) {
- return true;
- } else {
- CHECK_LT(0u, N);
- CHECK_LT(N, BitSizeOf<T>());
- T limit = static_cast<T>(1) << (N - 1u);
- return (-limit <= value) && (value < limit);
- }
-}
-
-template <typename T>
-constexpr T GetIntLimit(size_t bits) {
- DCHECK_NE(bits, 0u);
- DCHECK_LT(bits, BitSizeOf<T>());
- return static_cast<T>(1) << (bits - 1);
-}
-
-template <size_t kBits, typename T>
-constexpr bool IsInt(T value) {
- static_assert(kBits > 0, "kBits cannot be zero.");
- static_assert(kBits <= BitSizeOf<T>(), "kBits must be <= max.");
- static_assert(std::is_signed<T>::value, "Needs a signed type.");
- // Corner case for "use all bits." Can't use the limits, as they would overflow, but it is
- // trivially true.
- return (kBits == BitSizeOf<T>()) ?
- true :
- (-GetIntLimit<T>(kBits) <= value) && (value < GetIntLimit<T>(kBits));
-}
-
-template <size_t kBits, typename T>
-constexpr bool IsUint(T value) {
- static_assert(kBits > 0, "kBits cannot be zero.");
- static_assert(kBits <= BitSizeOf<T>(), "kBits must be <= max.");
- static_assert(std::is_integral<T>::value, "Needs an integral type.");
- // Corner case for "use all bits." Can't use the limits, as they would overflow, but it is
- // trivially true.
- // NOTE: To avoid triggering assertion in GetIntLimit(kBits+1) if kBits+1==BitSizeOf<T>(),
- // use GetIntLimit(kBits)*2u. The unsigned arithmetic works well for us if it overflows.
- using unsigned_type = typename std::make_unsigned<T>::type;
- return (0 <= value) &&
- (kBits == BitSizeOf<T>() ||
- (static_cast<unsigned_type>(value) <= GetIntLimit<unsigned_type>(kBits) * 2u - 1u));
-}
-
-template <size_t kBits, typename T>
-constexpr bool IsAbsoluteUint(T value) {
- static_assert(kBits <= BitSizeOf<T>(), "kBits must be <= max.");
- static_assert(std::is_integral<T>::value, "Needs an integral type.");
- using unsigned_type = typename std::make_unsigned<T>::type;
- return (kBits == BitSizeOf<T>())
- ? true
- : IsUint<kBits>(value < 0
- ? static_cast<unsigned_type>(-1 - value) + 1u // Avoid overflow.
- : static_cast<unsigned_type>(value));
-}
-
-// Generate maximum/minimum values for signed/unsigned n-bit integers
-template <typename T>
-constexpr T MaxInt(size_t bits) {
- DCHECK(std::is_unsigned<T>::value || bits > 0u) << "bits cannot be zero for signed.";
- DCHECK_LE(bits, BitSizeOf<T>());
- using unsigned_type = typename std::make_unsigned<T>::type;
- return bits == BitSizeOf<T>()
- ? std::numeric_limits<T>::max()
- : std::is_signed<T>::value
- ? ((bits == 1u) ? 0 : static_cast<T>(MaxInt<unsigned_type>(bits - 1)))
- : static_cast<T>(UINT64_C(1) << bits) - static_cast<T>(1);
-}
-
-template <typename T>
-constexpr T MinInt(size_t bits) {
- DCHECK(std::is_unsigned<T>::value || bits > 0) << "bits cannot be zero for signed.";
- DCHECK_LE(bits, BitSizeOf<T>());
- return bits == BitSizeOf<T>()
- ? std::numeric_limits<T>::min()
- : std::is_signed<T>::value
- ? ((bits == 1u) ? -1 : static_cast<T>(-1) - MaxInt<T>(bits))
- : static_cast<T>(0);
-}
-
-// Returns value with bit set in lowest one-bit position or 0 if 0. (java.lang.X.lowestOneBit).
-template <typename kind>
-inline static kind LowestOneBitValue(kind opnd) {
- // Hacker's Delight, Section 2-1
- return opnd & -opnd;
-}
-
-// Returns value with bit set in hightest one-bit position or 0 if 0. (java.lang.X.highestOneBit).
-template <typename T>
-inline static T HighestOneBitValue(T opnd) {
- using unsigned_type = typename std::make_unsigned<T>::type;
- T res;
- if (opnd == 0) {
- res = 0;
- } else {
- int bit_position = BitSizeOf<T>() - (CLZ(static_cast<unsigned_type>(opnd)) + 1);
- res = static_cast<T>(UINT64_C(1) << bit_position);
- }
- return res;
-}
-
-// Rotate bits.
-template <typename T, bool left>
-inline static T Rot(T opnd, int distance) {
- int mask = BitSizeOf<T>() - 1;
- int unsigned_right_shift = left ? (-distance & mask) : (distance & mask);
- int signed_left_shift = left ? (distance & mask) : (-distance & mask);
- using unsigned_type = typename std::make_unsigned<T>::type;
- return (static_cast<unsigned_type>(opnd) >> unsigned_right_shift) | (opnd << signed_left_shift);
-}
-
-// TUNING: use rbit for arm/arm64
-inline static uint32_t ReverseBits32(uint32_t opnd) {
- // Hacker's Delight 7-1
- opnd = ((opnd >> 1) & 0x55555555) | ((opnd & 0x55555555) << 1);
- opnd = ((opnd >> 2) & 0x33333333) | ((opnd & 0x33333333) << 2);
- opnd = ((opnd >> 4) & 0x0F0F0F0F) | ((opnd & 0x0F0F0F0F) << 4);
- opnd = ((opnd >> 8) & 0x00FF00FF) | ((opnd & 0x00FF00FF) << 8);
- opnd = ((opnd >> 16)) | ((opnd) << 16);
- return opnd;
-}
-
-// TUNING: use rbit for arm/arm64
-inline static uint64_t ReverseBits64(uint64_t opnd) {
- // Hacker's Delight 7-1
- opnd = (opnd & 0x5555555555555555L) << 1 | ((opnd >> 1) & 0x5555555555555555L);
- opnd = (opnd & 0x3333333333333333L) << 2 | ((opnd >> 2) & 0x3333333333333333L);
- opnd = (opnd & 0x0f0f0f0f0f0f0f0fL) << 4 | ((opnd >> 4) & 0x0f0f0f0f0f0f0f0fL);
- opnd = (opnd & 0x00ff00ff00ff00ffL) << 8 | ((opnd >> 8) & 0x00ff00ff00ff00ffL);
- opnd = (opnd << 48) | ((opnd & 0xffff0000L) << 16) | ((opnd >> 16) & 0xffff0000L) | (opnd >> 48);
- return opnd;
-}
-
-// Create a mask for the least significant "bits"
-// The returned value is always unsigned to prevent undefined behavior for bitwise ops.
-//
-// Given 'bits',
-// Returns:
-// <--- bits --->
-// +-----------------+------------+
-// | 0 ............0 | 1.....1 |
-// +-----------------+------------+
-// msb lsb
-template <typename T = size_t>
-inline static constexpr std::make_unsigned_t<T> MaskLeastSignificant(size_t bits) {
- DCHECK_GE(BitSizeOf<T>(), bits) << "Bits out of range for type T";
- using unsigned_T = std::make_unsigned_t<T>;
- if (bits >= BitSizeOf<T>()) {
- return std::numeric_limits<unsigned_T>::max();
- } else {
- auto kOne = static_cast<unsigned_T>(1); // Do not truncate for T>size_t.
- return static_cast<unsigned_T>((kOne << bits) - kOne);
- }
-}
-
-// Clears the bitfield starting at the least significant bit "lsb" with a bitwidth of 'width'.
-// (Equivalent of ARM BFC instruction).
-//
-// Given:
-// <-- width -->
-// +--------+------------+--------+
-// | ABC... | bitfield | XYZ... +
-// +--------+------------+--------+
-// lsb 0
-// Returns:
-// <-- width -->
-// +--------+------------+--------+
-// | ABC... | 0........0 | XYZ... +
-// +--------+------------+--------+
-// lsb 0
-template <typename T>
-inline static constexpr T BitFieldClear(T value, size_t lsb, size_t width) {
- DCHECK_GE(BitSizeOf(value), lsb + width) << "Bit field out of range for value";
- const auto val = static_cast<std::make_unsigned_t<T>>(value);
- const auto mask = MaskLeastSignificant<T>(width);
-
- return static_cast<T>(val & ~(mask << lsb));
-}
-
-// Inserts the contents of 'data' into bitfield of 'value' starting
-// at the least significant bit "lsb" with a bitwidth of 'width'.
-// Note: data must be within range of [MinInt(width), MaxInt(width)].
-// (Equivalent of ARM BFI instruction).
-//
-// Given (data):
-// <-- width -->
-// +--------+------------+--------+
-// | ABC... | bitfield | XYZ... +
-// +--------+------------+--------+
-// lsb 0
-// Returns:
-// <-- width -->
-// +--------+------------+--------+
-// | ABC... | 0...data | XYZ... +
-// +--------+------------+--------+
-// lsb 0
-
-template <typename T, typename T2>
-inline static constexpr T BitFieldInsert(T value, T2 data, size_t lsb, size_t width) {
- DCHECK_GE(BitSizeOf(value), lsb + width) << "Bit field out of range for value";
- if (width != 0u) {
- DCHECK_GE(MaxInt<T2>(width), data) << "Data out of range [too large] for bitwidth";
- DCHECK_LE(MinInt<T2>(width), data) << "Data out of range [too small] for bitwidth";
- } else {
- DCHECK_EQ(static_cast<T2>(0), data) << "Data out of range [nonzero] for bitwidth 0";
- }
- const auto data_mask = MaskLeastSignificant<T2>(width);
- const auto value_cleared = BitFieldClear(value, lsb, width);
-
- return static_cast<T>(value_cleared | ((data & data_mask) << lsb));
-}
-
-// Extracts the bitfield starting at the least significant bit "lsb" with a bitwidth of 'width'.
-// Signed types are sign-extended during extraction. (Equivalent of ARM UBFX/SBFX instruction).
-//
-// Given:
-// <-- width -->
-// +--------+-------------+-------+
-// | | bitfield | +
-// +--------+-------------+-------+
-// lsb 0
-// (Unsigned) Returns:
-// <-- width -->
-// +----------------+-------------+
-// | 0... 0 | bitfield |
-// +----------------+-------------+
-// 0
-// (Signed) Returns:
-// <-- width -->
-// +----------------+-------------+
-// | S... S | bitfield |
-// +----------------+-------------+
-// 0
-// where S is the highest bit in 'bitfield'.
-template <typename T>
-inline static constexpr T BitFieldExtract(T value, size_t lsb, size_t width) {
- DCHECK_GE(BitSizeOf(value), lsb + width) << "Bit field out of range for value";
- const auto val = static_cast<std::make_unsigned_t<T>>(value);
-
- const T bitfield_unsigned =
- static_cast<T>((val >> lsb) & MaskLeastSignificant<T>(width));
- if (std::is_signed<T>::value) {
- // Perform sign extension
- if (width == 0) { // Avoid underflow.
- return static_cast<T>(0);
- } else if (bitfield_unsigned & (1 << (width - 1))) { // Detect if sign bit was set.
- // MSB <width> LSB
- // 0b11111...100...000000
- const auto ones_negmask = ~MaskLeastSignificant<T>(width);
- return static_cast<T>(bitfield_unsigned | ones_negmask);
- }
- }
- // Skip sign extension.
- return bitfield_unsigned;
-}
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_BIT_UTILS_H_
diff --git a/runtime/base/bit_utils_iterator.h b/runtime/base/bit_utils_iterator.h
deleted file mode 100644
index 2d3d050..0000000
--- a/runtime/base/bit_utils_iterator.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2015 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_RUNTIME_BASE_BIT_UTILS_ITERATOR_H_
-#define ART_RUNTIME_BASE_BIT_UTILS_ITERATOR_H_
-
-#include <iterator>
-#include <limits>
-#include <type_traits>
-
-#include <android-base/logging.h>
-
-#include "base/bit_utils.h"
-#include "base/iteration_range.h"
-#include "base/stl_util.h"
-
-namespace art {
-
-// Using the Curiously Recurring Template Pattern to implement everything shared
-// by LowToHighBitIterator and HighToLowBitIterator, i.e. everything but operator*().
-template <typename T, typename Iter>
-class BitIteratorBase
- : public std::iterator<std::forward_iterator_tag, uint32_t, ptrdiff_t, void, void> {
- static_assert(std::is_integral<T>::value, "T must be integral");
- static_assert(std::is_unsigned<T>::value, "T must be unsigned");
-
- static_assert(sizeof(T) == sizeof(uint32_t) || sizeof(T) == sizeof(uint64_t), "Unsupported size");
-
- public:
- BitIteratorBase() : bits_(0u) { }
- explicit BitIteratorBase(T bits) : bits_(bits) { }
-
- Iter& operator++() {
- DCHECK_NE(bits_, 0u);
- uint32_t bit = *static_cast<Iter&>(*this);
- bits_ &= ~(static_cast<T>(1u) << bit);
- return static_cast<Iter&>(*this);
- }
-
- Iter& operator++(int) {
- Iter tmp(static_cast<Iter&>(*this));
- ++*this;
- return tmp;
- }
-
- protected:
- T bits_;
-
- template <typename U, typename I>
- friend bool operator==(const BitIteratorBase<U, I>& lhs, const BitIteratorBase<U, I>& rhs);
-};
-
-template <typename T, typename Iter>
-bool operator==(const BitIteratorBase<T, Iter>& lhs, const BitIteratorBase<T, Iter>& rhs) {
- return lhs.bits_ == rhs.bits_;
-}
-
-template <typename T, typename Iter>
-bool operator!=(const BitIteratorBase<T, Iter>& lhs, const BitIteratorBase<T, Iter>& rhs) {
- return !(lhs == rhs);
-}
-
-template <typename T>
-class LowToHighBitIterator : public BitIteratorBase<T, LowToHighBitIterator<T>> {
- public:
- using BitIteratorBase<T, LowToHighBitIterator<T>>::BitIteratorBase;
-
- uint32_t operator*() const {
- DCHECK_NE(this->bits_, 0u);
- return CTZ(this->bits_);
- }
-};
-
-template <typename T>
-class HighToLowBitIterator : public BitIteratorBase<T, HighToLowBitIterator<T>> {
- public:
- using BitIteratorBase<T, HighToLowBitIterator<T>>::BitIteratorBase;
-
- uint32_t operator*() const {
- DCHECK_NE(this->bits_, 0u);
- static_assert(std::numeric_limits<T>::radix == 2, "Unexpected radix!");
- return std::numeric_limits<T>::digits - 1u - CLZ(this->bits_);
- }
-};
-
-template <typename T>
-IterationRange<LowToHighBitIterator<T>> LowToHighBits(T bits) {
- return IterationRange<LowToHighBitIterator<T>>(
- LowToHighBitIterator<T>(bits), LowToHighBitIterator<T>());
-}
-
-template <typename T>
-IterationRange<HighToLowBitIterator<T>> HighToLowBits(T bits) {
- return IterationRange<HighToLowBitIterator<T>>(
- HighToLowBitIterator<T>(bits), HighToLowBitIterator<T>());
-}
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_BIT_UTILS_ITERATOR_H_
diff --git a/runtime/base/bit_utils_test.cc b/runtime/base/bit_utils_test.cc
deleted file mode 100644
index 3a80600..0000000
--- a/runtime/base/bit_utils_test.cc
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * Copyright (C) 2015 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.
- */
-
-#include <vector>
-
-#include "bit_utils.h"
-#include "bit_utils_iterator.h"
-
-#include "gtest/gtest.h"
-
-namespace art {
-
-// NOTE: CLZ(0u) is undefined.
-static_assert(31 == CLZ<uint32_t>(1u), "TestCLZ32#1");
-static_assert(30 == CLZ<uint32_t>(2u), "TestCLZ32#2");
-static_assert(16 == CLZ<uint32_t>(0x00008765u), "TestCLZ32#3");
-static_assert(15 == CLZ<uint32_t>(0x00012345u), "TestCLZ32#4");
-static_assert(1 == CLZ<uint32_t>(0x43214321u), "TestCLZ32#5");
-static_assert(0 == CLZ<uint32_t>(0x87654321u), "TestCLZ32#6");
-
-// NOTE: CLZ(0ull) is undefined.
-static_assert(63 == CLZ<uint64_t>(UINT64_C(1)), "TestCLZ64#1");
-static_assert(62 == CLZ<uint64_t>(UINT64_C(3)), "TestCLZ64#2");
-static_assert(48 == CLZ<uint64_t>(UINT64_C(0x00008765)), "TestCLZ64#3");
-static_assert(32 == CLZ<uint64_t>(UINT64_C(0x87654321)), "TestCLZ64#4");
-static_assert(31 == CLZ<uint64_t>(UINT64_C(0x123456789)), "TestCLZ64#5");
-static_assert(16 == CLZ<uint64_t>(UINT64_C(0x876543211234)), "TestCLZ64#6");
-static_assert(1 == CLZ<uint64_t>(UINT64_C(0x4321432187654321)), "TestCLZ64#7");
-static_assert(0 == CLZ<uint64_t>(UINT64_C(0x8765432187654321)), "TestCLZ64#8");
-
-// NOTE: CTZ(0u) is undefined.
-static_assert(0 == CTZ<uint32_t>(1u), "TestCTZ32#1");
-static_assert(1 == CTZ<uint32_t>(2u), "TestCTZ32#2");
-static_assert(15 == CTZ<uint32_t>(0x45678000u), "TestCTZ32#3");
-static_assert(16 == CTZ<uint32_t>(0x43210000u), "TestCTZ32#4");
-static_assert(30 == CTZ<uint32_t>(0xc0000000u), "TestCTZ32#5");
-static_assert(31 == CTZ<uint32_t>(0x80000000u), "TestCTZ32#6");
-
-// NOTE: CTZ(0ull) is undefined.
-static_assert(0 == CTZ<uint64_t>(UINT64_C(1)), "TestCTZ64#1");
-static_assert(1 == CTZ<uint64_t>(UINT64_C(2)), "TestCTZ64#2");
-static_assert(16 == CTZ<uint64_t>(UINT64_C(0x43210000)), "TestCTZ64#3");
-static_assert(31 == CTZ<uint64_t>(UINT64_C(0x80000000)), "TestCTZ64#4");
-static_assert(32 == CTZ<uint64_t>(UINT64_C(0x8765432100000000)), "TestCTZ64#5");
-static_assert(48 == CTZ<uint64_t>(UINT64_C(0x4321000000000000)), "TestCTZ64#6");
-static_assert(62 == CTZ<uint64_t>(UINT64_C(0x4000000000000000)), "TestCTZ64#7");
-static_assert(63 == CTZ<uint64_t>(UINT64_C(0x8000000000000000)), "TestCTZ64#8");
-
-static_assert(0 == POPCOUNT<uint32_t>(0u), "TestPOPCOUNT32#1");
-static_assert(1 == POPCOUNT<uint32_t>(8u), "TestPOPCOUNT32#2");
-static_assert(15 == POPCOUNT<uint32_t>(0x55555554u), "TestPOPCOUNT32#3");
-static_assert(16 == POPCOUNT<uint32_t>(0xaaaaaaaau), "TestPOPCOUNT32#4");
-static_assert(31 == POPCOUNT<uint32_t>(0xfffffffeu), "TestPOPCOUNT32#5");
-static_assert(32 == POPCOUNT<uint32_t>(0xffffffffu), "TestPOPCOUNT32#6");
-
-static_assert(0 == POPCOUNT<uint64_t>(UINT64_C(0)), "TestPOPCOUNT64#1");
-static_assert(1 == POPCOUNT<uint64_t>(UINT64_C(0x40000)), "TestPOPCOUNT64#2");
-static_assert(16 == POPCOUNT<uint64_t>(UINT64_C(0x1414141482828282)), "TestPOPCOUNT64#3");
-static_assert(31 == POPCOUNT<uint64_t>(UINT64_C(0x0000ffff00007fff)), "TestPOPCOUNT64#4");
-static_assert(32 == POPCOUNT<uint64_t>(UINT64_C(0x5555555555555555)), "TestPOPCOUNT64#5");
-static_assert(48 == POPCOUNT<uint64_t>(UINT64_C(0x7777bbbbddddeeee)), "TestPOPCOUNT64#6");
-static_assert(63 == POPCOUNT<uint64_t>(UINT64_C(0x7fffffffffffffff)), "TestPOPCOUNT64#7");
-static_assert(64 == POPCOUNT<uint64_t>(UINT64_C(0xffffffffffffffff)), "TestPOPCOUNT64#8");
-
-static_assert(-1 == MostSignificantBit<uint32_t>(0u), "TestMSB32#1");
-static_assert(0 == MostSignificantBit<uint32_t>(1u), "TestMSB32#2");
-static_assert(31 == MostSignificantBit<uint32_t>(~static_cast<uint32_t>(0u)), "TestMSB32#3");
-static_assert(2 == MostSignificantBit<uint32_t>(0b110), "TestMSB32#4");
-static_assert(2 == MostSignificantBit<uint32_t>(0b100), "TestMSB32#5");
-
-static_assert(-1 == MostSignificantBit<uint64_t>(UINT64_C(0)), "TestMSB64#1");
-static_assert(0 == MostSignificantBit<uint64_t>(UINT64_C(1)), "TestMSB64#2");
-static_assert(63 == MostSignificantBit<uint64_t>(~UINT64_C(0)), "TestMSB64#3");
-static_assert(34 == MostSignificantBit<uint64_t>(UINT64_C(0x700000000)), "TestMSB64#4");
-static_assert(34 == MostSignificantBit<uint64_t>(UINT64_C(0x777777777)), "TestMSB64#5");
-
-static_assert(-1 == LeastSignificantBit<uint32_t>(0u), "TestLSB32#1");
-static_assert(0 == LeastSignificantBit<uint32_t>(1u), "TestLSB32#1");
-static_assert(0 == LeastSignificantBit<uint32_t>(~static_cast<uint32_t>(0u)), "TestLSB32#1");
-static_assert(1 == LeastSignificantBit<uint32_t>(0b110), "TestLSB32#1");
-static_assert(2 == LeastSignificantBit<uint32_t>(0b100), "TestLSB32#1");
-
-static_assert(-1 == LeastSignificantBit<uint64_t>(UINT64_C(0)), "TestLSB64#1");
-static_assert(0 == LeastSignificantBit<uint64_t>(UINT64_C(1)), "TestLSB64#2");
-static_assert(0 == LeastSignificantBit<uint64_t>(~UINT64_C(0)), "TestLSB64#3");
-static_assert(12 == LeastSignificantBit<uint64_t>(UINT64_C(0x5000)), "TestLSB64#4");
-static_assert(48 == LeastSignificantBit<uint64_t>(UINT64_C(0x5555000000000000)), "TestLSB64#5");
-
-static_assert(0u == MinimumBitsToStore<uint32_t>(0u), "TestMinBits2Store32#1");
-static_assert(1u == MinimumBitsToStore<uint32_t>(1u), "TestMinBits2Store32#2");
-static_assert(2u == MinimumBitsToStore<uint32_t>(0b10u), "TestMinBits2Store32#3");
-static_assert(2u == MinimumBitsToStore<uint32_t>(0b11u), "TestMinBits2Store32#4");
-static_assert(3u == MinimumBitsToStore<uint32_t>(0b100u), "TestMinBits2Store32#5");
-static_assert(3u == MinimumBitsToStore<uint32_t>(0b110u), "TestMinBits2Store32#6");
-static_assert(3u == MinimumBitsToStore<uint32_t>(0b101u), "TestMinBits2Store32#7");
-static_assert(8u == MinimumBitsToStore<uint32_t>(0xFFu), "TestMinBits2Store32#8");
-static_assert(32u == MinimumBitsToStore<uint32_t>(~static_cast<uint32_t>(0u)),
- "TestMinBits2Store32#9");
-
-static_assert(0u == MinimumBitsToStore<uint64_t>(UINT64_C(0)), "TestMinBits2Store64#1");
-static_assert(1u == MinimumBitsToStore<uint64_t>(UINT64_C(1)), "TestMinBits2Store64#2");
-static_assert(2u == MinimumBitsToStore<uint64_t>(UINT64_C(0b10)), "TestMinBits2Store64#3");
-static_assert(2u == MinimumBitsToStore<uint64_t>(UINT64_C(0b11)), "TestMinBits2Store64#4");
-static_assert(3u == MinimumBitsToStore<uint64_t>(UINT64_C(0b100)), "TestMinBits2Store64#5");
-static_assert(3u == MinimumBitsToStore<uint64_t>(UINT64_C(0b110)), "TestMinBits2Store64#6");
-static_assert(3u == MinimumBitsToStore<uint64_t>(UINT64_C(0b101)), "TestMinBits2Store64#7");
-static_assert(8u == MinimumBitsToStore<uint64_t>(UINT64_C(0xFF)), "TestMinBits2Store64#8");
-static_assert(32u == MinimumBitsToStore<uint64_t>(UINT64_C(0xFFFFFFFF)), "TestMinBits2Store64#9");
-static_assert(33u == MinimumBitsToStore<uint64_t>(UINT64_C(0x1FFFFFFFF)), "TestMinBits2Store64#10");
-static_assert(64u == MinimumBitsToStore<uint64_t>(~UINT64_C(0)), "TestMinBits2Store64#11");
-
-static_assert(0 == TruncToPowerOfTwo<uint32_t>(0u), "TestTruncToPowerOfTwo32#1");
-static_assert(1 == TruncToPowerOfTwo<uint32_t>(1u), "TestTruncToPowerOfTwo32#2");
-static_assert(2 == TruncToPowerOfTwo<uint32_t>(2u), "TestTruncToPowerOfTwo32#3");
-static_assert(2 == TruncToPowerOfTwo<uint32_t>(3u), "TestTruncToPowerOfTwo32#4");
-static_assert(4 == TruncToPowerOfTwo<uint32_t>(7u), "TestTruncToPowerOfTwo32#5");
-static_assert(0x20000u == TruncToPowerOfTwo<uint32_t>(0x3aaaau),
- "TestTruncToPowerOfTwo32#6");
-static_assert(0x40000000u == TruncToPowerOfTwo<uint32_t>(0x40000001u),
- "TestTruncToPowerOfTwo32#7");
-static_assert(0x80000000u == TruncToPowerOfTwo<uint32_t>(0x80000000u),
- "TestTruncToPowerOfTwo32#8");
-
-static_assert(0 == TruncToPowerOfTwo<uint64_t>(UINT64_C(0)), "TestTruncToPowerOfTwo64#1");
-static_assert(1 == TruncToPowerOfTwo<uint64_t>(UINT64_C(1)), "TestTruncToPowerOfTwo64#2");
-static_assert(2 == TruncToPowerOfTwo<uint64_t>(UINT64_C(2)), "TestTruncToPowerOfTwo64#3");
-static_assert(2 == TruncToPowerOfTwo<uint64_t>(UINT64_C(3)), "TestTruncToPowerOfTwo64#4");
-static_assert(4 == TruncToPowerOfTwo<uint64_t>(UINT64_C(7)), "TestTruncToPowerOfTwo64#5");
-static_assert(UINT64_C(0x20000) == TruncToPowerOfTwo<uint64_t>(UINT64_C(0x3aaaa)),
- "TestTruncToPowerOfTwo64#6");
-static_assert(
- UINT64_C(0x4000000000000000) == TruncToPowerOfTwo<uint64_t>(UINT64_C(0x4000000000000001)),
- "TestTruncToPowerOfTwo64#7");
-static_assert(
- UINT64_C(0x8000000000000000) == TruncToPowerOfTwo<uint64_t>(UINT64_C(0x8000000000000000)),
- "TestTruncToPowerOfTwo64#8");
-
-static_assert(0 == RoundUpToPowerOfTwo<uint32_t>(0u), "TestRoundUpPowerOfTwo32#1");
-static_assert(1 == RoundUpToPowerOfTwo<uint32_t>(1u), "TestRoundUpPowerOfTwo32#2");
-static_assert(2 == RoundUpToPowerOfTwo<uint32_t>(2u), "TestRoundUpPowerOfTwo32#3");
-static_assert(4 == RoundUpToPowerOfTwo<uint32_t>(3u), "TestRoundUpPowerOfTwo32#4");
-static_assert(8 == RoundUpToPowerOfTwo<uint32_t>(7u), "TestRoundUpPowerOfTwo32#5");
-static_assert(0x40000u == RoundUpToPowerOfTwo<uint32_t>(0x2aaaau),
- "TestRoundUpPowerOfTwo32#6");
-static_assert(0x80000000u == RoundUpToPowerOfTwo<uint32_t>(0x40000001u),
- "TestRoundUpPowerOfTwo32#7");
-static_assert(0x80000000u == RoundUpToPowerOfTwo<uint32_t>(0x80000000u),
- "TestRoundUpPowerOfTwo32#8");
-
-static_assert(0 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(0)), "TestRoundUpPowerOfTwo64#1");
-static_assert(1 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(1)), "TestRoundUpPowerOfTwo64#2");
-static_assert(2 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(2)), "TestRoundUpPowerOfTwo64#3");
-static_assert(4 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(3)), "TestRoundUpPowerOfTwo64#4");
-static_assert(8 == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(7)), "TestRoundUpPowerOfTwo64#5");
-static_assert(UINT64_C(0x40000) == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(0x2aaaa)),
- "TestRoundUpPowerOfTwo64#6");
-static_assert(
- UINT64_C(0x8000000000000000) == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(0x4000000000000001)),
- "TestRoundUpPowerOfTwo64#7");
-static_assert(
- UINT64_C(0x8000000000000000) == RoundUpToPowerOfTwo<uint64_t>(UINT64_C(0x8000000000000000)),
- "TestRoundUpPowerOfTwo64#8");
-
-static constexpr int64_t kInt32MinMinus1 =
- static_cast<int64_t>(std::numeric_limits<int32_t>::min()) - 1;
-static constexpr int64_t kInt32MaxPlus1 =
- static_cast<int64_t>(std::numeric_limits<int32_t>::max()) + 1;
-static constexpr int64_t kUint32MaxPlus1 =
- static_cast<int64_t>(std::numeric_limits<uint32_t>::max()) + 1;
-
-TEST(BitUtilsTest, TestIsInt32) {
- EXPECT_FALSE(IsInt<int32_t>(1, -2));
- EXPECT_TRUE(IsInt<int32_t>(1, -1));
- EXPECT_TRUE(IsInt<int32_t>(1, 0));
- EXPECT_FALSE(IsInt<int32_t>(1, 1));
- EXPECT_FALSE(IsInt<int32_t>(4, -9));
- EXPECT_TRUE(IsInt<int32_t>(4, -8));
- EXPECT_TRUE(IsInt<int32_t>(4, 7));
- EXPECT_FALSE(IsInt<int32_t>(4, 8));
- EXPECT_FALSE(IsInt<int32_t>(31, std::numeric_limits<int32_t>::min()));
- EXPECT_FALSE(IsInt<int32_t>(31, std::numeric_limits<int32_t>::max()));
- EXPECT_TRUE(IsInt<int32_t>(32, std::numeric_limits<int32_t>::min()));
- EXPECT_TRUE(IsInt<int32_t>(32, std::numeric_limits<int32_t>::max()));
-}
-
-TEST(BitUtilsTest, TestIsInt64) {
- EXPECT_FALSE(IsInt<int64_t>(1, -2));
- EXPECT_TRUE(IsInt<int64_t>(1, -1));
- EXPECT_TRUE(IsInt<int64_t>(1, 0));
- EXPECT_FALSE(IsInt<int64_t>(1, 1));
- EXPECT_FALSE(IsInt<int64_t>(4, -9));
- EXPECT_TRUE(IsInt<int64_t>(4, -8));
- EXPECT_TRUE(IsInt<int64_t>(4, 7));
- EXPECT_FALSE(IsInt<int64_t>(4, 8));
- EXPECT_FALSE(IsInt<int64_t>(31, std::numeric_limits<int32_t>::min()));
- EXPECT_FALSE(IsInt<int64_t>(31, std::numeric_limits<int32_t>::max()));
- EXPECT_TRUE(IsInt<int64_t>(32, std::numeric_limits<int32_t>::min()));
- EXPECT_TRUE(IsInt<int64_t>(32, std::numeric_limits<int32_t>::max()));
- EXPECT_FALSE(IsInt<int64_t>(32, kInt32MinMinus1));
- EXPECT_FALSE(IsInt<int64_t>(32, kInt32MaxPlus1));
- EXPECT_FALSE(IsInt<int64_t>(63, std::numeric_limits<int64_t>::min()));
- EXPECT_FALSE(IsInt<int64_t>(63, std::numeric_limits<int64_t>::max()));
- EXPECT_TRUE(IsInt<int64_t>(64, std::numeric_limits<int64_t>::min()));
- EXPECT_TRUE(IsInt<int64_t>(64, std::numeric_limits<int64_t>::max()));
-}
-
-static_assert(!IsInt<1, int32_t>(-2), "TestIsInt32#1");
-static_assert(IsInt<1, int32_t>(-1), "TestIsInt32#2");
-static_assert(IsInt<1, int32_t>(0), "TestIsInt32#3");
-static_assert(!IsInt<1, int32_t>(1), "TestIsInt32#4");
-static_assert(!IsInt<4, int32_t>(-9), "TestIsInt32#5");
-static_assert(IsInt<4, int32_t>(-8), "TestIsInt32#6");
-static_assert(IsInt<4, int32_t>(7), "TestIsInt32#7");
-static_assert(!IsInt<4, int32_t>(8), "TestIsInt32#8");
-static_assert(!IsInt<31, int32_t>(std::numeric_limits<int32_t>::min()), "TestIsInt32#9");
-static_assert(!IsInt<31, int32_t>(std::numeric_limits<int32_t>::max()), "TestIsInt32#10");
-static_assert(IsInt<32, int32_t>(std::numeric_limits<int32_t>::min()), "TestIsInt32#11");
-static_assert(IsInt<32, int32_t>(std::numeric_limits<int32_t>::max()), "TestIsInt32#12");
-
-static_assert(!IsInt<1, int64_t>(-2), "TestIsInt64#1");
-static_assert(IsInt<1, int64_t>(-1), "TestIsInt64#2");
-static_assert(IsInt<1, int64_t>(0), "TestIsInt64#3");
-static_assert(!IsInt<1, int64_t>(1), "TestIsInt64#4");
-static_assert(!IsInt<4, int64_t>(-9), "TestIsInt64#5");
-static_assert(IsInt<4, int64_t>(-8), "TestIsInt64#6");
-static_assert(IsInt<4, int64_t>(7), "TestIsInt64#7");
-static_assert(!IsInt<4, int64_t>(8), "TestIsInt64#8");
-static_assert(!IsInt<31, int64_t>(std::numeric_limits<int32_t>::min()), "TestIsInt64#9");
-static_assert(!IsInt<31, int64_t>(std::numeric_limits<int32_t>::max()), "TestIsInt64#10");
-static_assert(IsInt<32, int64_t>(std::numeric_limits<int32_t>::min()), "TestIsInt64#11");
-static_assert(IsInt<32, int64_t>(std::numeric_limits<int32_t>::max()), "TestIsInt64#12");
-static_assert(!IsInt<32, int64_t>(kInt32MinMinus1), "TestIsInt64#13");
-static_assert(!IsInt<32, int64_t>(kInt32MaxPlus1), "TestIsInt64#14");
-static_assert(!IsInt<63, int64_t>(std::numeric_limits<int64_t>::min()), "TestIsInt64#15");
-static_assert(!IsInt<63, int64_t>(std::numeric_limits<int64_t>::max()), "TestIsInt64#16");
-static_assert(IsInt<64, int64_t>(std::numeric_limits<int64_t>::min()), "TestIsInt64#17");
-static_assert(IsInt<64, int64_t>(std::numeric_limits<int64_t>::max()), "TestIsInt64#18");
-
-static_assert(!IsUint<1, int32_t>(-1), "TestIsUint32#1");
-static_assert(IsUint<1, int32_t>(0), "TestIsUint32#2");
-static_assert(IsUint<1, int32_t>(1), "TestIsUint32#3");
-static_assert(!IsUint<1, int32_t>(2), "TestIsUint32#4");
-static_assert(!IsUint<4, int32_t>(-1), "TestIsUint32#5");
-static_assert(IsUint<4, int32_t>(0), "TestIsUint32#6");
-static_assert(IsUint<4, int32_t>(15), "TestIsUint32#7");
-static_assert(!IsUint<4, int32_t>(16), "TestIsUint32#8");
-static_assert(!IsUint<30, int32_t>(std::numeric_limits<int32_t>::max()), "TestIsUint32#9");
-static_assert(IsUint<31, int32_t>(std::numeric_limits<int32_t>::max()), "TestIsUint32#10");
-static_assert(!IsUint<32, int32_t>(-1), "TestIsUint32#11");
-static_assert(IsUint<32, int32_t>(0), "TestIsUint32#11");
-static_assert(IsUint<32, uint32_t>(static_cast<uint32_t>(-1)), "TestIsUint32#12");
-
-static_assert(!IsUint<1, int64_t>(-1), "TestIsUint64#1");
-static_assert(IsUint<1, int64_t>(0), "TestIsUint64#2");
-static_assert(IsUint<1, int64_t>(1), "TestIsUint64#3");
-static_assert(!IsUint<1, int64_t>(2), "TestIsUint64#4");
-static_assert(!IsUint<4, int64_t>(-1), "TestIsUint64#5");
-static_assert(IsUint<4, int64_t>(0), "TestIsUint64#6");
-static_assert(IsUint<4, int64_t>(15), "TestIsUint64#7");
-static_assert(!IsUint<4, int64_t>(16), "TestIsUint64#8");
-static_assert(!IsUint<30, int64_t>(std::numeric_limits<int32_t>::max()), "TestIsUint64#9");
-static_assert(IsUint<31, int64_t>(std::numeric_limits<int32_t>::max()), "TestIsUint64#10");
-static_assert(!IsUint<62, int64_t>(std::numeric_limits<int64_t>::max()), "TestIsUint64#11");
-static_assert(IsUint<63, int64_t>(std::numeric_limits<int64_t>::max()), "TestIsUint64#12");
-static_assert(!IsUint<64, int64_t>(-1), "TestIsUint64#13");
-static_assert(IsUint<64, int64_t>(0), "TestIsUint64#14");
-static_assert(IsUint<64, uint64_t>(static_cast<uint32_t>(-1)), "TestIsUint64#15");
-
-static_assert(!IsAbsoluteUint<1, int32_t>(-2), "TestIsAbsoluteUint32#1");
-static_assert(IsAbsoluteUint<1, int32_t>(-1), "TestIsAbsoluteUint32#2");
-static_assert(IsAbsoluteUint<1, int32_t>(0), "TestIsAbsoluteUint32#3");
-static_assert(IsAbsoluteUint<1, int32_t>(1), "TestIsAbsoluteUint32#4");
-static_assert(!IsAbsoluteUint<1, int32_t>(2), "TestIsAbsoluteUint32#5");
-static_assert(!IsAbsoluteUint<4, int32_t>(-16), "TestIsAbsoluteUint32#6");
-static_assert(IsAbsoluteUint<4, int32_t>(-15), "TestIsAbsoluteUint32#7");
-static_assert(IsAbsoluteUint<4, int32_t>(0), "TestIsAbsoluteUint32#8");
-static_assert(IsAbsoluteUint<4, int32_t>(15), "TestIsAbsoluteUint32#9");
-static_assert(!IsAbsoluteUint<4, int32_t>(16), "TestIsAbsoluteUint32#10");
-static_assert(!IsAbsoluteUint<30, int32_t>(std::numeric_limits<int32_t>::max()),
- "TestIsAbsoluteUint32#11");
-static_assert(IsAbsoluteUint<31, int32_t>(std::numeric_limits<int32_t>::max()),
- "TestIsAbsoluteUint32#12");
-static_assert(!IsAbsoluteUint<31, int32_t>(std::numeric_limits<int32_t>::min()),
- "TestIsAbsoluteUint32#13");
-static_assert(IsAbsoluteUint<31, int32_t>(std::numeric_limits<int32_t>::min() + 1),
- "TestIsAbsoluteUint32#14");
-static_assert(IsAbsoluteUint<32, int32_t>(std::numeric_limits<int32_t>::max()),
- "TestIsAbsoluteUint32#15");
-static_assert(IsAbsoluteUint<32, int32_t>(std::numeric_limits<int32_t>::min()),
- "TestIsAbsoluteUint32#16");
-static_assert(IsAbsoluteUint<32, int32_t>(0), "TestIsAbsoluteUint32#17");
-
-static_assert(!IsAbsoluteUint<1, int64_t>(-2), "TestIsAbsoluteUint64#1");
-static_assert(IsAbsoluteUint<1, int64_t>(-1), "TestIsAbsoluteUint64#2");
-static_assert(IsAbsoluteUint<1, int64_t>(0), "TestIsAbsoluteUint64#3");
-static_assert(IsAbsoluteUint<1, int64_t>(1), "TestIsAbsoluteUint64#4");
-static_assert(!IsAbsoluteUint<1, int64_t>(2), "TestIsAbsoluteUint64#5");
-static_assert(!IsAbsoluteUint<4, int64_t>(-16), "TestIsAbsoluteUint64#6");
-static_assert(IsAbsoluteUint<4, int64_t>(-15), "TestIsAbsoluteUint64#7");
-static_assert(IsAbsoluteUint<4, int64_t>(0), "TestIsAbsoluteUint64#8");
-static_assert(IsAbsoluteUint<4, int64_t>(15), "TestIsAbsoluteUint64#9");
-static_assert(!IsAbsoluteUint<4, int64_t>(16), "TestIsAbsoluteUint64#10");
-static_assert(!IsAbsoluteUint<30, int64_t>(std::numeric_limits<int32_t>::max()),
- "TestIsAbsoluteUint64#11");
-static_assert(IsAbsoluteUint<31, int64_t>(std::numeric_limits<int32_t>::max()),
- "TestIsAbsoluteUint64#12");
-static_assert(!IsAbsoluteUint<31, int64_t>(std::numeric_limits<int32_t>::min()),
- "TestIsAbsoluteUint64#13");
-static_assert(IsAbsoluteUint<31, int64_t>(std::numeric_limits<int32_t>::min() + 1),
- "TestIsAbsoluteUint64#14");
-static_assert(IsAbsoluteUint<32, int64_t>(std::numeric_limits<int32_t>::max()),
- "TestIsAbsoluteUint64#15");
-static_assert(IsAbsoluteUint<32, int64_t>(std::numeric_limits<int32_t>::min()),
- "TestIsAbsoluteUint64#16");
-static_assert(!IsAbsoluteUint<62, int64_t>(std::numeric_limits<int64_t>::max()),
- "TestIsAbsoluteUint64#17");
-static_assert(IsAbsoluteUint<63, int64_t>(std::numeric_limits<int64_t>::max()),
- "TestIsAbsoluteUint64#18");
-static_assert(!IsAbsoluteUint<63, int64_t>(std::numeric_limits<int64_t>::min()),
- "TestIsAbsoluteUint64#19");
-static_assert(IsAbsoluteUint<63, int64_t>(std::numeric_limits<int64_t>::min() + 1),
- "TestIsAbsoluteUint64#20");
-static_assert(IsAbsoluteUint<64, int64_t>(std::numeric_limits<int64_t>::max()),
- "TestIsAbsoluteUint64#21");
-static_assert(IsAbsoluteUint<64, int64_t>(std::numeric_limits<int64_t>::min()),
- "TestIsAbsoluteUint64#22");
-static_assert(!IsAbsoluteUint<32, int64_t>(-kUint32MaxPlus1), "TestIsAbsoluteUint64#23");
-static_assert(IsAbsoluteUint<32, int64_t>(-kUint32MaxPlus1 + 1), "TestIsAbsoluteUint64#24");
-static_assert(IsAbsoluteUint<32, int64_t>(0), "TestIsAbsoluteUint64#25");
-static_assert(IsAbsoluteUint<64, int64_t>(0), "TestIsAbsoluteUint64#26");
-static_assert(IsAbsoluteUint<32, int64_t>(std::numeric_limits<uint32_t>::max()),
- "TestIsAbsoluteUint64#27");
-static_assert(!IsAbsoluteUint<32, int64_t>(kUint32MaxPlus1), "TestIsAbsoluteUint64#28");
-
-static_assert(MaskLeastSignificant(0) == 0b0, "TestMaskLeastSignificant#1");
-static_assert(MaskLeastSignificant(1) == 0b1, "TestMaskLeastSignificant#2");
-static_assert(MaskLeastSignificant(2) == 0b11, "TestMaskLeastSignificant#3");
-static_assert(MaskLeastSignificant<uint8_t>(8) == 0xFF, "TestMaskLeastSignificant#4");
-static_assert(MaskLeastSignificant<int8_t>(8) == 0xFF, "TestMaskLeastSignificant#5");
-static_assert(MaskLeastSignificant<uint64_t>(63) == (std::numeric_limits<uint64_t>::max() >> 1u),
- "TestMaskLeastSignificant#6");
-
-static_assert(BitFieldClear(0xFF, /*lsb*/0, /*width*/0) == 0xFF, "TestBitFieldClear#1");
-static_assert(BitFieldClear(std::numeric_limits<uint32_t>::max(), /*lsb*/0, /*width*/32) == 0x0,
- "TestBitFieldClear#2");
-static_assert(BitFieldClear(std::numeric_limits<int32_t>::max(), /*lsb*/0, /*width*/32) == 0x0,
- "TestBitFieldClear#3");
-static_assert(BitFieldClear(0xFF, /*lsb*/0, /*width*/2) == 0b11111100, "TestBitFieldClear#4");
-static_assert(BitFieldClear(0xFF, /*lsb*/0, /*width*/3) == 0b11111000, "TestBitFieldClear#5");
-static_assert(BitFieldClear(0xFF, /*lsb*/1, /*width*/3) == 0b11110001, "TestBitFieldClear#6");
-static_assert(BitFieldClear(0xFF, /*lsb*/2, /*width*/3) == 0b11100011, "TestBitFieldClear#7");
-
-static_assert(BitFieldExtract(0xFF, /*lsb*/0, /*width*/0) == 0x0, "TestBitFieldExtract#1");
-static_assert(BitFieldExtract(std::numeric_limits<uint32_t>::max(), /*lsb*/0, /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldExtract#2");
-static_assert(BitFieldExtract(std::numeric_limits<int32_t>::max(), /*lsb*/0, /*width*/32)
- == std::numeric_limits<int32_t>::max(),
- "TestBitFieldExtract#3");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/0, /*width*/2) == 0b00000011,
- "TestBitFieldExtract#4");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/0, /*width*/3) == 0b00000111,
- "TestBitFieldExtract#5");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/1, /*width*/3) == 0b00000111,
- "TestBitFieldExtract#6");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/2, /*width*/3) == 0b00000111,
- "TestBitFieldExtract#7");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/3, /*width*/3) == 0b00000111,
- "TestBitFieldExtract#8");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/8, /*width*/3) == 0b00000000,
- "TestBitFieldExtract#9");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/7, /*width*/3) == 0b00000001,
- "TestBitFieldExtract#10");
-static_assert(BitFieldExtract(static_cast<uint32_t>(0xFF), /*lsb*/6, /*width*/3) == 0b00000011,
- "TestBitFieldExtract#11");
-static_assert(BitFieldExtract(0xFF, /*lsb*/0, /*width*/2) == -1, "TestBitFieldExtract#12");
-static_assert(BitFieldExtract(0xFF, /*lsb*/0, /*width*/3) == -1, "TestBitFieldExtract#13");
-static_assert(BitFieldExtract(0xFF, /*lsb*/1, /*width*/3) == -1, "TestBitFieldExtract#14");
-static_assert(BitFieldExtract(0xFF, /*lsb*/2, /*width*/3) == -1, "TestBitFieldExtract#15");
-static_assert(BitFieldExtract(0xFF, /*lsb*/3, /*width*/3) == -1, "TestBitFieldExtract#16");
-static_assert(BitFieldExtract(0xFF, /*lsb*/8, /*width*/3) == 0b00000000, "TestBitFieldExtract#17");
-static_assert(BitFieldExtract(0xFF, /*lsb*/7, /*width*/3) == 0b00000001, "TestBitFieldExtract#18");
-static_assert(BitFieldExtract(0xFF, /*lsb*/6, /*width*/3) == 0b00000011, "TestBitFieldExtract#19");
-static_assert(BitFieldExtract(static_cast<uint8_t>(0b01101010), /*lsb*/2, /*width*/4)
- == 0b00001010,
- "TestBitFieldExtract#20");
-static_assert(BitFieldExtract(static_cast<int8_t>(0b01101010), /*lsb*/2, /*width*/4)
- == static_cast<int8_t>(0b11111010),
- "TestBitFieldExtract#21");
-
-static_assert(BitFieldInsert(0xFF, /*data*/0x0, /*lsb*/0, /*width*/0) == 0xFF,
- "TestBitFieldInsert#1");
-static_assert(BitFieldInsert(std::numeric_limits<uint32_t>::max(),
- /*data*/std::numeric_limits<uint32_t>::max(),
- /*lsb*/0,
- /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldInsert#2");
-static_assert(BitFieldInsert(std::numeric_limits<int32_t>::max(),
- /*data*/std::numeric_limits<uint32_t>::max(),
- /*lsb*/0,
- /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldInsert#3");
-static_assert(BitFieldInsert(0u,
- /*data*/std::numeric_limits<uint32_t>::max(),
- /*lsb*/0,
- /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldInsert#4");
-static_assert(BitFieldInsert(-(-0),
- /*data*/std::numeric_limits<uint32_t>::max(),
- /*lsb*/0,
- /*width*/32)
- == std::numeric_limits<uint32_t>::max(),
- "TestBitFieldInsert#5");
-static_assert(BitFieldInsert(0x00, /*data*/0b11u, /*lsb*/0, /*width*/2) == 0b00000011,
- "TestBitFieldInsert#6");
-static_assert(BitFieldInsert(0x00, /*data*/0b111u, /*lsb*/0, /*width*/3) == 0b00000111,
- "TestBitFieldInsert#7");
-static_assert(BitFieldInsert(0x00, /*data*/0b111u, /*lsb*/1, /*width*/3) == 0b00001110,
- "TestBitFieldInsert#8");
-static_assert(BitFieldInsert(0x00, /*data*/0b111u, /*lsb*/2, /*width*/3) == 0b00011100,
- "TestBitFieldInsert#9");
-static_assert(BitFieldInsert(0b01011100, /*data*/0b1101u, /*lsb*/4, /*width*/4) == 0b11011100,
- "TestBitFieldInsert#10");
-
-template <typename Container>
-void CheckElements(const std::initializer_list<uint32_t>& expected, const Container& elements) {
- auto expected_it = expected.begin();
- auto element_it = elements.begin();
- size_t idx = 0u;
- while (expected_it != expected.end() && element_it != elements.end()) {
- EXPECT_EQ(*expected_it, *element_it) << idx;
- ++idx;
- ++expected_it;
- ++element_it;
- }
- ASSERT_TRUE(expected_it == expected.end() && element_it == elements.end())
- << std::boolalpha << (expected_it == expected.end()) << " " << (element_it == elements.end());
-}
-
-TEST(BitUtilsTest, TestLowToHighBits32) {
- CheckElements({}, LowToHighBits<uint32_t>(0u));
- CheckElements({0}, LowToHighBits<uint32_t>(1u));
- CheckElements({15}, LowToHighBits<uint32_t>(0x8000u));
- CheckElements({31}, LowToHighBits<uint32_t>(0x80000000u));
- CheckElements({0, 31}, LowToHighBits<uint32_t>(0x80000001u));
- CheckElements({0, 1, 2, 3, 4, 5, 6, 7, 31}, LowToHighBits<uint32_t>(0x800000ffu));
- CheckElements({0, 8, 16, 24, 31}, LowToHighBits<uint32_t>(0x81010101u));
- CheckElements({16, 17, 30, 31}, LowToHighBits<uint32_t>(0xc0030000u));
- CheckElements({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
- LowToHighBits<uint32_t>(0xffffffffu));
-}
-
-TEST(BitUtilsTest, TestLowToHighBits64) {
- CheckElements({}, LowToHighBits<uint64_t>(UINT64_C(0)));
- CheckElements({0}, LowToHighBits<uint64_t>(UINT64_C(1)));
- CheckElements({32}, LowToHighBits<uint64_t>(UINT64_C(0x100000000)));
- CheckElements({63}, LowToHighBits<uint64_t>(UINT64_C(0x8000000000000000)));
- CheckElements({0, 63}, LowToHighBits<uint64_t>(UINT64_C(0x8000000000000001)));
- CheckElements({0, 1, 2, 3, 4, 5, 6, 7, 63},
- LowToHighBits<uint64_t>(UINT64_C(0x80000000000000ff)));
- CheckElements({0, 8, 16, 24, 32, 40, 48, 56, 63},
- LowToHighBits<uint64_t>(UINT64_C(0x8101010101010101)));
- CheckElements({16, 17, 62, 63}, LowToHighBits<uint64_t>(UINT64_C(0xc000000000030000)));
- CheckElements({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
- 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63},
- LowToHighBits<uint64_t>(UINT64_C(0xffffffffffffffff)));
-}
-
-TEST(BitUtilsTest, TestHighToLowBits32) {
- CheckElements({}, HighToLowBits<uint32_t>(0u));
- CheckElements({0}, HighToLowBits<uint32_t>(1u));
- CheckElements({15}, HighToLowBits<uint32_t>(0x8000u));
- CheckElements({31}, HighToLowBits<uint32_t>(0x80000000u));
- CheckElements({31, 0}, HighToLowBits<uint32_t>(0x80000001u));
- CheckElements({31, 7, 6, 5, 4, 3, 2, 1, 0}, HighToLowBits<uint32_t>(0x800000ffu));
- CheckElements({31, 24, 16, 8, 0}, HighToLowBits<uint32_t>(0x81010101u));
- CheckElements({31, 30, 17, 16}, HighToLowBits<uint32_t>(0xc0030000u));
- CheckElements({31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
- 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
- HighToLowBits<uint32_t>(0xffffffffu));
-}
-
-TEST(BitUtilsTest, TestHighToLowBits64) {
- CheckElements({}, HighToLowBits<uint64_t>(UINT64_C(0)));
- CheckElements({0}, HighToLowBits<uint64_t>(UINT64_C(1)));
- CheckElements({32}, HighToLowBits<uint64_t>(UINT64_C(0x100000000)));
- CheckElements({63}, HighToLowBits<uint64_t>(UINT64_C(0x8000000000000000)));
- CheckElements({63, 0}, HighToLowBits<uint64_t>(UINT64_C(0x8000000000000001)));
- CheckElements({63, 7, 6, 5, 4, 3, 2, 1, 0},
- HighToLowBits<uint64_t>(UINT64_C(0x80000000000000ff)));
- CheckElements({63, 56, 48, 40, 32, 24, 16, 8, 0},
- HighToLowBits<uint64_t>(UINT64_C(0x8101010101010101)));
- CheckElements({63, 62, 17, 16}, HighToLowBits<uint64_t>(UINT64_C(0xc000000000030000)));
- CheckElements({63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48,
- 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32,
- 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16,
- 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
- HighToLowBits<uint64_t>(UINT64_C(0xffffffffffffffff)));
-}
-
-} // namespace art
diff --git a/runtime/base/casts.h b/runtime/base/casts.h
deleted file mode 100644
index 3c6b2be..0000000
--- a/runtime/base/casts.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2011 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_RUNTIME_BASE_CASTS_H_
-#define ART_RUNTIME_BASE_CASTS_H_
-
-#include <assert.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <limits>
-#include <type_traits>
-
-#include <android-base/logging.h>
-
-#include "stl_util_identity.h"
-
-namespace art {
-
-// Use implicit_cast as a safe version of static_cast or const_cast
-// for upcasting in the type hierarchy (i.e. casting a pointer to Foo
-// to a pointer to SuperclassOfFoo or casting a pointer to Foo to
-// a const pointer to Foo).
-// When you use implicit_cast, the compiler checks that the cast is safe.
-// Such explicit implicit_casts are necessary in surprisingly many
-// situations where C++ demands an exact type match instead of an
-// argument type convertible to a target type.
-//
-// The From type can be inferred, so the preferred syntax for using
-// implicit_cast is the same as for static_cast etc.:
-//
-// implicit_cast<ToType>(expr)
-//
-// implicit_cast would have been part of the C++ standard library,
-// but the proposal was submitted too late. It will probably make
-// its way into the language in the future.
-template<typename To, typename From>
-inline To implicit_cast(From const &f) {
- return f;
-}
-
-// When you upcast (that is, cast a pointer from type Foo to type
-// SuperclassOfFoo), it's fine to use implicit_cast<>, since upcasts
-// always succeed. When you downcast (that is, cast a pointer from
-// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because
-// how do you know the pointer is really of type SubclassOfFoo? It
-// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus,
-// when you downcast, you should use this macro. In debug mode, we
-// use dynamic_cast<> to double-check the downcast is legal (we die
-// if it's not). In normal mode, we do the efficient static_cast<>
-// instead. Thus, it's important to test in debug mode to make sure
-// the cast is legal!
-// This is the only place in the code we should use dynamic_cast<>.
-// In particular, you SHOULDN'T be using dynamic_cast<> in order to
-// do RTTI (eg code like this:
-// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo);
-// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo);
-// You should design the code some other way not to need this.
-
-template<typename To, typename From> // use like this: down_cast<T*>(foo);
-inline To down_cast(From* f) { // so we only accept pointers
- static_assert(std::is_base_of<From, typename std::remove_pointer<To>::type>::value,
- "down_cast unsafe as To is not a subtype of From");
-
- return static_cast<To>(f);
-}
-
-template<typename To, typename From> // use like this: down_cast<T&>(foo);
-inline To down_cast(From& f) { // so we only accept references
- static_assert(std::is_base_of<From, typename std::remove_reference<To>::type>::value,
- "down_cast unsafe as To is not a subtype of From");
-
- return static_cast<To>(f);
-}
-
-template <class Dest, class Source>
-inline Dest bit_cast(const Source& source) {
- // Compile time assertion: sizeof(Dest) == sizeof(Source)
- // A compile error here means your Dest and Source have different sizes.
- static_assert(sizeof(Dest) == sizeof(Source), "sizes should be equal");
- Dest dest;
- memcpy(&dest, &source, sizeof(dest));
- return dest;
-}
-
-// A version of static_cast that DCHECKs that the value can be precisely represented
-// when converting to Dest.
-template <typename Dest, typename Source>
-constexpr Dest dchecked_integral_cast(Source source) {
- DCHECK(
- // Check that the value is within the lower limit of Dest.
- (static_cast<intmax_t>(std::numeric_limits<Dest>::min()) <=
- static_cast<intmax_t>(std::numeric_limits<Source>::min()) ||
- source >= static_cast<Source>(std::numeric_limits<Dest>::min())) &&
- // Check that the value is within the upper limit of Dest.
- (static_cast<uintmax_t>(std::numeric_limits<Dest>::max()) >=
- static_cast<uintmax_t>(std::numeric_limits<Source>::max()) ||
- source <= static_cast<Source>(std::numeric_limits<Dest>::max())))
- << "dchecked_integral_cast failed for " << source
- << " (would be " << static_cast<Dest>(source) << ")";
-
- return static_cast<Dest>(source);
-}
-
-// A version of dchecked_integral_cast casting between an integral type and an enum type.
-// When casting to an enum type, the cast does not check if the value corresponds to an enumerator.
-// When casting from an enum type, the target type can be omitted and the enum's underlying type
-// shall be used.
-
-template <typename Dest, typename Source>
-constexpr
-typename std::enable_if<!std::is_enum<Source>::value, Dest>::type
-enum_cast(Source value) {
- return static_cast<Dest>(
- dchecked_integral_cast<typename std::underlying_type<Dest>::type>(value));
-}
-
-template <typename Dest = void, typename Source>
-constexpr
-typename std::enable_if<std::is_enum<Source>::value,
- typename std::conditional<std::is_same<Dest, void>::value,
- std::underlying_type<Source>,
- Identity<Dest>>::type>::type::type
-enum_cast(Source value) {
- using return_type = typename std::conditional<std::is_same<Dest, void>::value,
- std::underlying_type<Source>,
- Identity<Dest>>::type::type;
- return dchecked_integral_cast<return_type>(
- static_cast<typename std::underlying_type<Source>::type>(value));
-}
-
-// A version of reinterpret_cast<>() between pointers and int64_t/uint64_t
-// that goes through uintptr_t to avoid treating the pointer as "signed."
-
-template <typename Dest, typename Source>
-inline Dest reinterpret_cast64(Source source) {
- // This is the overload for casting from int64_t/uint64_t to a pointer.
- static_assert(std::is_same<Source, int64_t>::value || std::is_same<Source, uint64_t>::value,
- "Source must be int64_t or uint64_t.");
- static_assert(std::is_pointer<Dest>::value, "Dest must be a pointer.");
- // Check that we don't lose any non-0 bits here.
- DCHECK_EQ(static_cast<Source>(static_cast<uintptr_t>(source)), source);
- return reinterpret_cast<Dest>(static_cast<uintptr_t>(source));
-}
-
-template <typename Dest, typename Source>
-inline Dest reinterpret_cast64(Source* ptr) {
- // This is the overload for casting from a pointer to int64_t/uint64_t.
- static_assert(std::is_same<Dest, int64_t>::value || std::is_same<Dest, uint64_t>::value,
- "Dest must be int64_t or uint64_t.");
- static_assert(sizeof(uintptr_t) <= sizeof(Dest), "Expecting at most 64-bit pointers.");
- return static_cast<Dest>(reinterpret_cast<uintptr_t>(ptr));
-}
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_CASTS_H_
diff --git a/runtime/base/enums.h b/runtime/base/enums.h
deleted file mode 100644
index 52cab2a..0000000
--- a/runtime/base/enums.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2016 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_RUNTIME_BASE_ENUMS_H_
-#define ART_RUNTIME_BASE_ENUMS_H_
-
-#include <cstddef>
-#include <ostream>
-
-namespace art {
-
-enum class PointerSize : size_t {
- k32 = 4,
- k64 = 8
-};
-std::ostream& operator<<(std::ostream& os, const PointerSize& rhs);
-
-static constexpr PointerSize kRuntimePointerSize = sizeof(void*) == 8U
- ? PointerSize::k64
- : PointerSize::k32;
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_ENUMS_H_
diff --git a/runtime/base/hash_map.h b/runtime/base/hash_map.h
deleted file mode 100644
index b18d586..0000000
--- a/runtime/base/hash_map.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2014 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_RUNTIME_BASE_HASH_MAP_H_
-#define ART_RUNTIME_BASE_HASH_MAP_H_
-
-#include <utility>
-
-#include "hash_set.h"
-
-namespace art {
-
-template <typename Fn>
-class HashMapWrapper {
- public:
- // Hash function.
- template <class Key, class Value>
- size_t operator()(const std::pair<Key, Value>& pair) const {
- return fn_(pair.first);
- }
- template <class Key>
- size_t operator()(const Key& key) const {
- return fn_(key);
- }
- template <class Key, class Value>
- bool operator()(const std::pair<Key, Value>& a, const std::pair<Key, Value>& b) const {
- return fn_(a.first, b.first);
- }
- template <class Key, class Value, class Element>
- bool operator()(const std::pair<Key, Value>& a, const Element& element) const {
- return fn_(a.first, element);
- }
-
- private:
- Fn fn_;
-};
-
-template <class Key, class Value, class EmptyFn,
- class HashFn = std::hash<Key>, class Pred = std::equal_to<Key>,
- class Alloc = std::allocator<std::pair<Key, Value>>>
-class HashMap : public HashSet<std::pair<Key, Value>,
- EmptyFn,
- HashMapWrapper<HashFn>,
- HashMapWrapper<Pred>,
- Alloc> {
- private:
- using Base = HashSet<std::pair<Key, Value>,
- EmptyFn,
- HashMapWrapper<HashFn>,
- HashMapWrapper<Pred>,
- Alloc>;
-
- public:
- HashMap() : Base() { }
- explicit HashMap(const Alloc& alloc)
- : Base(alloc) { }
-};
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_HASH_MAP_H_
diff --git a/runtime/base/hash_set.h b/runtime/base/hash_set.h
deleted file mode 100644
index 47e6d93..0000000
--- a/runtime/base/hash_set.h
+++ /dev/null
@@ -1,693 +0,0 @@
-/*
- * Copyright (C) 2014 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_RUNTIME_BASE_HASH_SET_H_
-#define ART_RUNTIME_BASE_HASH_SET_H_
-
-#include <stdint.h>
-
-#include <functional>
-#include <iterator>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-#include <android-base/logging.h>
-
-#include "bit_utils.h"
-#include "macros.h"
-
-namespace art {
-
-// Returns true if an item is empty.
-template <class T>
-class DefaultEmptyFn {
- public:
- void MakeEmpty(T& item) const {
- item = T();
- }
- bool IsEmpty(const T& item) const {
- return item == T();
- }
-};
-
-template <class T>
-class DefaultEmptyFn<T*> {
- public:
- void MakeEmpty(T*& item) const {
- item = nullptr;
- }
- bool IsEmpty(T* const& item) const {
- return item == nullptr;
- }
-};
-
-// Low memory version of a hash set, uses less memory than std::unordered_set since elements aren't
-// boxed. Uses linear probing to resolve collisions.
-// EmptyFn needs to implement two functions MakeEmpty(T& item) and IsEmpty(const T& item).
-// TODO: We could get rid of this requirement by using a bitmap, though maybe this would be slower
-// and more complicated.
-template <class T, class EmptyFn = DefaultEmptyFn<T>, class HashFn = std::hash<T>,
- class Pred = std::equal_to<T>, class Alloc = std::allocator<T>>
-class HashSet {
- template <class Elem, class HashSetType>
- class BaseIterator : std::iterator<std::forward_iterator_tag, Elem> {
- public:
- BaseIterator(const BaseIterator&) = default;
- BaseIterator(BaseIterator&&) = default;
- BaseIterator(HashSetType* hash_set, size_t index) : index_(index), hash_set_(hash_set) {
- }
- BaseIterator& operator=(const BaseIterator&) = default;
- BaseIterator& operator=(BaseIterator&&) = default;
-
- bool operator==(const BaseIterator& other) const {
- return hash_set_ == other.hash_set_ && this->index_ == other.index_;
- }
-
- bool operator!=(const BaseIterator& other) const {
- return !(*this == other);
- }
-
- BaseIterator operator++() { // Value after modification.
- this->index_ = this->NextNonEmptySlot(this->index_, hash_set_);
- return *this;
- }
-
- BaseIterator operator++(int) {
- BaseIterator temp = *this;
- this->index_ = this->NextNonEmptySlot(this->index_, hash_set_);
- return temp;
- }
-
- Elem& operator*() const {
- DCHECK(!hash_set_->IsFreeSlot(this->index_));
- return hash_set_->ElementForIndex(this->index_);
- }
-
- Elem* operator->() const {
- return &**this;
- }
-
- // TODO: Operator -- --(int) (and use std::bidirectional_iterator_tag)
-
- private:
- size_t index_;
- HashSetType* hash_set_;
-
- size_t NextNonEmptySlot(size_t index, const HashSet* hash_set) const {
- const size_t num_buckets = hash_set->NumBuckets();
- DCHECK_LT(index, num_buckets);
- do {
- ++index;
- } while (index < num_buckets && hash_set->IsFreeSlot(index));
- return index;
- }
-
- friend class HashSet;
- };
-
- public:
- using value_type = T;
- using allocator_type = Alloc;
- using reference = T&;
- using const_reference = const T&;
- using pointer = T*;
- using const_pointer = const T*;
- using iterator = BaseIterator<T, HashSet>;
- using const_iterator = BaseIterator<const T, const HashSet>;
- using size_type = size_t;
- using difference_type = ptrdiff_t;
-
- static constexpr double kDefaultMinLoadFactor = 0.4;
- static constexpr double kDefaultMaxLoadFactor = 0.7;
- static constexpr size_t kMinBuckets = 1000;
-
- // If we don't own the data, this will create a new array which owns the data.
- void Clear() {
- DeallocateStorage();
- num_elements_ = 0;
- elements_until_expand_ = 0;
- }
-
- HashSet() : HashSet(kDefaultMinLoadFactor, kDefaultMaxLoadFactor) {}
-
- HashSet(double min_load_factor, double max_load_factor) noexcept
- : num_elements_(0u),
- num_buckets_(0u),
- elements_until_expand_(0u),
- owns_data_(false),
- data_(nullptr),
- min_load_factor_(min_load_factor),
- max_load_factor_(max_load_factor) {
- DCHECK_GT(min_load_factor, 0.0);
- DCHECK_LT(max_load_factor, 1.0);
- }
-
- explicit HashSet(const allocator_type& alloc) noexcept
- : allocfn_(alloc),
- hashfn_(),
- emptyfn_(),
- pred_(),
- num_elements_(0u),
- num_buckets_(0u),
- elements_until_expand_(0u),
- owns_data_(false),
- data_(nullptr),
- min_load_factor_(kDefaultMinLoadFactor),
- max_load_factor_(kDefaultMaxLoadFactor) {
- }
-
- HashSet(const HashSet& other) noexcept
- : allocfn_(other.allocfn_),
- hashfn_(other.hashfn_),
- emptyfn_(other.emptyfn_),
- pred_(other.pred_),
- num_elements_(other.num_elements_),
- num_buckets_(0),
- elements_until_expand_(other.elements_until_expand_),
- owns_data_(false),
- data_(nullptr),
- min_load_factor_(other.min_load_factor_),
- max_load_factor_(other.max_load_factor_) {
- AllocateStorage(other.NumBuckets());
- for (size_t i = 0; i < num_buckets_; ++i) {
- ElementForIndex(i) = other.data_[i];
- }
- }
-
- // noexcept required so that the move constructor is used instead of copy constructor.
- // b/27860101
- HashSet(HashSet&& other) noexcept
- : allocfn_(std::move(other.allocfn_)),
- hashfn_(std::move(other.hashfn_)),
- emptyfn_(std::move(other.emptyfn_)),
- pred_(std::move(other.pred_)),
- num_elements_(other.num_elements_),
- num_buckets_(other.num_buckets_),
- elements_until_expand_(other.elements_until_expand_),
- owns_data_(other.owns_data_),
- data_(other.data_),
- min_load_factor_(other.min_load_factor_),
- max_load_factor_(other.max_load_factor_) {
- other.num_elements_ = 0u;
- other.num_buckets_ = 0u;
- other.elements_until_expand_ = 0u;
- other.owns_data_ = false;
- other.data_ = nullptr;
- }
-
- // Construct from existing data.
- // Read from a block of memory, if make_copy_of_data is false, then data_ points to within the
- // passed in ptr_.
- HashSet(const uint8_t* ptr, bool make_copy_of_data, size_t* read_count) noexcept {
- uint64_t temp;
- size_t offset = 0;
- offset = ReadFromBytes(ptr, offset, &temp);
- num_elements_ = static_cast<uint64_t>(temp);
- offset = ReadFromBytes(ptr, offset, &temp);
- num_buckets_ = static_cast<uint64_t>(temp);
- CHECK_LE(num_elements_, num_buckets_);
- offset = ReadFromBytes(ptr, offset, &temp);
- elements_until_expand_ = static_cast<uint64_t>(temp);
- offset = ReadFromBytes(ptr, offset, &min_load_factor_);
- offset = ReadFromBytes(ptr, offset, &max_load_factor_);
- if (!make_copy_of_data) {
- owns_data_ = false;
- data_ = const_cast<T*>(reinterpret_cast<const T*>(ptr + offset));
- offset += sizeof(*data_) * num_buckets_;
- } else {
- AllocateStorage(num_buckets_);
- // Write elements, not that this may not be safe for cross compilation if the elements are
- // pointer sized.
- for (size_t i = 0; i < num_buckets_; ++i) {
- offset = ReadFromBytes(ptr, offset, &data_[i]);
- }
- }
- // Caller responsible for aligning.
- *read_count = offset;
- }
-
- // Returns how large the table is after being written. If target is null, then no writing happens
- // but the size is still returned. Target must be 8 byte aligned.
- size_t WriteToMemory(uint8_t* ptr) const {
- size_t offset = 0;
- offset = WriteToBytes(ptr, offset, static_cast<uint64_t>(num_elements_));
- offset = WriteToBytes(ptr, offset, static_cast<uint64_t>(num_buckets_));
- offset = WriteToBytes(ptr, offset, static_cast<uint64_t>(elements_until_expand_));
- offset = WriteToBytes(ptr, offset, min_load_factor_);
- offset = WriteToBytes(ptr, offset, max_load_factor_);
- // Write elements, not that this may not be safe for cross compilation if the elements are
- // pointer sized.
- for (size_t i = 0; i < num_buckets_; ++i) {
- offset = WriteToBytes(ptr, offset, data_[i]);
- }
- // Caller responsible for aligning.
- return offset;
- }
-
- ~HashSet() {
- DeallocateStorage();
- }
-
- HashSet& operator=(HashSet&& other) noexcept {
- HashSet(std::move(other)).swap(*this); // NOLINT [runtime/explicit] [5]
- return *this;
- }
-
- HashSet& operator=(const HashSet& other) noexcept {
- HashSet(other).swap(*this); // NOLINT(runtime/explicit) - a case of lint gone mad.
- return *this;
- }
-
- // Lower case for c++11 for each.
- iterator begin() {
- iterator ret(this, 0);
- if (num_buckets_ != 0 && IsFreeSlot(ret.index_)) {
- ++ret; // Skip all the empty slots.
- }
- return ret;
- }
-
- // Lower case for c++11 for each. const version.
- const_iterator begin() const {
- const_iterator ret(this, 0);
- if (num_buckets_ != 0 && IsFreeSlot(ret.index_)) {
- ++ret; // Skip all the empty slots.
- }
- return ret;
- }
-
- // Lower case for c++11 for each.
- iterator end() {
- return iterator(this, NumBuckets());
- }
-
- // Lower case for c++11 for each. const version.
- const_iterator end() const {
- return const_iterator(this, NumBuckets());
- }
-
- bool Empty() const {
- return Size() == 0;
- }
-
- // Return true if the hash set has ownership of the underlying data.
- bool OwnsData() const {
- return owns_data_;
- }
-
- // Erase algorithm:
- // Make an empty slot where the iterator is pointing.
- // Scan forwards until we hit another empty slot.
- // If an element in between doesn't rehash to the range from the current empty slot to the
- // iterator. It must be before the empty slot, in that case we can move it to the empty slot
- // and set the empty slot to be the location we just moved from.
- // Relies on maintaining the invariant that there's no empty slots from the 'ideal' index of an
- // element to its actual location/index.
- iterator Erase(iterator it) {
- // empty_index is the index that will become empty.
- size_t empty_index = it.index_;
- DCHECK(!IsFreeSlot(empty_index));
- size_t next_index = empty_index;
- bool filled = false; // True if we filled the empty index.
- while (true) {
- next_index = NextIndex(next_index);
- T& next_element = ElementForIndex(next_index);
- // If the next element is empty, we are done. Make sure to clear the current empty index.
- if (emptyfn_.IsEmpty(next_element)) {
- emptyfn_.MakeEmpty(ElementForIndex(empty_index));
- break;
- }
- // Otherwise try to see if the next element can fill the current empty index.
- const size_t next_hash = hashfn_(next_element);
- // Calculate the ideal index, if it is within empty_index + 1 to next_index then there is
- // nothing we can do.
- size_t next_ideal_index = IndexForHash(next_hash);
- // Loop around if needed for our check.
- size_t unwrapped_next_index = next_index;
- if (unwrapped_next_index < empty_index) {
- unwrapped_next_index += NumBuckets();
- }
- // Loop around if needed for our check.
- size_t unwrapped_next_ideal_index = next_ideal_index;
- if (unwrapped_next_ideal_index < empty_index) {
- unwrapped_next_ideal_index += NumBuckets();
- }
- if (unwrapped_next_ideal_index <= empty_index ||
- unwrapped_next_ideal_index > unwrapped_next_index) {
- // If the target index isn't within our current range it must have been probed from before
- // the empty index.
- ElementForIndex(empty_index) = std::move(next_element);
- filled = true; // TODO: Optimize
- empty_index = next_index;
- }
- }
- --num_elements_;
- // If we didn't fill the slot then we need go to the next non free slot.
- if (!filled) {
- ++it;
- }
- return it;
- }
-
- // Find an element, returns end() if not found.
- // Allows custom key (K) types, example of when this is useful:
- // Set of Class* sorted by name, want to find a class with a name but can't allocate a dummy
- // object in the heap for performance solution.
- template <typename K>
- iterator Find(const K& key) {
- return FindWithHash(key, hashfn_(key));
- }
-
- template <typename K>
- const_iterator Find(const K& key) const {
- return FindWithHash(key, hashfn_(key));
- }
-
- template <typename K>
- iterator FindWithHash(const K& key, size_t hash) {
- return iterator(this, FindIndex(key, hash));
- }
-
- template <typename K>
- const_iterator FindWithHash(const K& key, size_t hash) const {
- return const_iterator(this, FindIndex(key, hash));
- }
-
- // Insert an element, allows duplicates.
- template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
- void Insert(U&& element) {
- InsertWithHash(std::forward<U>(element), hashfn_(element));
- }
-
- template <typename U, typename = typename std::enable_if<std::is_convertible<U, T>::value>::type>
- void InsertWithHash(U&& element, size_t hash) {
- DCHECK_EQ(hash, hashfn_(element));
- if (num_elements_ >= elements_until_expand_) {
- Expand();
- DCHECK_LT(num_elements_, elements_until_expand_);
- }
- const size_t index = FirstAvailableSlot(IndexForHash(hash));
- data_[index] = std::forward<U>(element);
- ++num_elements_;
- }
-
- size_t Size() const {
- return num_elements_;
- }
-
- void swap(HashSet& other) {
- // Use argument-dependent lookup with fall-back to std::swap() for function objects.
- using std::swap;
- swap(allocfn_, other.allocfn_);
- swap(hashfn_, other.hashfn_);
- swap(emptyfn_, other.emptyfn_);
- swap(pred_, other.pred_);
- std::swap(data_, other.data_);
- std::swap(num_buckets_, other.num_buckets_);
- std::swap(num_elements_, other.num_elements_);
- std::swap(elements_until_expand_, other.elements_until_expand_);
- std::swap(min_load_factor_, other.min_load_factor_);
- std::swap(max_load_factor_, other.max_load_factor_);
- std::swap(owns_data_, other.owns_data_);
- }
-
- allocator_type get_allocator() const {
- return allocfn_;
- }
-
- void ShrinkToMaximumLoad() {
- Resize(Size() / max_load_factor_);
- }
-
- // Reserve enough room to insert until Size() == num_elements without requiring to grow the hash
- // set. No-op if the hash set is already large enough to do this.
- void Reserve(size_t num_elements) {
- size_t num_buckets = num_elements / max_load_factor_;
- // Deal with rounding errors. Add one for rounding.
- while (static_cast<size_t>(num_buckets * max_load_factor_) <= num_elements + 1u) {
- ++num_buckets;
- }
- if (num_buckets > NumBuckets()) {
- Resize(num_buckets);
- }
- }
-
- // To distance that inserted elements were probed. Used for measuring how good hash functions
- // are.
- size_t TotalProbeDistance() const {
- size_t total = 0;
- for (size_t i = 0; i < NumBuckets(); ++i) {
- const T& element = ElementForIndex(i);
- if (!emptyfn_.IsEmpty(element)) {
- size_t ideal_location = IndexForHash(hashfn_(element));
- if (ideal_location > i) {
- total += i + NumBuckets() - ideal_location;
- } else {
- total += i - ideal_location;
- }
- }
- }
- return total;
- }
-
- // Calculate the current load factor and return it.
- double CalculateLoadFactor() const {
- return static_cast<double>(Size()) / static_cast<double>(NumBuckets());
- }
-
- // Make sure that everything reinserts in the right spot. Returns the number of errors.
- size_t Verify() NO_THREAD_SAFETY_ANALYSIS {
- size_t errors = 0;
- for (size_t i = 0; i < num_buckets_; ++i) {
- T& element = data_[i];
- if (!emptyfn_.IsEmpty(element)) {
- T temp;
- emptyfn_.MakeEmpty(temp);
- std::swap(temp, element);
- size_t first_slot = FirstAvailableSlot(IndexForHash(hashfn_(temp)));
- if (i != first_slot) {
- LOG(ERROR) << "Element " << i << " should be in slot " << first_slot;
- ++errors;
- }
- std::swap(temp, element);
- }
- }
- return errors;
- }
-
- double GetMinLoadFactor() const {
- return min_load_factor_;
- }
-
- double GetMaxLoadFactor() const {
- return max_load_factor_;
- }
-
- // Change the load factor of the hash set. If the current load factor is greater than the max
- // specified, then we resize the hash table storage.
- void SetLoadFactor(double min_load_factor, double max_load_factor) {
- DCHECK_LT(min_load_factor, max_load_factor);
- DCHECK_GT(min_load_factor, 0.0);
- DCHECK_LT(max_load_factor, 1.0);
- min_load_factor_ = min_load_factor;
- max_load_factor_ = max_load_factor;
- elements_until_expand_ = NumBuckets() * max_load_factor_;
- // If the current load factor isn't in the range, then resize to the mean of the minimum and
- // maximum load factor.
- const double load_factor = CalculateLoadFactor();
- if (load_factor > max_load_factor_) {
- Resize(Size() / ((min_load_factor_ + max_load_factor_) * 0.5));
- }
- }
-
- // The hash set expands when Size() reaches ElementsUntilExpand().
- size_t ElementsUntilExpand() const {
- return elements_until_expand_;
- }
-
- size_t NumBuckets() const {
- return num_buckets_;
- }
-
- private:
- T& ElementForIndex(size_t index) {
- DCHECK_LT(index, NumBuckets());
- DCHECK(data_ != nullptr);
- return data_[index];
- }
-
- const T& ElementForIndex(size_t index) const {
- DCHECK_LT(index, NumBuckets());
- DCHECK(data_ != nullptr);
- return data_[index];
- }
-
- size_t IndexForHash(size_t hash) const {
- // Protect against undefined behavior (division by zero).
- if (UNLIKELY(num_buckets_ == 0)) {
- return 0;
- }
- return hash % num_buckets_;
- }
-
- size_t NextIndex(size_t index) const {
- if (UNLIKELY(++index >= num_buckets_)) {
- DCHECK_EQ(index, NumBuckets());
- return 0;
- }
- return index;
- }
-
- // Find the hash table slot for an element, or return NumBuckets() if not found.
- // This value for not found is important so that iterator(this, FindIndex(...)) == end().
- template <typename K>
- size_t FindIndex(const K& element, size_t hash) const {
- // Guard against failing to get an element for a non-existing index.
- if (UNLIKELY(NumBuckets() == 0)) {
- return 0;
- }
- DCHECK_EQ(hashfn_(element), hash);
- size_t index = IndexForHash(hash);
- while (true) {
- const T& slot = ElementForIndex(index);
- if (emptyfn_.IsEmpty(slot)) {
- return NumBuckets();
- }
- if (pred_(slot, element)) {
- return index;
- }
- index = NextIndex(index);
- }
- }
-
- bool IsFreeSlot(size_t index) const {
- return emptyfn_.IsEmpty(ElementForIndex(index));
- }
-
- // Allocate a number of buckets.
- void AllocateStorage(size_t num_buckets) {
- num_buckets_ = num_buckets;
- data_ = allocfn_.allocate(num_buckets_);
- owns_data_ = true;
- for (size_t i = 0; i < num_buckets_; ++i) {
- allocfn_.construct(allocfn_.address(data_[i]));
- emptyfn_.MakeEmpty(data_[i]);
- }
- }
-
- void DeallocateStorage() {
- if (owns_data_) {
- for (size_t i = 0; i < NumBuckets(); ++i) {
- allocfn_.destroy(allocfn_.address(data_[i]));
- }
- if (data_ != nullptr) {
- allocfn_.deallocate(data_, NumBuckets());
- }
- owns_data_ = false;
- }
- data_ = nullptr;
- num_buckets_ = 0;
- }
-
- // Expand the set based on the load factors.
- void Expand() {
- size_t min_index = static_cast<size_t>(Size() / min_load_factor_);
- // Resize based on the minimum load factor.
- Resize(min_index);
- }
-
- // Expand / shrink the table to the new specified size.
- void Resize(size_t new_size) {
- if (new_size < kMinBuckets) {
- new_size = kMinBuckets;
- }
- DCHECK_GE(new_size, Size());
- T* const old_data = data_;
- size_t old_num_buckets = num_buckets_;
- // Reinsert all of the old elements.
- const bool owned_data = owns_data_;
- AllocateStorage(new_size);
- for (size_t i = 0; i < old_num_buckets; ++i) {
- T& element = old_data[i];
- if (!emptyfn_.IsEmpty(element)) {
- data_[FirstAvailableSlot(IndexForHash(hashfn_(element)))] = std::move(element);
- }
- if (owned_data) {
- allocfn_.destroy(allocfn_.address(element));
- }
- }
- if (owned_data) {
- allocfn_.deallocate(old_data, old_num_buckets);
- }
-
- // When we hit elements_until_expand_, we are at the max load factor and must expand again.
- elements_until_expand_ = NumBuckets() * max_load_factor_;
- }
-
- ALWAYS_INLINE size_t FirstAvailableSlot(size_t index) const {
- DCHECK_LT(index, NumBuckets()); // Don't try to get a slot out of range.
- size_t non_empty_count = 0;
- while (!emptyfn_.IsEmpty(data_[index])) {
- index = NextIndex(index);
- non_empty_count++;
- DCHECK_LE(non_empty_count, NumBuckets()); // Don't loop forever.
- }
- return index;
- }
-
- // Return new offset.
- template <typename Elem>
- static size_t WriteToBytes(uint8_t* ptr, size_t offset, Elem n) {
- DCHECK_ALIGNED(ptr + offset, sizeof(n));
- if (ptr != nullptr) {
- *reinterpret_cast<Elem*>(ptr + offset) = n;
- }
- return offset + sizeof(n);
- }
-
- template <typename Elem>
- static size_t ReadFromBytes(const uint8_t* ptr, size_t offset, Elem* out) {
- DCHECK(ptr != nullptr);
- DCHECK_ALIGNED(ptr + offset, sizeof(*out));
- *out = *reinterpret_cast<const Elem*>(ptr + offset);
- return offset + sizeof(*out);
- }
-
- Alloc allocfn_; // Allocator function.
- HashFn hashfn_; // Hashing function.
- EmptyFn emptyfn_; // IsEmpty/SetEmpty function.
- Pred pred_; // Equals function.
- size_t num_elements_; // Number of inserted elements.
- size_t num_buckets_; // Number of hash table buckets.
- size_t elements_until_expand_; // Maximum number of elements until we expand the table.
- bool owns_data_; // If we own data_ and are responsible for freeing it.
- T* data_; // Backing storage.
- double min_load_factor_;
- double max_load_factor_;
-
- ART_FRIEND_TEST(InternTableTest, CrossHash);
-};
-
-template <class T, class EmptyFn, class HashFn, class Pred, class Alloc>
-void swap(HashSet<T, EmptyFn, HashFn, Pred, Alloc>& lhs,
- HashSet<T, EmptyFn, HashFn, Pred, Alloc>& rhs) {
- lhs.swap(rhs);
-}
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_HASH_SET_H_
diff --git a/runtime/base/hash_set_test.cc b/runtime/base/hash_set_test.cc
deleted file mode 100644
index ff745b4..0000000
--- a/runtime/base/hash_set_test.cc
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2014 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.
- */
-
-#include "hash_set.h"
-
-#include <forward_list>
-#include <map>
-#include <sstream>
-#include <string>
-#include <unordered_set>
-#include <vector>
-
-#include <gtest/gtest.h>
-#include "hash_map.h"
-
-namespace art {
-
-struct IsEmptyFnString {
- void MakeEmpty(std::string& item) const {
- item.clear();
- }
- bool IsEmpty(const std::string& item) const {
- return item.empty();
- }
-};
-
-class HashSetTest : public testing::Test {
- public:
- HashSetTest() : seed_(97421), unique_number_(0) {
- }
- std::string RandomString(size_t len) {
- std::ostringstream oss;
- for (size_t i = 0; i < len; ++i) {
- oss << static_cast<char>('A' + PRand() % 64);
- }
- static_assert(' ' < 'A', "space must be less than a");
- oss << " " << unique_number_++; // Relies on ' ' < 'A'
- return oss.str();
- }
- void SetSeed(size_t seed) {
- seed_ = seed;
- }
- size_t PRand() { // Pseudo random.
- seed_ = seed_ * 1103515245 + 12345;
- return seed_;
- }
-
- private:
- size_t seed_;
- size_t unique_number_;
-};
-
-TEST_F(HashSetTest, TestSmoke) {
- HashSet<std::string, IsEmptyFnString> hash_set;
- const std::string test_string = "hello world 1234";
- ASSERT_TRUE(hash_set.Empty());
- ASSERT_EQ(hash_set.Size(), 0U);
- hash_set.Insert(test_string);
- auto it = hash_set.Find(test_string);
- ASSERT_EQ(*it, test_string);
- auto after_it = hash_set.Erase(it);
- ASSERT_TRUE(after_it == hash_set.end());
- ASSERT_TRUE(hash_set.Empty());
- ASSERT_EQ(hash_set.Size(), 0U);
- it = hash_set.Find(test_string);
- ASSERT_TRUE(it == hash_set.end());
-}
-
-TEST_F(HashSetTest, TestInsertAndErase) {
- HashSet<std::string, IsEmptyFnString> hash_set;
- static constexpr size_t count = 1000;
- std::vector<std::string> strings;
- for (size_t i = 0; i < count; ++i) {
- // Insert a bunch of elements and make sure we can find them.
- strings.push_back(RandomString(10));
- hash_set.Insert(strings[i]);
- auto it = hash_set.Find(strings[i]);
- ASSERT_TRUE(it != hash_set.end());
- ASSERT_EQ(*it, strings[i]);
- }
- ASSERT_EQ(strings.size(), hash_set.Size());
- // Try to erase the odd strings.
- for (size_t i = 1; i < count; i += 2) {
- auto it = hash_set.Find(strings[i]);
- ASSERT_TRUE(it != hash_set.end());
- ASSERT_EQ(*it, strings[i]);
- hash_set.Erase(it);
- }
- // Test removed.
- for (size_t i = 1; i < count; i += 2) {
- auto it = hash_set.Find(strings[i]);
- ASSERT_TRUE(it == hash_set.end());
- }
- for (size_t i = 0; i < count; i += 2) {
- auto it = hash_set.Find(strings[i]);
- ASSERT_TRUE(it != hash_set.end());
- ASSERT_EQ(*it, strings[i]);
- }
-}
-
-TEST_F(HashSetTest, TestIterator) {
- HashSet<std::string, IsEmptyFnString> hash_set;
- ASSERT_TRUE(hash_set.begin() == hash_set.end());
- static constexpr size_t count = 1000;
- std::vector<std::string> strings;
- for (size_t i = 0; i < count; ++i) {
- // Insert a bunch of elements and make sure we can find them.
- strings.push_back(RandomString(10));
- hash_set.Insert(strings[i]);
- }
- // Make sure we visit each string exactly once.
- std::map<std::string, size_t> found_count;
- for (const std::string& s : hash_set) {
- ++found_count[s];
- }
- for (size_t i = 0; i < count; ++i) {
- ASSERT_EQ(found_count[strings[i]], 1U);
- }
- found_count.clear();
- // Remove all the elements with iterator erase.
- for (auto it = hash_set.begin(); it != hash_set.end();) {
- ++found_count[*it];
- it = hash_set.Erase(it);
- ASSERT_EQ(hash_set.Verify(), 0U);
- }
- for (size_t i = 0; i < count; ++i) {
- ASSERT_EQ(found_count[strings[i]], 1U);
- }
-}
-
-TEST_F(HashSetTest, TestSwap) {
- HashSet<std::string, IsEmptyFnString> hash_seta, hash_setb;
- std::vector<std::string> strings;
- static constexpr size_t count = 1000;
- for (size_t i = 0; i < count; ++i) {
- strings.push_back(RandomString(10));
- hash_seta.Insert(strings[i]);
- }
- std::swap(hash_seta, hash_setb);
- hash_seta.Insert("TEST");
- hash_setb.Insert("TEST2");
- for (size_t i = 0; i < count; ++i) {
- strings.push_back(RandomString(10));
- hash_seta.Insert(strings[i]);
- }
-}
-
-TEST_F(HashSetTest, TestShrink) {
- HashSet<std::string, IsEmptyFnString> hash_set;
- std::vector<std::string> strings = {"a", "b", "c", "d", "e", "f", "g"};
- for (size_t i = 0; i < strings.size(); ++i) {
- // Insert some strings into the beginning of our hash set to establish an initial size
- hash_set.Insert(strings[i]);
- }
-
- hash_set.ShrinkToMaximumLoad();
- const double initial_load = hash_set.CalculateLoadFactor();
-
- // Insert a bunch of random strings to guarantee that we grow the capacity.
- std::vector<std::string> random_strings;
- static constexpr size_t count = 1000;
- for (size_t i = 0; i < count; ++i) {
- random_strings.push_back(RandomString(10));
- hash_set.Insert(random_strings[i]);
- }
-
- // Erase all the extra strings which guarantees that our load factor will be really bad.
- for (size_t i = 0; i < count; ++i) {
- hash_set.Erase(hash_set.Find(random_strings[i]));
- }
-
- const double bad_load = hash_set.CalculateLoadFactor();
- EXPECT_GT(initial_load, bad_load);
-
- // Shrink again, the load factor should be good again.
- hash_set.ShrinkToMaximumLoad();
- EXPECT_DOUBLE_EQ(initial_load, hash_set.CalculateLoadFactor());
-
- // Make sure all the initial elements we had are still there
- for (const std::string& initial_string : strings) {
- EXPECT_NE(hash_set.end(), hash_set.Find(initial_string))
- << "expected to find " << initial_string;
- }
-}
-
-TEST_F(HashSetTest, TestLoadFactor) {
- HashSet<std::string, IsEmptyFnString> hash_set;
- static constexpr size_t kStringCount = 1000;
- static constexpr double kEpsilon = 0.01;
- for (size_t i = 0; i < kStringCount; ++i) {
- hash_set.Insert(RandomString(i % 10 + 1));
- }
- // Check that changing the load factor resizes the table to be within the target range.
- EXPECT_GE(hash_set.CalculateLoadFactor() + kEpsilon, hash_set.GetMinLoadFactor());
- EXPECT_LE(hash_set.CalculateLoadFactor() - kEpsilon, hash_set.GetMaxLoadFactor());
- hash_set.SetLoadFactor(0.1, 0.3);
- EXPECT_DOUBLE_EQ(0.1, hash_set.GetMinLoadFactor());
- EXPECT_DOUBLE_EQ(0.3, hash_set.GetMaxLoadFactor());
- EXPECT_LE(hash_set.CalculateLoadFactor() - kEpsilon, hash_set.GetMaxLoadFactor());
- hash_set.SetLoadFactor(0.6, 0.8);
- EXPECT_LE(hash_set.CalculateLoadFactor() - kEpsilon, hash_set.GetMaxLoadFactor());
-}
-
-TEST_F(HashSetTest, TestStress) {
- HashSet<std::string, IsEmptyFnString> hash_set;
- std::unordered_multiset<std::string> std_set;
- std::vector<std::string> strings;
- static constexpr size_t string_count = 2000;
- static constexpr size_t operations = 100000;
- static constexpr size_t target_size = 5000;
- for (size_t i = 0; i < string_count; ++i) {
- strings.push_back(RandomString(i % 10 + 1));
- }
- const size_t seed = time(nullptr);
- SetSeed(seed);
- LOG(INFO) << "Starting stress test with seed " << seed;
- for (size_t i = 0; i < operations; ++i) {
- ASSERT_EQ(hash_set.Size(), std_set.size());
- size_t delta = std::abs(static_cast<ssize_t>(target_size) -
- static_cast<ssize_t>(hash_set.Size()));
- size_t n = PRand();
- if (n % target_size == 0) {
- hash_set.Clear();
- std_set.clear();
- ASSERT_TRUE(hash_set.Empty());
- ASSERT_TRUE(std_set.empty());
- } else if (n % target_size < delta) {
- // Skew towards adding elements until we are at the desired size.
- const std::string& s = strings[PRand() % string_count];
- hash_set.Insert(s);
- std_set.insert(s);
- ASSERT_EQ(*hash_set.Find(s), *std_set.find(s));
- } else {
- const std::string& s = strings[PRand() % string_count];
- auto it1 = hash_set.Find(s);
- auto it2 = std_set.find(s);
- ASSERT_EQ(it1 == hash_set.end(), it2 == std_set.end());
- if (it1 != hash_set.end()) {
- ASSERT_EQ(*it1, *it2);
- hash_set.Erase(it1);
- std_set.erase(it2);
- }
- }
- }
-}
-
-struct IsEmptyStringPair {
- void MakeEmpty(std::pair<std::string, int>& pair) const {
- pair.first.clear();
- }
- bool IsEmpty(const std::pair<std::string, int>& pair) const {
- return pair.first.empty();
- }
-};
-
-TEST_F(HashSetTest, TestHashMap) {
- HashMap<std::string, int, IsEmptyStringPair> hash_map;
- hash_map.Insert(std::make_pair(std::string("abcd"), 123));
- hash_map.Insert(std::make_pair(std::string("abcd"), 124));
- hash_map.Insert(std::make_pair(std::string("bags"), 444));
- auto it = hash_map.Find(std::string("abcd"));
- ASSERT_EQ(it->second, 123);
- hash_map.Erase(it);
- it = hash_map.Find(std::string("abcd"));
- ASSERT_EQ(it->second, 124);
-}
-
-struct IsEmptyFnVectorInt {
- void MakeEmpty(std::vector<int>& item) const {
- item.clear();
- }
- bool IsEmpty(const std::vector<int>& item) const {
- return item.empty();
- }
-};
-
-template <typename T>
-size_t HashIntSequence(T begin, T end) {
- size_t hash = 0;
- for (auto iter = begin; iter != end; ++iter) {
- hash = hash * 2 + *iter;
- }
- return hash;
-}
-
-struct VectorIntHashEquals {
- std::size_t operator()(const std::vector<int>& item) const {
- return HashIntSequence(item.begin(), item.end());
- }
-
- std::size_t operator()(const std::forward_list<int>& item) const {
- return HashIntSequence(item.begin(), item.end());
- }
-
- bool operator()(const std::vector<int>& a, const std::vector<int>& b) const {
- return a == b;
- }
-
- bool operator()(const std::vector<int>& a, const std::forward_list<int>& b) const {
- auto aiter = a.begin();
- auto biter = b.begin();
- while (aiter != a.end() && biter != b.end()) {
- if (*aiter != *biter) {
- return false;
- }
- aiter++;
- biter++;
- }
- return (aiter == a.end() && biter == b.end());
- }
-};
-
-TEST_F(HashSetTest, TestLookupByAlternateKeyType) {
- HashSet<std::vector<int>, IsEmptyFnVectorInt, VectorIntHashEquals, VectorIntHashEquals> hash_set;
- hash_set.Insert(std::vector<int>({1, 2, 3, 4}));
- hash_set.Insert(std::vector<int>({4, 2}));
- ASSERT_EQ(hash_set.end(), hash_set.Find(std::vector<int>({1, 1, 1, 1})));
- ASSERT_NE(hash_set.end(), hash_set.Find(std::vector<int>({1, 2, 3, 4})));
- ASSERT_EQ(hash_set.end(), hash_set.Find(std::forward_list<int>({1, 1, 1, 1})));
- ASSERT_NE(hash_set.end(), hash_set.Find(std::forward_list<int>({1, 2, 3, 4})));
-}
-
-TEST_F(HashSetTest, TestReserve) {
- HashSet<std::string, IsEmptyFnString> hash_set;
- std::vector<size_t> sizes = {1, 10, 25, 55, 128, 1024, 4096};
- for (size_t size : sizes) {
- hash_set.Reserve(size);
- const size_t buckets_before = hash_set.NumBuckets();
- // Check that we expanded enough.
- CHECK_GE(hash_set.ElementsUntilExpand(), size);
- // Try inserting elements until we are at our reserve size and ensure the hash set did not
- // expand.
- while (hash_set.Size() < size) {
- hash_set.Insert(std::to_string(hash_set.Size()));
- }
- CHECK_EQ(hash_set.NumBuckets(), buckets_before);
- }
- // Check the behaviour for shrinking, it does not necessarily resize down.
- constexpr size_t size = 100;
- hash_set.Reserve(size);
- CHECK_GE(hash_set.ElementsUntilExpand(), size);
-}
-
-} // namespace art
diff --git a/runtime/base/hex_dump.h b/runtime/base/hex_dump.h
index 8769ece..2ce0aef 100644
--- a/runtime/base/hex_dump.h
+++ b/runtime/base/hex_dump.h
@@ -17,7 +17,7 @@
#ifndef ART_RUNTIME_BASE_HEX_DUMP_H_
#define ART_RUNTIME_BASE_HEX_DUMP_H_
-#include "macros.h"
+#include "base/macros.h"
#include <ostream>
diff --git a/runtime/base/iteration_range.h b/runtime/base/iteration_range.h
deleted file mode 100644
index 3f6f5d6..0000000
--- a/runtime/base/iteration_range.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2015 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_RUNTIME_BASE_ITERATION_RANGE_H_
-#define ART_RUNTIME_BASE_ITERATION_RANGE_H_
-
-#include <iterator>
-
-namespace art {
-
-// Helper class that acts as a container for range-based loops, given an iteration
-// range [first, last) defined by two iterators.
-template <typename Iter>
-class IterationRange {
- public:
- typedef Iter iterator;
- typedef typename std::iterator_traits<Iter>::difference_type difference_type;
- typedef typename std::iterator_traits<Iter>::value_type value_type;
- typedef typename std::iterator_traits<Iter>::pointer pointer;
- typedef typename std::iterator_traits<Iter>::reference reference;
-
- IterationRange(iterator first, iterator last) : first_(first), last_(last) { }
-
- iterator begin() const { return first_; }
- iterator end() const { return last_; }
- iterator cbegin() const { return first_; }
- iterator cend() const { return last_; }
-
- private:
- const iterator first_;
- const iterator last_;
-};
-
-template <typename Iter>
-inline IterationRange<Iter> MakeIterationRange(const Iter& begin_it, const Iter& end_it) {
- return IterationRange<Iter>(begin_it, end_it);
-}
-
-template <typename Iter>
-inline IterationRange<Iter> MakeEmptyIterationRange(const Iter& it) {
- return IterationRange<Iter>(it, it);
-}
-
-template <typename Container>
-inline auto ReverseRange(Container&& c) {
- typedef typename std::reverse_iterator<decltype(c.begin())> riter;
- return MakeIterationRange(riter(c.end()), riter(c.begin()));
-}
-
-template <typename T, size_t size>
-inline auto ReverseRange(T (&array)[size]) {
- return ReverseRange(MakeIterationRange<T*>(array, array+size));
-}
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_ITERATION_RANGE_H_
diff --git a/runtime/base/macros.h b/runtime/base/macros.h
deleted file mode 100644
index 512e5ce..0000000
--- a/runtime/base/macros.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2010 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_RUNTIME_BASE_MACROS_H_
-#define ART_RUNTIME_BASE_MACROS_H_
-
-#include <stddef.h> // for size_t
-#include <unistd.h> // for TEMP_FAILURE_RETRY
-
-#include "android-base/macros.h"
-#include "android-base/thread_annotations.h"
-
-#define OVERRIDE override
-#define FINAL final
-
-// Declare a friend relationship in a class with a test. Used rather that FRIEND_TEST to avoid
-// globally importing gtest/gtest.h into the main ART header files.
-#define ART_FRIEND_TEST(test_set_name, individual_test)\
-friend class test_set_name##_##individual_test##_Test
-
-// Declare a friend relationship in a class with a typed test.
-#define ART_FRIEND_TYPED_TEST(test_set_name, individual_test)\
-template<typename T> ART_FRIEND_TEST(test_set_name, individual_test)
-
-// A macro to disallow new and delete operators for a class. It goes in the private: declarations.
-// NOTE: Providing placement new (and matching delete) for constructing container elements.
-#define DISALLOW_ALLOCATION() \
- public: \
- NO_RETURN ALWAYS_INLINE void operator delete(void*, size_t) { UNREACHABLE(); } \
- ALWAYS_INLINE void* operator new(size_t, void* ptr) noexcept { return ptr; } \
- ALWAYS_INLINE void operator delete(void*, void*) noexcept { } \
- private: \
- void* operator new(size_t) = delete // NOLINT
-
-#define SIZEOF_MEMBER(t, f) sizeof((reinterpret_cast<t*>(4096))->f) // NOLINT
-
-#define OFFSETOF_MEMBER(t, f) \
- (reinterpret_cast<uintptr_t>(&reinterpret_cast<t*>(16)->f) - static_cast<uintptr_t>(16u)) // NOLINT
-
-#define OFFSETOF_MEMBERPTR(t, f) \
- (reinterpret_cast<uintptr_t>(&(reinterpret_cast<t*>(16)->*f)) - static_cast<uintptr_t>(16)) // NOLINT
-
-#define PACKED(x) __attribute__ ((__aligned__(x), __packed__))
-
-// Stringify the argument.
-#define QUOTE(x) #x
-#define STRINGIFY(x) QUOTE(x)
-
-// Append tokens after evaluating.
-#define APPEND_TOKENS_AFTER_EVAL_2(a, b) a ## b
-#define APPEND_TOKENS_AFTER_EVAL(a, b) APPEND_TOKENS_AFTER_EVAL_2(a, b)
-
-#ifndef NDEBUG
-#define ALWAYS_INLINE
-#else
-#define ALWAYS_INLINE __attribute__ ((always_inline))
-#endif
-
-// clang doesn't like attributes on lambda functions. It would be nice to say:
-// #define ALWAYS_INLINE_LAMBDA ALWAYS_INLINE
-#define ALWAYS_INLINE_LAMBDA
-
-#define NO_INLINE __attribute__ ((noinline))
-
-#if defined (__APPLE__)
-#define HOT_ATTR
-#define COLD_ATTR
-#else
-#define HOT_ATTR __attribute__ ((hot))
-#define COLD_ATTR __attribute__ ((cold))
-#endif
-
-#define PURE __attribute__ ((__pure__))
-
-// Define that a position within code is unreachable, for example:
-// int foo () { LOG(FATAL) << "Don't call me"; UNREACHABLE(); }
-// without the UNREACHABLE a return statement would be necessary.
-#define UNREACHABLE __builtin_unreachable
-
-// Add the C++11 noreturn attribute.
-#define NO_RETURN [[ noreturn ]] // NOLINT[whitespace/braces] [5]
-
-// Annotalysis thread-safety analysis support. Things that are not in base.
-
-#define LOCKABLE CAPABILITY("mutex")
-#define SHARED_LOCKABLE SHARED_CAPABILITY("mutex")
-
-#endif // ART_RUNTIME_BASE_MACROS_H_
diff --git a/runtime/base/memory_tool.h b/runtime/base/memory_tool.h
deleted file mode 100644
index 223c1de..0000000
--- a/runtime/base/memory_tool.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2015 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_RUNTIME_BASE_MEMORY_TOOL_H_
-#define ART_RUNTIME_BASE_MEMORY_TOOL_H_
-
-#include <stddef.h>
-
-#if !defined(__has_feature)
-#define __has_feature(x) 0
-#endif
-
-#if __has_feature(address_sanitizer)
-
-#include <sanitizer/asan_interface.h>
-#define ADDRESS_SANITIZER
-
-#ifdef ART_ENABLE_ADDRESS_SANITIZER
-#define MEMORY_TOOL_MAKE_NOACCESS(p, s) __asan_poison_memory_region(p, s)
-#define MEMORY_TOOL_MAKE_UNDEFINED(p, s) __asan_unpoison_memory_region(p, s)
-#define MEMORY_TOOL_MAKE_DEFINED(p, s) __asan_unpoison_memory_region(p, s)
-constexpr bool kMemoryToolIsAvailable = true;
-#else
-#define MEMORY_TOOL_MAKE_NOACCESS(p, s) do { (void)(p); (void)(s); } while (0)
-#define MEMORY_TOOL_MAKE_UNDEFINED(p, s) do { (void)(p); (void)(s); } while (0)
-#define MEMORY_TOOL_MAKE_DEFINED(p, s) do { (void)(p); (void)(s); } while (0)
-constexpr bool kMemoryToolIsAvailable = false;
-#endif
-
-extern "C" void __asan_handle_no_return();
-
-#define ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
-#define MEMORY_TOOL_HANDLE_NO_RETURN __asan_handle_no_return()
-#define RUNNING_ON_MEMORY_TOOL 1U
-constexpr bool kMemoryToolIsValgrind = false;
-constexpr bool kMemoryToolDetectsLeaks = true;
-constexpr bool kMemoryToolAddsRedzones = true;
-constexpr size_t kMemoryToolStackGuardSizeScale = 2;
-
-#else
-
-#include <memcheck/memcheck.h>
-#include <valgrind.h>
-#define MEMORY_TOOL_MAKE_NOACCESS(p, s) VALGRIND_MAKE_MEM_NOACCESS(p, s)
-#define MEMORY_TOOL_MAKE_UNDEFINED(p, s) VALGRIND_MAKE_MEM_UNDEFINED(p, s)
-#define MEMORY_TOOL_MAKE_DEFINED(p, s) VALGRIND_MAKE_MEM_DEFINED(p, s)
-#define ATTRIBUTE_NO_SANITIZE_ADDRESS
-#define MEMORY_TOOL_HANDLE_NO_RETURN do { } while (0)
-#define RUNNING_ON_MEMORY_TOOL RUNNING_ON_VALGRIND
-constexpr bool kMemoryToolIsAvailable = true;
-constexpr bool kMemoryToolIsValgrind = true;
-constexpr bool kMemoryToolDetectsLeaks = true;
-constexpr bool kMemoryToolAddsRedzones = true;
-constexpr size_t kMemoryToolStackGuardSizeScale = 1;
-
-#endif
-
-#endif // ART_RUNTIME_BASE_MEMORY_TOOL_H_
diff --git a/runtime/base/safe_copy.cc b/runtime/base/safe_copy.cc
index b46b921..7ba5cbd 100644
--- a/runtime/base/safe_copy.cc
+++ b/runtime/base/safe_copy.cc
@@ -24,7 +24,7 @@
#include <android-base/macros.h>
-#include "bit_utils.h"
+#include "base/bit_utils.h"
namespace art {
diff --git a/runtime/base/scoped_arena_allocator.h b/runtime/base/scoped_arena_allocator.h
index 35e337f..202902e 100644
--- a/runtime/base/scoped_arena_allocator.h
+++ b/runtime/base/scoped_arena_allocator.h
@@ -20,9 +20,9 @@
#include <android-base/logging.h>
#include "arena_allocator.h"
+#include "base/macros.h"
#include "debug_stack.h"
#include "globals.h"
-#include "macros.h"
namespace art {
diff --git a/runtime/base/scoped_arena_containers.h b/runtime/base/scoped_arena_containers.h
index 756089f..f8ee3f3 100644
--- a/runtime/base/scoped_arena_containers.h
+++ b/runtime/base/scoped_arena_containers.h
@@ -26,7 +26,7 @@
#include "arena_containers.h" // For ArenaAllocatorAdapterKind.
#include "base/dchecked_vector.h"
-#include "safe_map.h"
+#include "base/safe_map.h"
#include "scoped_arena_allocator.h"
namespace art {
diff --git a/runtime/base/stl_util.h b/runtime/base/stl_util.h
deleted file mode 100644
index 02f3765..0000000
--- a/runtime/base/stl_util.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2011 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_RUNTIME_BASE_STL_UTIL_H_
-#define ART_RUNTIME_BASE_STL_UTIL_H_
-
-#include <algorithm>
-#include <set>
-#include <sstream>
-
-#include <android-base/logging.h>
-
-namespace art {
-
-// STLDeleteContainerPointers()
-// For a range within a container of pointers, calls delete
-// (non-array version) on these pointers.
-// NOTE: for these three functions, we could just implement a DeleteObject
-// functor and then call for_each() on the range and functor, but this
-// requires us to pull in all of algorithm.h, which seems expensive.
-// For hash_[multi]set, it is important that this deletes behind the iterator
-// because the hash_set may call the hash function on the iterator when it is
-// advanced, which could result in the hash function trying to deference a
-// stale pointer.
-template <class ForwardIterator>
-void STLDeleteContainerPointers(ForwardIterator begin,
- ForwardIterator end) {
- while (begin != end) {
- ForwardIterator temp = begin;
- ++begin;
- delete *temp;
- }
-}
-
-// STLDeleteElements() deletes all the elements in an STL container and clears
-// the container. This function is suitable for use with a vector, set,
-// hash_set, or any other STL container which defines sensible begin(), end(),
-// and clear() methods.
-//
-// If container is null, this function is a no-op.
-//
-// As an alternative to calling STLDeleteElements() directly, consider
-// using a container of std::unique_ptr, which ensures that your container's
-// elements are deleted when the container goes out of scope.
-template <class T>
-void STLDeleteElements(T *container) {
- if (container != nullptr) {
- STLDeleteContainerPointers(container->begin(), container->end());
- container->clear();
- }
-}
-
-// Given an STL container consisting of (key, value) pairs, STLDeleteValues
-// deletes all the "value" components and clears the container. Does nothing
-// in the case it's given a null pointer.
-template <class T>
-void STLDeleteValues(T *v) {
- if (v != nullptr) {
- for (typename T::iterator i = v->begin(); i != v->end(); ++i) {
- delete i->second;
- }
- v->clear();
- }
-}
-
-// Deleter using free() for use with std::unique_ptr<>. See also UniqueCPtr<> below.
-struct FreeDelete {
- // NOTE: Deleting a const object is valid but free() takes a non-const pointer.
- void operator()(const void* ptr) const {
- free(const_cast<void*>(ptr));
- }
-};
-
-// Alias for std::unique_ptr<> that uses the C function free() to delete objects.
-template <typename T>
-using UniqueCPtr = std::unique_ptr<T, FreeDelete>;
-
-// Find index of the first element with the specified value known to be in the container.
-template <typename Container, typename T>
-size_t IndexOfElement(const Container& container, const T& value) {
- auto it = std::find(container.begin(), container.end(), value);
- DCHECK(it != container.end()); // Must exist.
- return std::distance(container.begin(), it);
-}
-
-// Remove the first element with the specified value known to be in the container.
-template <typename Container, typename T>
-void RemoveElement(Container& container, const T& value) {
- auto it = std::find(container.begin(), container.end(), value);
- DCHECK(it != container.end()); // Must exist.
- container.erase(it);
-}
-
-// Replace the first element with the specified old_value known to be in the container.
-template <typename Container, typename T>
-void ReplaceElement(Container& container, const T& old_value, const T& new_value) {
- auto it = std::find(container.begin(), container.end(), old_value);
- DCHECK(it != container.end()); // Must exist.
- *it = new_value;
-}
-
-// Search for an element with the specified value and return true if it was found, false otherwise.
-template <typename Container, typename T>
-bool ContainsElement(const Container& container, const T& value, size_t start_pos = 0u) {
- DCHECK_LE(start_pos, container.size());
- auto start = container.begin();
- std::advance(start, start_pos);
- auto it = std::find(start, container.end(), value);
- return it != container.end();
-}
-
-// 32-bit FNV-1a hash function suitable for std::unordered_map.
-// It can be used with any container which works with range-based for loop.
-// See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function
-template <typename Vector>
-struct FNVHash {
- size_t operator()(const Vector& vector) const {
- uint32_t hash = 2166136261u;
- for (const auto& value : vector) {
- hash = (hash ^ value) * 16777619u;
- }
- return hash;
- }
-};
-
-// Merge `other` entries into `to_update`.
-template <typename T>
-static inline void MergeSets(std::set<T>& to_update, const std::set<T>& other) {
- to_update.insert(other.begin(), other.end());
-}
-
-// Returns a copy of the passed vector that doesn't memory-own its entries.
-template <typename T>
-static inline std::vector<T*> MakeNonOwningPointerVector(const std::vector<std::unique_ptr<T>>& src) {
- std::vector<T*> result;
- result.reserve(src.size());
- for (const std::unique_ptr<T>& t : src) {
- result.push_back(t.get());
- }
- return result;
-}
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_STL_UTIL_H_
diff --git a/runtime/base/stl_util_identity.h b/runtime/base/stl_util_identity.h
deleted file mode 100644
index 40a93f7..0000000
--- a/runtime/base/stl_util_identity.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2011 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_RUNTIME_BASE_STL_UTIL_IDENTITY_H_
-#define ART_RUNTIME_BASE_STL_UTIL_IDENTITY_H_
-
-namespace art {
-
-// Use to suppress type deduction for a function argument.
-// See std::identity<> for more background:
-// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html#20.2.2 - move/forward helpers
-//
-// e.g. "template <typename X> void bar(identity<X>::type foo);
-// bar(5); // compilation error
-// bar<int>(5); // ok
-// or "template <typename T> void foo(T* x, typename Identity<T*>::type y);
-// Base b;
-// Derived d;
-// foo(&b, &d); // Use implicit Derived* -> Base* conversion.
-// If T was deduced from both &b and &d, there would be a mismatch, i.e. deduction failure.
-template <typename T>
-struct Identity {
- using type = T;
-};
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_STL_UTIL_IDENTITY_H_
diff --git a/runtime/base/stringpiece.cc b/runtime/base/stringpiece.cc
deleted file mode 100644
index aea4e74..0000000
--- a/runtime/base/stringpiece.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-#include "stringpiece.h"
-
-#include <ostream>
-#include <utility>
-
-#include <android-base/logging.h>
-
-namespace art {
-
-void StringPiece::CopyToString(std::string* target) const {
- target->assign(ptr_, length_);
-}
-
-StringPiece::size_type StringPiece::copy(char* buf, size_type n, size_type pos) const {
- size_type ret = std::min(length_ - pos, n);
- memcpy(buf, ptr_ + pos, ret);
- return ret;
-}
-
-StringPiece::size_type StringPiece::find(const StringPiece& s, size_type pos) const {
- if (length_ == 0 || pos > static_cast<size_type>(length_)) {
- return npos;
- }
- const char* result = std::search(ptr_ + pos, ptr_ + length_, s.ptr_, s.ptr_ + s.length_);
- const size_type xpos = result - ptr_;
- return xpos + s.length_ <= length_ ? xpos : npos;
-}
-
-int StringPiece::compare(const StringPiece& x) const {
- int r = memcmp(ptr_, x.ptr_, std::min(length_, x.length_));
- if (r == 0) {
- if (length_ < x.length_) r = -1;
- else if (length_ > x.length_) r = +1;
- }
- return r;
-}
-
-StringPiece::size_type StringPiece::find(char c, size_type pos) const {
- if (length_ == 0 || pos >= length_) {
- return npos;
- }
- const char* result = std::find(ptr_ + pos, ptr_ + length_, c);
- return result != ptr_ + length_ ? result - ptr_ : npos;
-}
-
-StringPiece::size_type StringPiece::rfind(const StringPiece& s, size_type pos) const {
- if (length_ < s.length_) return npos;
- const size_t ulen = length_;
- if (s.length_ == 0) return std::min(ulen, pos);
-
- const char* last = ptr_ + std::min(ulen - s.length_, pos) + s.length_;
- const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
- return result != last ? result - ptr_ : npos;
-}
-
-StringPiece::size_type StringPiece::rfind(char c, size_type pos) const {
- if (length_ == 0) return npos;
- for (int i = std::min(pos, static_cast<size_type>(length_ - 1));
- i >= 0; --i) {
- if (ptr_[i] == c) {
- return i;
- }
- }
- return npos;
-}
-
-StringPiece StringPiece::substr(size_type pos, size_type n) const {
- if (pos > static_cast<size_type>(length_)) pos = length_;
- if (n > length_ - pos) n = length_ - pos;
- return StringPiece(ptr_ + pos, n);
-}
-
-std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
- o.write(piece.data(), piece.size());
- return o;
-}
-
-} // namespace art
diff --git a/runtime/base/stringpiece.h b/runtime/base/stringpiece.h
deleted file mode 100644
index e7109dc..0000000
--- a/runtime/base/stringpiece.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2010 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_RUNTIME_BASE_STRINGPIECE_H_
-#define ART_RUNTIME_BASE_STRINGPIECE_H_
-
-#include <string.h>
-#include <string>
-
-#include <android-base/logging.h>
-
-namespace art {
-
-// A string-like object that points to a sized piece of memory.
-//
-// Functions or methods may use const StringPiece& parameters to accept either
-// a "const char*" or a "string" value that will be implicitly converted to
-// a StringPiece. The implicit conversion means that it is often appropriate
-// to include this .h file in other files rather than forward-declaring
-// StringPiece as would be appropriate for most other Google classes.
-class StringPiece {
- public:
- // standard STL container boilerplate
- typedef char value_type;
- typedef const char* pointer;
- typedef const char& reference;
- typedef const char& const_reference;
- typedef size_t size_type;
- typedef ptrdiff_t difference_type;
- static constexpr size_type npos = size_type(-1);
- typedef const char* const_iterator;
- typedef const char* iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
-
- // We provide non-explicit singleton constructors so users can pass
- // in a "const char*" or a "string" wherever a "StringPiece" is
- // expected.
- StringPiece() : ptr_(nullptr), length_(0) { }
- StringPiece(const char* str) // NOLINT implicit constructor desired
- : ptr_(str), length_((str == nullptr) ? 0 : strlen(str)) { }
- StringPiece(const std::string& str) // NOLINT implicit constructor desired
- : ptr_(str.data()), length_(str.size()) { }
- StringPiece(const char* offset, size_t len) : ptr_(offset), length_(len) { }
-
- // data() may return a pointer to a buffer with embedded NULs, and the
- // returned buffer may or may not be null terminated. Therefore it is
- // typically a mistake to pass data() to a routine that expects a NUL
- // terminated string.
- const char* data() const { return ptr_; }
- size_type size() const { return length_; }
- size_type length() const { return length_; }
- bool empty() const { return length_ == 0; }
-
- void clear() {
- ptr_ = nullptr;
- length_ = 0;
- }
- void set(const char* data_in, size_type len) {
- ptr_ = data_in;
- length_ = len;
- }
- void set(const char* str) {
- ptr_ = str;
- if (str != nullptr) {
- length_ = strlen(str);
- } else {
- length_ = 0;
- }
- }
- void set(const void* data_in, size_type len) {
- ptr_ = reinterpret_cast<const char*>(data_in);
- length_ = len;
- }
-
- char operator[](size_type i) const {
- DCHECK_LT(i, length_);
- return ptr_[i];
- }
-
- void remove_prefix(size_type n) {
- ptr_ += n;
- length_ -= n;
- }
-
- void remove_suffix(size_type n) {
- length_ -= n;
- }
-
- int compare(const StringPiece& x) const;
-
- std::string as_string() const {
- return std::string(data(), size());
- }
- // We also define ToString() here, since many other string-like
- // interfaces name the routine that converts to a C++ string
- // "ToString", and it's confusing to have the method that does that
- // for a StringPiece be called "as_string()". We also leave the
- // "as_string()" method defined here for existing code.
- std::string ToString() const {
- return std::string(data(), size());
- }
-
- void CopyToString(std::string* target) const;
- void AppendToString(std::string* target) const;
-
- // Does "this" start with "x"
- bool starts_with(const StringPiece& x) const {
- return ((length_ >= x.length_) &&
- (memcmp(ptr_, x.ptr_, x.length_) == 0));
- }
-
- // Does "this" end with "x"
- bool ends_with(const StringPiece& x) const {
- return ((length_ >= x.length_) &&
- (memcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
- }
-
- iterator begin() const { return ptr_; }
- iterator end() const { return ptr_ + length_; }
- const_reverse_iterator rbegin() const {
- return const_reverse_iterator(ptr_ + length_);
- }
- const_reverse_iterator rend() const {
- return const_reverse_iterator(ptr_);
- }
-
- size_type copy(char* buf, size_type n, size_type pos = 0) const;
-
- size_type find(const StringPiece& s, size_type pos = 0) const;
- size_type find(char c, size_type pos = 0) const;
- size_type rfind(const StringPiece& s, size_type pos = npos) const;
- size_type rfind(char c, size_type pos = npos) const;
-
- StringPiece substr(size_type pos, size_type n = npos) const;
-
- int Compare(const StringPiece& rhs) const {
- const int r = memcmp(data(), rhs.data(), std::min(size(), rhs.size()));
- if (r != 0) {
- return r;
- }
- if (size() < rhs.size()) {
- return -1;
- } else if (size() > rhs.size()) {
- return 1;
- }
- return 0;
- }
-
- private:
- // Pointer to char data, not necessarily zero terminated.
- const char* ptr_;
- // Length of data.
- size_type length_;
-};
-
-// This large function is defined inline so that in a fairly common case where
-// one of the arguments is a literal, the compiler can elide a lot of the
-// following comparisons.
-inline bool operator==(const StringPiece& x, const StringPiece& y) {
- StringPiece::size_type len = x.size();
- if (len != y.size()) {
- return false;
- }
-
- const char* p1 = x.data();
- const char* p2 = y.data();
- if (p1 == p2) {
- return true;
- }
- if (len == 0) {
- return true;
- }
-
- // Test last byte in case strings share large common prefix
- if (p1[len-1] != p2[len-1]) return false;
- if (len == 1) return true;
-
- // At this point we can, but don't have to, ignore the last byte. We use
- // this observation to fold the odd-length case into the even-length case.
- len &= ~1;
-
- return memcmp(p1, p2, len) == 0;
-}
-
-inline bool operator==(const StringPiece& x, const char* y) {
- if (y == nullptr) {
- return x.size() == 0;
- } else {
- return strncmp(x.data(), y, x.size()) == 0 && y[x.size()] == '\0';
- }
-}
-
-inline bool operator!=(const StringPiece& x, const StringPiece& y) {
- return !(x == y);
-}
-
-inline bool operator!=(const StringPiece& x, const char* y) {
- return !(x == y);
-}
-
-inline bool operator<(const StringPiece& x, const StringPiece& y) {
- return x.Compare(y) < 0;
-}
-
-inline bool operator>(const StringPiece& x, const StringPiece& y) {
- return y < x;
-}
-
-inline bool operator<=(const StringPiece& x, const StringPiece& y) {
- return !(x > y);
-}
-
-inline bool operator>=(const StringPiece& x, const StringPiece& y) {
- return !(x < y);
-}
-
-extern std::ostream& operator<<(std::ostream& o, const StringPiece& piece);
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_STRINGPIECE_H_
diff --git a/runtime/base/tracking_safe_map.h b/runtime/base/tracking_safe_map.h
new file mode 100644
index 0000000..2f3984d
--- /dev/null
+++ b/runtime/base/tracking_safe_map.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2013 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_RUNTIME_BASE_TRACKING_SAFE_MAP_H_
+#define ART_RUNTIME_BASE_TRACKING_SAFE_MAP_H_
+
+#include "base/allocator.h"
+#include "base/safe_map.h"
+
+namespace art {
+
+template<class Key, class T, AllocatorTag kTag, class Compare = std::less<Key>>
+class AllocationTrackingSafeMap : public SafeMap<
+ Key, T, Compare, TrackingAllocator<std::pair<const Key, T>, kTag>> {
+};
+
+} // namespace art
+
+#endif // ART_RUNTIME_BASE_TRACKING_SAFE_MAP_H_
diff --git a/runtime/base/value_object.h b/runtime/base/value_object.h
deleted file mode 100644
index 8c752a9..0000000
--- a/runtime/base/value_object.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2014 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_RUNTIME_BASE_VALUE_OBJECT_H_
-#define ART_RUNTIME_BASE_VALUE_OBJECT_H_
-
-#include "base/macros.h"
-
-namespace art {
-
-class ValueObject {
- private:
- DISALLOW_ALLOCATION();
-};
-
-} // namespace art
-
-#endif // ART_RUNTIME_BASE_VALUE_OBJECT_H_
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index f18e0b4..c667fe2 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -36,6 +36,7 @@
#include "art_method-inl.h"
#include "base/arena_allocator.h"
#include "base/casts.h"
+#include "base/leb128.h"
#include "base/logging.h"
#include "base/scoped_arena_containers.h"
#include "base/scoped_flock.h"
@@ -79,7 +80,6 @@
#include "jit/jit_code_cache.h"
#include "jit/profile_compilation_info.h"
#include "jni_internal.h"
-#include "leb128.h"
#include "linear_alloc.h"
#include "mirror/call_site.h"
#include "mirror/class-inl.h"
diff --git a/runtime/common_dex_operations.h b/runtime/common_dex_operations.h
index 1db25c4..37e074d 100644
--- a/runtime/common_dex_operations.h
+++ b/runtime/common_dex_operations.h
@@ -24,6 +24,7 @@
#include "base/mutex.h"
#include "class_linker.h"
#include "dex/code_item_accessors.h"
+#include "dex/primitive.h"
#include "handle_scope-inl.h"
#include "instrumentation.h"
#include "interpreter/shadow_frame.h"
@@ -31,7 +32,6 @@
#include "mirror/class.h"
#include "mirror/object.h"
#include "obj_ptr-inl.h"
-#include "primitive.h"
#include "runtime.h"
#include "stack.h"
#include "thread.h"
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 8c268d8..e4fbc86 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -38,6 +38,7 @@
#include "dex/art_dex_file_loader.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_loader.h"
+#include "dex/primitive.h"
#include "gc/heap.h"
#include "gc_root-inl.h"
#include "gtest/gtest.h"
@@ -51,7 +52,6 @@
#include "native/dalvik_system_DexFile.h"
#include "noop_compiler_callbacks.h"
#include "os.h"
-#include "primitive.h"
#include "runtime-inl.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index 5066385..99a4c77 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -29,6 +29,7 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
#include "base/enums.h"
+#include "base/safe_map.h"
#include "base/strlcpy.h"
#include "base/time_utils.h"
#include "class_linker-inl.h"
@@ -64,7 +65,6 @@
#include "oat_file.h"
#include "obj_ptr-inl.h"
#include "reflection.h"
-#include "safe_map.h"
#include "scoped_thread_state_change-inl.h"
#include "stack.h"
#include "thread_list.h"
diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc
index d057ff3..b466181 100644
--- a/runtime/elf_file.cc
+++ b/runtime/elf_file.cc
@@ -25,11 +25,11 @@
#include "android-base/strings.h"
#include "arch/instruction_set.h"
+#include "base/leb128.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "elf_file_impl.h"
#include "elf_utils.h"
-#include "leb128.h"
#include "utils.h"
namespace art {
diff --git a/runtime/gc/accounting/mod_union_table.h b/runtime/gc/accounting/mod_union_table.h
index 4b5d5f3..766e0f5 100644
--- a/runtime/gc/accounting/mod_union_table.h
+++ b/runtime/gc/accounting/mod_union_table.h
@@ -18,11 +18,12 @@
#define ART_RUNTIME_GC_ACCOUNTING_MOD_UNION_TABLE_H_
#include "base/allocator.h"
+#include "base/safe_map.h"
+#include "base/tracking_safe_map.h"
#include "bitmap.h"
#include "card_table.h"
#include "globals.h"
#include "mirror/object_reference.h"
-#include "safe_map.h"
#include <set>
#include <vector>
diff --git a/runtime/gc/accounting/remembered_set.h b/runtime/gc/accounting/remembered_set.h
index 90d4ffb..e9376a9 100644
--- a/runtime/gc/accounting/remembered_set.h
+++ b/runtime/gc/accounting/remembered_set.h
@@ -18,8 +18,8 @@
#define ART_RUNTIME_GC_ACCOUNTING_REMEMBERED_SET_H_
#include "base/allocator.h"
+#include "base/safe_map.h"
#include "globals.h"
-#include "safe_map.h"
#include <set>
#include <vector>
diff --git a/runtime/gc/collector/concurrent_copying.h b/runtime/gc/collector/concurrent_copying.h
index c58dd44..a00dbb5 100644
--- a/runtime/gc/collector/concurrent_copying.h
+++ b/runtime/gc/collector/concurrent_copying.h
@@ -18,12 +18,12 @@
#define ART_RUNTIME_GC_COLLECTOR_CONCURRENT_COPYING_H_
#include "barrier.h"
+#include "base/safe_map.h"
#include "garbage_collector.h"
#include "immune_spaces.h"
#include "jni.h"
#include "mirror/object_reference.h"
#include "offsets.h"
-#include "safe_map.h"
#include <unordered_map>
#include <vector>
diff --git a/runtime/gc/heap.h b/runtime/gc/heap.h
index 9d2d2ed..592172f 100644
--- a/runtime/gc/heap.h
+++ b/runtime/gc/heap.h
@@ -30,6 +30,7 @@
#include "base/macros.h"
#include "base/mutex.h"
#include "base/runtime_debug.h"
+#include "base/safe_map.h"
#include "base/time_utils.h"
#include "gc/collector/gc_type.h"
#include "gc/collector/iteration.h"
@@ -42,7 +43,6 @@
#include "offsets.h"
#include "process_state.h"
#include "read_barrier_config.h"
-#include "safe_map.h"
#include "verify_object.h"
namespace art {
diff --git a/runtime/gc/space/large_object_space.h b/runtime/gc/space/large_object_space.h
index 38e28b1..f37d814 100644
--- a/runtime/gc/space/large_object_space.h
+++ b/runtime/gc/space/large_object_space.h
@@ -18,8 +18,9 @@
#define ART_RUNTIME_GC_SPACE_LARGE_OBJECT_SPACE_H_
#include "base/allocator.h"
+#include "base/safe_map.h"
+#include "base/tracking_safe_map.h"
#include "dlmalloc_space.h"
-#include "safe_map.h"
#include "space.h"
#include <set>
diff --git a/runtime/globals.h b/runtime/globals.h
index ca4040d..bdc2177 100644
--- a/runtime/globals.h
+++ b/runtime/globals.h
@@ -17,123 +17,7 @@
#ifndef ART_RUNTIME_GLOBALS_H_
#define ART_RUNTIME_GLOBALS_H_
-#include <stddef.h>
-#include <stdint.h>
-
-namespace art {
-
-static constexpr size_t KB = 1024;
-static constexpr size_t MB = KB * KB;
-static constexpr size_t GB = KB * KB * KB;
-
-// Runtime sizes.
-static constexpr size_t kBitsPerByte = 8;
-static constexpr size_t kBitsPerByteLog2 = 3;
-static constexpr int kBitsPerIntPtrT = sizeof(intptr_t) * kBitsPerByte;
-
-// Required stack alignment
-static constexpr size_t kStackAlignment = 16;
-
-// System page size. We check this against sysconf(_SC_PAGE_SIZE) at runtime, but use a simple
-// compile-time constant so the compiler can generate better code.
-static constexpr int kPageSize = 4096;
-
-// Returns whether the given memory offset can be used for generating
-// an implicit null check.
-static inline bool CanDoImplicitNullCheckOn(uintptr_t offset) {
- return offset < kPageSize;
-}
-
-// Required object alignment
-static constexpr size_t kObjectAlignmentShift = 3;
-static constexpr size_t kObjectAlignment = 1u << kObjectAlignmentShift;
-static constexpr size_t kLargeObjectAlignment = kPageSize;
-
-// Clion, clang analyzer, etc can falsely believe that "if (kIsDebugBuild)" always
-// returns the same value. By wrapping into a call to another constexpr function, we force it
-// to realize that is not actually always evaluating to the same value.
-static constexpr bool GlobalsReturnSelf(bool self) { return self; }
-
-// Whether or not this is a debug build. Useful in conditionals where NDEBUG isn't.
-// TODO: Use only __clang_analyzer__ here. b/64455231
-#if defined(NDEBUG) && !defined(__CLION_IDE__)
-static constexpr bool kIsDebugBuild = GlobalsReturnSelf(false);
-#else
-static constexpr bool kIsDebugBuild = GlobalsReturnSelf(true);
-#endif
-
-#if defined(ART_PGO_INSTRUMENTATION)
-static constexpr bool kIsPGOInstrumentation = true;
-#else
-static constexpr bool kIsPGOInstrumentation = false;
-#endif
-
-// ART_TARGET - Defined for target builds of ART.
-// ART_TARGET_LINUX - Defined for target Linux builds of ART.
-// ART_TARGET_ANDROID - Defined for target Android builds of ART.
-// Note: Either ART_TARGET_LINUX or ART_TARGET_ANDROID need to be set when ART_TARGET is set.
-// Note: When ART_TARGET_LINUX is defined mem_map.h will not be using Ashmem for memory mappings
-// (usually only available on Android kernels).
-#if defined(ART_TARGET)
-// Useful in conditionals where ART_TARGET isn't.
-static constexpr bool kIsTargetBuild = true;
-# if defined(ART_TARGET_LINUX)
-static constexpr bool kIsTargetLinux = true;
-# elif defined(ART_TARGET_ANDROID)
-static constexpr bool kIsTargetLinux = false;
-# else
-# error "Either ART_TARGET_LINUX or ART_TARGET_ANDROID needs to be defined for target builds."
-# endif
-#else
-static constexpr bool kIsTargetBuild = false;
-# if defined(ART_TARGET_LINUX)
-# error "ART_TARGET_LINUX defined for host build."
-# elif defined(ART_TARGET_ANDROID)
-# error "ART_TARGET_ANDROID defined for host build."
-# else
-static constexpr bool kIsTargetLinux = false;
-# endif
-#endif
-
-// Additional statically-linked ART binaries (dex2oats, oatdumps, etc.) are
-// always available on the host
-#if !defined(ART_TARGET)
-static constexpr bool kHostStaticBuildEnabled = true;
-#else
-static constexpr bool kHostStaticBuildEnabled = false;
-#endif
-
-// Garbage collector constants.
-static constexpr bool kMovingCollector = true;
-static constexpr bool kMarkCompactSupport = false && kMovingCollector;
-// True if we allow moving classes.
-static constexpr bool kMovingClasses = !kMarkCompactSupport;
-
-// If true, enable the tlab allocator by default.
-#ifdef ART_USE_TLAB
-static constexpr bool kUseTlab = true;
-#else
-static constexpr bool kUseTlab = false;
-#endif
-
-// Kinds of tracing clocks.
-enum class TraceClockSource {
- kThreadCpu,
- kWall,
- kDual, // Both wall and thread CPU clocks.
-};
-
-#if defined(__linux__)
-static constexpr TraceClockSource kDefaultTraceClockSource = TraceClockSource::kDual;
-#else
-static constexpr TraceClockSource kDefaultTraceClockSource = TraceClockSource::kWall;
-#endif
-
-static constexpr bool kDefaultMustRelocate = true;
-
-// Size of a heap reference.
-static constexpr size_t kHeapReferenceSize = sizeof(uint32_t);
-
-} // namespace art
+// TODO: remove this file in favor of libartbase/base/globals.h
+#include "base/globals.h"
#endif // ART_RUNTIME_GLOBALS_H_
diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h
index d7e5e18..e0519a0 100644
--- a/runtime/hidden_api.h
+++ b/runtime/hidden_api.h
@@ -17,7 +17,7 @@
#ifndef ART_RUNTIME_HIDDEN_API_H_
#define ART_RUNTIME_HIDDEN_API_H_
-#include "hidden_api_access_flags.h"
+#include "dex/hidden_api_access_flags.h"
#include "reflection.h"
#include "runtime.h"
diff --git a/runtime/hidden_api_access_flags.h b/runtime/hidden_api_access_flags.h
deleted file mode 100644
index 6a88c12..0000000
--- a/runtime/hidden_api_access_flags.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2018 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_RUNTIME_HIDDEN_API_ACCESS_FLAGS_H_
-#define ART_RUNTIME_HIDDEN_API_ACCESS_FLAGS_H_
-
-#include "base/bit_utils.h"
-#include "dex/modifiers.h"
-
-namespace art {
-
-/* This class is used for encoding and decoding access flags of class members
- * from the boot class path. These access flags might contain additional two bits
- * of information on whether the given class member should be hidden from apps
- * and under what circumstances.
- *
- * The encoding is different inside DexFile, where we are concerned with size,
- * and at runtime where we want to optimize for speed of access. The class
- * provides helper functions to decode/encode both of them.
- *
- * Encoding in DexFile
- * ===================
- *
- * First bit is encoded as inversion of visibility flags (public/private/protected).
- * At most one can be set for any given class member. If two or three are set,
- * this is interpreted as the first bit being set and actual visibility flags
- * being the complement of the encoded flags.
- *
- * Second bit is either encoded as bit 5 for fields and non-native methods, where
- * it carries no other meaning. If a method is native (bit 8 set), bit 9 is used.
- *
- * Bits were selected so that they never increase the length of unsigned LEB-128
- * encoding of the access flags.
- *
- * Encoding at runtime
- * ===================
- *
- * Two bits are set aside in the uint32_t access flags in the intrinsics ordinal
- * space (thus intrinsics need to be special-cased). These are two consecutive
- * bits and they are directly used to store the integer value of the ApiList
- * enum values.
- *
- */
-class HiddenApiAccessFlags {
- public:
- enum ApiList {
- kWhitelist = 0,
- kLightGreylist,
- kDarkGreylist,
- kBlacklist,
- };
-
- static ALWAYS_INLINE ApiList DecodeFromDex(uint32_t dex_access_flags) {
- DexHiddenAccessFlags flags(dex_access_flags);
- uint32_t int_value = (flags.IsFirstBitSet() ? 1 : 0) + (flags.IsSecondBitSet() ? 2 : 0);
- return static_cast<ApiList>(int_value);
- }
-
- static ALWAYS_INLINE uint32_t RemoveFromDex(uint32_t dex_access_flags) {
- DexHiddenAccessFlags flags(dex_access_flags);
- flags.SetFirstBit(false);
- flags.SetSecondBit(false);
- return flags.GetEncoding();
- }
-
- static ALWAYS_INLINE uint32_t EncodeForDex(uint32_t dex_access_flags, ApiList value) {
- DexHiddenAccessFlags flags(RemoveFromDex(dex_access_flags));
- uint32_t int_value = static_cast<uint32_t>(value);
- flags.SetFirstBit((int_value & 1) != 0);
- flags.SetSecondBit((int_value & 2) != 0);
- return flags.GetEncoding();
- }
-
- static ALWAYS_INLINE ApiList DecodeFromRuntime(uint32_t runtime_access_flags) {
- if ((runtime_access_flags & kAccIntrinsic) != 0) {
- return kWhitelist;
- } else {
- uint32_t int_value = (runtime_access_flags & kAccHiddenApiBits) >> kAccFlagsShift;
- return static_cast<ApiList>(int_value);
- }
- }
-
- static ALWAYS_INLINE uint32_t EncodeForRuntime(uint32_t runtime_access_flags, ApiList value) {
- CHECK_EQ(runtime_access_flags & kAccIntrinsic, 0u);
-
- uint32_t hidden_api_flags = static_cast<uint32_t>(value) << kAccFlagsShift;
- CHECK_EQ(hidden_api_flags & ~kAccHiddenApiBits, 0u);
-
- runtime_access_flags &= ~kAccHiddenApiBits;
- return runtime_access_flags | hidden_api_flags;
- }
-
- private:
- static const int kAccFlagsShift = CTZ(kAccHiddenApiBits);
- static_assert(IsPowerOfTwo((kAccHiddenApiBits >> kAccFlagsShift) + 1),
- "kAccHiddenApiBits are not continuous");
-
- struct DexHiddenAccessFlags {
- explicit DexHiddenAccessFlags(uint32_t access_flags) : access_flags_(access_flags) {}
-
- ALWAYS_INLINE uint32_t GetSecondFlag() {
- return ((access_flags_ & kAccNative) != 0) ? kAccDexHiddenBitNative : kAccDexHiddenBit;
- }
-
- ALWAYS_INLINE bool IsFirstBitSet() {
- static_assert(IsPowerOfTwo(0u), "Following statement checks if *at most* one bit is set");
- return !IsPowerOfTwo(access_flags_ & kAccVisibilityFlags);
- }
-
- ALWAYS_INLINE void SetFirstBit(bool value) {
- if (IsFirstBitSet() != value) {
- access_flags_ ^= kAccVisibilityFlags;
- }
- }
-
- ALWAYS_INLINE bool IsSecondBitSet() {
- return (access_flags_ & GetSecondFlag()) != 0;
- }
-
- ALWAYS_INLINE void SetSecondBit(bool value) {
- if (value) {
- access_flags_ |= GetSecondFlag();
- } else {
- access_flags_ &= ~GetSecondFlag();
- }
- }
-
- ALWAYS_INLINE uint32_t GetEncoding() const {
- return access_flags_;
- }
-
- uint32_t access_flags_;
- };
-};
-
-inline std::ostream& operator<<(std::ostream& os, HiddenApiAccessFlags::ApiList value) {
- switch (value) {
- case HiddenApiAccessFlags::kWhitelist:
- os << "whitelist";
- break;
- case HiddenApiAccessFlags::kLightGreylist:
- os << "light greylist";
- break;
- case HiddenApiAccessFlags::kDarkGreylist:
- os << "dark greylist";
- break;
- case HiddenApiAccessFlags::kBlacklist:
- os << "blacklist";
- break;
- }
- return os;
-}
-
-} // namespace art
-
-
-#endif // ART_RUNTIME_HIDDEN_API_ACCESS_FLAGS_H_
diff --git a/runtime/hprof/hprof.cc b/runtime/hprof/hprof.cc
index af9fbcd..52ee516 100644
--- a/runtime/hprof/hprof.cc
+++ b/runtime/hprof/hprof.cc
@@ -44,6 +44,7 @@
#include "base/array_ref.h"
#include "base/macros.h"
#include "base/mutex.h"
+#include "base/safe_map.h"
#include "base/time_utils.h"
#include "base/unix_file/fd_file.h"
#include "class_linker.h"
@@ -64,7 +65,6 @@
#include "mirror/class.h"
#include "mirror/object-refvisitor-inl.h"
#include "os.h"
-#include "safe_map.h"
#include "scoped_thread_state_change-inl.h"
#include "thread_list.h"
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 46b3f8d..8e7a638 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -25,8 +25,8 @@
#include "base/enums.h"
#include "base/macros.h"
#include "base/mutex.h"
+#include "base/safe_map.h"
#include "gc_root.h"
-#include "safe_map.h"
namespace art {
namespace mirror {
diff --git a/runtime/jdwp/object_registry.h b/runtime/jdwp/object_registry.h
index 26869b6..1728a73 100644
--- a/runtime/jdwp/object_registry.h
+++ b/runtime/jdwp/object_registry.h
@@ -23,10 +23,10 @@
#include <map>
#include "base/casts.h"
+#include "base/safe_map.h"
#include "handle.h"
#include "jdwp/jdwp.h"
#include "obj_ptr.h"
-#include "safe_map.h"
namespace art {
diff --git a/runtime/jit/jit_code_cache.h b/runtime/jit/jit_code_cache.h
index fc011dd..0d1311f 100644
--- a/runtime/jit/jit_code_cache.h
+++ b/runtime/jit/jit_code_cache.h
@@ -24,9 +24,9 @@
#include "base/histogram-inl.h"
#include "base/macros.h"
#include "base/mutex.h"
+#include "base/safe_map.h"
#include "gc_root.h"
#include "method_reference.h"
-#include "safe_map.h"
namespace art {
diff --git a/runtime/jit/profile_compilation_info.cc b/runtime/jit/profile_compilation_info.cc
index 21caa42..7be29c9 100644
--- a/runtime/jit/profile_compilation_info.cc
+++ b/runtime/jit/profile_compilation_info.cc
@@ -37,6 +37,7 @@
#include "base/file_utils.h"
#include "base/logging.h" // For VLOG.
#include "base/mutex.h"
+#include "base/safe_map.h"
#include "base/scoped_flock.h"
#include "base/stl_util.h"
#include "base/systrace.h"
@@ -45,7 +46,6 @@
#include "dex/dex_file_loader.h"
#include "jit/profiling_info.h"
#include "os.h"
-#include "safe_map.h"
#include "utils.h"
#include "zip_archive.h"
diff --git a/runtime/jit/profile_compilation_info.h b/runtime/jit/profile_compilation_info.h
index 3213c85..7e09b6b 100644
--- a/runtime/jit/profile_compilation_info.h
+++ b/runtime/jit/profile_compilation_info.h
@@ -23,13 +23,13 @@
#include "atomic.h"
#include "base/arena_containers.h"
#include "base/arena_object.h"
+#include "base/safe_map.h"
#include "bit_memory_region.h"
#include "dex/dex_cache_resolved_classes.h"
#include "dex/dex_file.h"
#include "dex/dex_file_types.h"
#include "method_reference.h"
#include "mem_map.h"
-#include "safe_map.h"
#include "type_reference.h"
namespace art {
diff --git a/runtime/jit/profile_saver.h b/runtime/jit/profile_saver.h
index ce8233b..e5cd11b 100644
--- a/runtime/jit/profile_saver.h
+++ b/runtime/jit/profile_saver.h
@@ -18,11 +18,11 @@
#define ART_RUNTIME_JIT_PROFILE_SAVER_H_
#include "base/mutex.h"
+#include "base/safe_map.h"
#include "jit_code_cache.h"
#include "method_reference.h"
#include "profile_compilation_info.h"
#include "profile_saver_options.h"
-#include "safe_map.h"
namespace art {
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index cd4d954..4c73d87 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -30,6 +30,7 @@
#include "base/enums.h"
#include "base/logging.h" // For VLOG.
#include "base/mutex.h"
+#include "base/safe_map.h"
#include "base/stl_util.h"
#include "class_linker-inl.h"
#include "dex/dex_file-inl.h"
@@ -55,7 +56,6 @@
#include "parsed_options.h"
#include "reflection.h"
#include "runtime.h"
-#include "safe_map.h"
#include "scoped_thread_state_change-inl.h"
#include "thread.h"
#include "well_known_classes.h"
diff --git a/runtime/leb128.h b/runtime/leb128.h
deleted file mode 100644
index 07eadc1..0000000
--- a/runtime/leb128.h
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * Copyright (C) 2011 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_RUNTIME_LEB128_H_
-#define ART_RUNTIME_LEB128_H_
-
-#include <vector>
-
-#include <android-base/logging.h>
-
-#include "base/bit_utils.h"
-#include "base/macros.h"
-#include "globals.h"
-
-namespace art {
-
-// Reads an unsigned LEB128 value, updating the given pointer to point
-// just past the end of the read value. This function tolerates
-// non-zero high-order bits in the fifth encoded byte.
-static inline uint32_t DecodeUnsignedLeb128(const uint8_t** data) {
- const uint8_t* ptr = *data;
- int result = *(ptr++);
- if (UNLIKELY(result > 0x7f)) {
- int cur = *(ptr++);
- result = (result & 0x7f) | ((cur & 0x7f) << 7);
- if (cur > 0x7f) {
- cur = *(ptr++);
- result |= (cur & 0x7f) << 14;
- if (cur > 0x7f) {
- cur = *(ptr++);
- result |= (cur & 0x7f) << 21;
- if (cur > 0x7f) {
- // Note: We don't check to see if cur is out of range here,
- // meaning we tolerate garbage in the four high-order bits.
- cur = *(ptr++);
- result |= cur << 28;
- }
- }
- }
- }
- *data = ptr;
- return static_cast<uint32_t>(result);
-}
-
-static inline uint32_t DecodeUnsignedLeb128WithoutMovingCursor(const uint8_t* data) {
- return DecodeUnsignedLeb128(&data);
-}
-
-static inline bool DecodeUnsignedLeb128Checked(const uint8_t** data,
- const void* end,
- uint32_t* out) {
- const uint8_t* ptr = *data;
- if (ptr >= end) {
- return false;
- }
- int result = *(ptr++);
- if (UNLIKELY(result > 0x7f)) {
- if (ptr >= end) {
- return false;
- }
- int cur = *(ptr++);
- result = (result & 0x7f) | ((cur & 0x7f) << 7);
- if (cur > 0x7f) {
- if (ptr >= end) {
- return false;
- }
- cur = *(ptr++);
- result |= (cur & 0x7f) << 14;
- if (cur > 0x7f) {
- if (ptr >= end) {
- return false;
- }
- cur = *(ptr++);
- result |= (cur & 0x7f) << 21;
- if (cur > 0x7f) {
- if (ptr >= end) {
- return false;
- }
- // Note: We don't check to see if cur is out of range here,
- // meaning we tolerate garbage in the four high-order bits.
- cur = *(ptr++);
- result |= cur << 28;
- }
- }
- }
- }
- *data = ptr;
- *out = static_cast<uint32_t>(result);
- return true;
-}
-
-// Reads an unsigned LEB128 + 1 value. updating the given pointer to point
-// just past the end of the read value. This function tolerates
-// non-zero high-order bits in the fifth encoded byte.
-// It is possible for this function to return -1.
-static inline int32_t DecodeUnsignedLeb128P1(const uint8_t** data) {
- return DecodeUnsignedLeb128(data) - 1;
-}
-
-// Reads a signed LEB128 value, updating the given pointer to point
-// just past the end of the read value. This function tolerates
-// non-zero high-order bits in the fifth encoded byte.
-static inline int32_t DecodeSignedLeb128(const uint8_t** data) {
- const uint8_t* ptr = *data;
- int32_t result = *(ptr++);
- if (result <= 0x7f) {
- result = (result << 25) >> 25;
- } else {
- int cur = *(ptr++);
- result = (result & 0x7f) | ((cur & 0x7f) << 7);
- if (cur <= 0x7f) {
- result = (result << 18) >> 18;
- } else {
- cur = *(ptr++);
- result |= (cur & 0x7f) << 14;
- if (cur <= 0x7f) {
- result = (result << 11) >> 11;
- } else {
- cur = *(ptr++);
- result |= (cur & 0x7f) << 21;
- if (cur <= 0x7f) {
- result = (result << 4) >> 4;
- } else {
- // Note: We don't check to see if cur is out of range here,
- // meaning we tolerate garbage in the four high-order bits.
- cur = *(ptr++);
- result |= cur << 28;
- }
- }
- }
- }
- *data = ptr;
- return result;
-}
-
-static inline bool DecodeSignedLeb128Checked(const uint8_t** data,
- const void* end,
- int32_t* out) {
- const uint8_t* ptr = *data;
- if (ptr >= end) {
- return false;
- }
- int32_t result = *(ptr++);
- if (result <= 0x7f) {
- result = (result << 25) >> 25;
- } else {
- if (ptr >= end) {
- return false;
- }
- int cur = *(ptr++);
- result = (result & 0x7f) | ((cur & 0x7f) << 7);
- if (cur <= 0x7f) {
- result = (result << 18) >> 18;
- } else {
- if (ptr >= end) {
- return false;
- }
- cur = *(ptr++);
- result |= (cur & 0x7f) << 14;
- if (cur <= 0x7f) {
- result = (result << 11) >> 11;
- } else {
- if (ptr >= end) {
- return false;
- }
- cur = *(ptr++);
- result |= (cur & 0x7f) << 21;
- if (cur <= 0x7f) {
- result = (result << 4) >> 4;
- } else {
- if (ptr >= end) {
- return false;
- }
- // Note: We don't check to see if cur is out of range here,
- // meaning we tolerate garbage in the four high-order bits.
- cur = *(ptr++);
- result |= cur << 28;
- }
- }
- }
- }
- *data = ptr;
- *out = static_cast<uint32_t>(result);
- return true;
-}
-
-// Returns the number of bytes needed to encode the value in unsigned LEB128.
-static inline uint32_t UnsignedLeb128Size(uint32_t data) {
- // bits_to_encode = (data != 0) ? 32 - CLZ(x) : 1 // 32 - CLZ(data | 1)
- // bytes = ceil(bits_to_encode / 7.0); // (6 + bits_to_encode) / 7
- uint32_t x = 6 + 32 - CLZ(data | 1U);
- // Division by 7 is done by (x * 37) >> 8 where 37 = ceil(256 / 7).
- // This works for 0 <= x < 256 / (7 * 37 - 256), i.e. 0 <= x <= 85.
- return (x * 37) >> 8;
-}
-
-static inline bool IsLeb128Terminator(const uint8_t* ptr) {
- return *ptr <= 0x7f;
-}
-
-// Returns the first byte of a Leb128 value assuming that:
-// (1) `end_ptr` points to the first byte after the Leb128 value, and
-// (2) there is another Leb128 value before this one.
-template <typename T>
-static inline T* ReverseSearchUnsignedLeb128(T* end_ptr) {
- static_assert(std::is_same<typename std::remove_const<T>::type, uint8_t>::value,
- "T must be a uint8_t");
- T* ptr = end_ptr;
-
- // Move one byte back, check that this is the terminating byte.
- ptr--;
- DCHECK(IsLeb128Terminator(ptr));
-
- // Keep moving back while the previous byte is not a terminating byte.
- // Fail after reading five bytes in case there isn't another Leb128 value
- // before this one.
- while (!IsLeb128Terminator(ptr - 1)) {
- ptr--;
- DCHECK_LE(static_cast<ptrdiff_t>(end_ptr - ptr), 5);
- }
-
- return ptr;
-}
-
-// Returns the number of bytes needed to encode the value in unsigned LEB128.
-static inline uint32_t SignedLeb128Size(int32_t data) {
- // Like UnsignedLeb128Size(), but we need one bit beyond the highest bit that differs from sign.
- data = data ^ (data >> 31);
- uint32_t x = 1 /* we need to encode the sign bit */ + 6 + 32 - CLZ(data | 1U);
- return (x * 37) >> 8;
-}
-
-static inline uint8_t* EncodeUnsignedLeb128(uint8_t* dest, uint32_t value) {
- uint8_t out = value & 0x7f;
- value >>= 7;
- while (value != 0) {
- *dest++ = out | 0x80;
- out = value & 0x7f;
- value >>= 7;
- }
- *dest++ = out;
- return dest;
-}
-
-template <typename Vector>
-static inline void EncodeUnsignedLeb128(Vector* dest, uint32_t value) {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
- uint8_t out = value & 0x7f;
- value >>= 7;
- while (value != 0) {
- dest->push_back(out | 0x80);
- out = value & 0x7f;
- value >>= 7;
- }
- dest->push_back(out);
-}
-
-// Overwrite encoded Leb128 with a new value. The new value must be less than
-// or equal to the old value to ensure that it fits the allocated space.
-static inline void UpdateUnsignedLeb128(uint8_t* dest, uint32_t value) {
- const uint8_t* old_end = dest;
- uint32_t old_value = DecodeUnsignedLeb128(&old_end);
- DCHECK_LE(UnsignedLeb128Size(value), UnsignedLeb128Size(old_value));
- for (uint8_t* end = EncodeUnsignedLeb128(dest, value); end < old_end; end++) {
- // Use longer encoding than necessary to fill the allocated space.
- end[-1] |= 0x80;
- end[0] = 0;
- }
-}
-
-static inline uint8_t* EncodeSignedLeb128(uint8_t* dest, int32_t value) {
- uint32_t extra_bits = static_cast<uint32_t>(value ^ (value >> 31)) >> 6;
- uint8_t out = value & 0x7f;
- while (extra_bits != 0u) {
- *dest++ = out | 0x80;
- value >>= 7;
- out = value & 0x7f;
- extra_bits >>= 7;
- }
- *dest++ = out;
- return dest;
-}
-
-template<typename Vector>
-static inline void EncodeSignedLeb128(Vector* dest, int32_t value) {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
- uint32_t extra_bits = static_cast<uint32_t>(value ^ (value >> 31)) >> 6;
- uint8_t out = value & 0x7f;
- while (extra_bits != 0u) {
- dest->push_back(out | 0x80);
- value >>= 7;
- out = value & 0x7f;
- extra_bits >>= 7;
- }
- dest->push_back(out);
-}
-
-// An encoder that pushes int32_t/uint32_t data onto the given std::vector.
-template <typename Vector = std::vector<uint8_t>>
-class Leb128Encoder {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- public:
- explicit Leb128Encoder(Vector* data) : data_(data) {
- DCHECK(data != nullptr);
- }
-
- void Reserve(uint32_t size) {
- data_->reserve(size);
- }
-
- void PushBackUnsigned(uint32_t value) {
- EncodeUnsignedLeb128(data_, value);
- }
-
- template<typename It>
- void InsertBackUnsigned(It cur, It end) {
- for (; cur != end; ++cur) {
- PushBackUnsigned(*cur);
- }
- }
-
- void PushBackSigned(int32_t value) {
- EncodeSignedLeb128(data_, value);
- }
-
- template<typename It>
- void InsertBackSigned(It cur, It end) {
- for (; cur != end; ++cur) {
- PushBackSigned(*cur);
- }
- }
-
- const Vector& GetData() const {
- return *data_;
- }
-
- protected:
- Vector* const data_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Leb128Encoder);
-};
-
-// An encoder with an API similar to vector<uint32_t> where the data is captured in ULEB128 format.
-template <typename Vector = std::vector<uint8_t>>
-class Leb128EncodingVector FINAL : private Vector,
- public Leb128Encoder<Vector> {
- static_assert(std::is_same<typename Vector::value_type, uint8_t>::value, "Invalid value type");
-
- public:
- Leb128EncodingVector() : Leb128Encoder<Vector>(this) { }
-
- explicit Leb128EncodingVector(const typename Vector::allocator_type& alloc)
- : Vector(alloc),
- Leb128Encoder<Vector>(this) { }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Leb128EncodingVector);
-};
-
-} // namespace art
-
-#endif // ART_RUNTIME_LEB128_H_
diff --git a/runtime/leb128_test.cc b/runtime/leb128_test.cc
deleted file mode 100644
index 747fc19..0000000
--- a/runtime/leb128_test.cc
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-#include "leb128.h"
-
-#include "gtest/gtest.h"
-
-#include "base/histogram-inl.h"
-#include "base/time_utils.h"
-
-namespace art {
-
-struct DecodeUnsignedLeb128TestCase {
- uint32_t decoded;
- uint8_t leb128_data[5];
-};
-
-static DecodeUnsignedLeb128TestCase uleb128_tests[] = {
- {0, {0, 0, 0, 0, 0}},
- {1, {1, 0, 0, 0, 0}},
- {0x7F, {0x7F, 0, 0, 0, 0}},
- {0x80, {0x80, 1, 0, 0, 0}},
- {0x81, {0x81, 1, 0, 0, 0}},
- {0xFF, {0xFF, 1, 0, 0, 0}},
- {0x4000, {0x80, 0x80, 1, 0, 0}},
- {0x4001, {0x81, 0x80, 1, 0, 0}},
- {0x4081, {0x81, 0x81, 1, 0, 0}},
- {0x0FFFFFFF, {0xFF, 0xFF, 0xFF, 0x7F, 0}},
- {0xFFFFFFFF, {0xFF, 0xFF, 0xFF, 0xFF, 0xF}},
-};
-
-struct DecodeSignedLeb128TestCase {
- int32_t decoded;
- uint8_t leb128_data[5];
-};
-
-static DecodeSignedLeb128TestCase sleb128_tests[] = {
- {0, {0, 0, 0, 0, 0}},
- {1, {1, 0, 0, 0, 0}},
- {0x3F, {0x3F, 0, 0, 0, 0}},
- {0x40, {0xC0, 0 /* sign bit */, 0, 0, 0}},
- {0x41, {0xC1, 0 /* sign bit */, 0, 0, 0}},
- {0x80, {0x80, 1, 0, 0, 0}},
- {0xFF, {0xFF, 1, 0, 0, 0}},
- {0x1FFF, {0xFF, 0x3F, 0, 0, 0}},
- {0x2000, {0x80, 0xC0, 0 /* sign bit */, 0, 0}},
- {0x2001, {0x81, 0xC0, 0 /* sign bit */, 0, 0}},
- {0x2081, {0x81, 0xC1, 0 /* sign bit */, 0, 0}},
- {0x4000, {0x80, 0x80, 1, 0, 0}},
- {0x0FFFFF, {0xFF, 0xFF, 0x3F, 0, 0}},
- {0x100000, {0x80, 0x80, 0xC0, 0 /* sign bit */, 0}},
- {0x100001, {0x81, 0x80, 0xC0, 0 /* sign bit */, 0}},
- {0x100081, {0x81, 0x81, 0xC0, 0 /* sign bit */, 0}},
- {0x104081, {0x81, 0x81, 0xC1, 0 /* sign bit */, 0}},
- {0x200000, {0x80, 0x80, 0x80, 1, 0}},
- {0x7FFFFFF, {0xFF, 0xFF, 0xFF, 0x3F, 0}},
- {0x8000000, {0x80, 0x80, 0x80, 0xC0, 0 /* sign bit */}},
- {0x8000001, {0x81, 0x80, 0x80, 0xC0, 0 /* sign bit */}},
- {0x8000081, {0x81, 0x81, 0x80, 0xC0, 0 /* sign bit */}},
- {0x8004081, {0x81, 0x81, 0x81, 0xC0, 0 /* sign bit */}},
- {0x8204081, {0x81, 0x81, 0x81, 0xC1, 0 /* sign bit */}},
- {0x0FFFFFFF, {0xFF, 0xFF, 0xFF, 0xFF, 0 /* sign bit */}},
- {0x10000000, {0x80, 0x80, 0x80, 0x80, 1}},
- {0x7FFFFFFF, {0xFF, 0xFF, 0xFF, 0xFF, 0x7}},
- {-1, {0x7F, 0, 0, 0, 0}},
- {-2, {0x7E, 0, 0, 0, 0}},
- {-0x3F, {0x41, 0, 0, 0, 0}},
- {-0x40, {0x40, 0, 0, 0, 0}},
- {-0x41, {0xBF, 0x7F, 0, 0, 0}},
- {-0x80, {0x80, 0x7F, 0, 0, 0}},
- {-0x81, {0xFF, 0x7E, 0, 0, 0}},
- {-0x00002000, {0x80, 0x40, 0, 0, 0}},
- {-0x00002001, {0xFF, 0xBF, 0x7F, 0, 0}},
- {-0x00100000, {0x80, 0x80, 0x40, 0, 0}},
- {-0x00100001, {0xFF, 0xFF, 0xBF, 0x7F, 0}},
- {-0x08000000, {0x80, 0x80, 0x80, 0x40, 0}},
- {-0x08000001, {0xFF, 0xFF, 0xFF, 0xBF, 0x7F}},
- {-0x20000000, {0x80, 0x80, 0x80, 0x80, 0x7E}},
- {static_cast<int32_t>(0x80000000), {0x80, 0x80, 0x80, 0x80, 0x78}},
-};
-
-TEST(Leb128Test, UnsignedSinglesVector) {
- // Test individual encodings.
- for (size_t i = 0; i < arraysize(uleb128_tests); ++i) {
- Leb128EncodingVector<> builder;
- builder.PushBackUnsigned(uleb128_tests[i].decoded);
- EXPECT_EQ(UnsignedLeb128Size(uleb128_tests[i].decoded), builder.GetData().size());
- const uint8_t* data_ptr = &uleb128_tests[i].leb128_data[0];
- const uint8_t* encoded_data_ptr = &builder.GetData()[0];
- for (size_t j = 0; j < 5; ++j) {
- if (j < builder.GetData().size()) {
- EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j;
- } else {
- EXPECT_EQ(data_ptr[j], 0U) << " i = " << i << " j = " << j;
- }
- }
- EXPECT_EQ(DecodeUnsignedLeb128(&data_ptr), uleb128_tests[i].decoded) << " i = " << i;
- }
-}
-
-TEST(Leb128Test, UnsignedSingles) {
- // Test individual encodings.
- for (size_t i = 0; i < arraysize(uleb128_tests); ++i) {
- uint8_t encoded_data[5];
- uint8_t* end = EncodeUnsignedLeb128(encoded_data, uleb128_tests[i].decoded);
- size_t data_size = static_cast<size_t>(end - encoded_data);
- EXPECT_EQ(UnsignedLeb128Size(uleb128_tests[i].decoded), data_size);
- const uint8_t* data_ptr = &uleb128_tests[i].leb128_data[0];
- for (size_t j = 0; j < 5; ++j) {
- if (j < data_size) {
- EXPECT_EQ(data_ptr[j], encoded_data[j]) << " i = " << i << " j = " << j;
- } else {
- EXPECT_EQ(data_ptr[j], 0U) << " i = " << i << " j = " << j;
- }
- }
- EXPECT_EQ(DecodeUnsignedLeb128(&data_ptr), uleb128_tests[i].decoded) << " i = " << i;
- }
-}
-
-TEST(Leb128Test, UnsignedStreamVector) {
- // Encode a number of entries.
- Leb128EncodingVector<> builder;
- for (size_t i = 0; i < arraysize(uleb128_tests); ++i) {
- builder.PushBackUnsigned(uleb128_tests[i].decoded);
- }
- const uint8_t* encoded_data_ptr = &builder.GetData()[0];
- for (size_t i = 0; i < arraysize(uleb128_tests); ++i) {
- const uint8_t* data_ptr = &uleb128_tests[i].leb128_data[0];
- for (size_t j = 0; j < UnsignedLeb128Size(uleb128_tests[i].decoded); ++j) {
- EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j;
- }
- for (size_t j = UnsignedLeb128Size(uleb128_tests[i].decoded); j < 5; ++j) {
- EXPECT_EQ(data_ptr[j], 0) << " i = " << i << " j = " << j;
- }
- EXPECT_EQ(DecodeUnsignedLeb128(&encoded_data_ptr), uleb128_tests[i].decoded) << " i = " << i;
- }
- EXPECT_EQ(builder.GetData().size(),
- static_cast<size_t>(encoded_data_ptr - &builder.GetData()[0]));
-}
-
-TEST(Leb128Test, UnsignedStream) {
- // Encode a number of entries.
- uint8_t encoded_data[5 * arraysize(uleb128_tests)];
- uint8_t* end = encoded_data;
- for (size_t i = 0; i < arraysize(uleb128_tests); ++i) {
- end = EncodeUnsignedLeb128(end, uleb128_tests[i].decoded);
- }
- size_t data_size = static_cast<size_t>(end - encoded_data);
- const uint8_t* encoded_data_ptr = encoded_data;
- for (size_t i = 0; i < arraysize(uleb128_tests); ++i) {
- const uint8_t* data_ptr = &uleb128_tests[i].leb128_data[0];
- for (size_t j = 0; j < UnsignedLeb128Size(uleb128_tests[i].decoded); ++j) {
- EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j;
- }
- for (size_t j = UnsignedLeb128Size(uleb128_tests[i].decoded); j < 5; ++j) {
- EXPECT_EQ(data_ptr[j], 0) << " i = " << i << " j = " << j;
- }
- EXPECT_EQ(DecodeUnsignedLeb128(&encoded_data_ptr), uleb128_tests[i].decoded) << " i = " << i;
- }
- EXPECT_EQ(data_size, static_cast<size_t>(encoded_data_ptr - encoded_data));
-}
-
-TEST(Leb128Test, SignedSinglesVector) {
- // Test individual encodings.
- for (size_t i = 0; i < arraysize(sleb128_tests); ++i) {
- Leb128EncodingVector<> builder;
- builder.PushBackSigned(sleb128_tests[i].decoded);
- EXPECT_EQ(SignedLeb128Size(sleb128_tests[i].decoded), builder.GetData().size());
- const uint8_t* data_ptr = &sleb128_tests[i].leb128_data[0];
- const uint8_t* encoded_data_ptr = &builder.GetData()[0];
- for (size_t j = 0; j < 5; ++j) {
- if (j < builder.GetData().size()) {
- EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j;
- } else {
- EXPECT_EQ(data_ptr[j], 0U) << " i = " << i << " j = " << j;
- }
- }
- EXPECT_EQ(DecodeSignedLeb128(&data_ptr), sleb128_tests[i].decoded) << " i = " << i;
- }
-}
-
-TEST(Leb128Test, SignedSingles) {
- // Test individual encodings.
- for (size_t i = 0; i < arraysize(sleb128_tests); ++i) {
- uint8_t encoded_data[5];
- uint8_t* end = EncodeSignedLeb128(encoded_data, sleb128_tests[i].decoded);
- size_t data_size = static_cast<size_t>(end - encoded_data);
- EXPECT_EQ(SignedLeb128Size(sleb128_tests[i].decoded), data_size);
- const uint8_t* data_ptr = &sleb128_tests[i].leb128_data[0];
- for (size_t j = 0; j < 5; ++j) {
- if (j < data_size) {
- EXPECT_EQ(data_ptr[j], encoded_data[j]) << " i = " << i << " j = " << j;
- } else {
- EXPECT_EQ(data_ptr[j], 0U) << " i = " << i << " j = " << j;
- }
- }
- EXPECT_EQ(DecodeSignedLeb128(&data_ptr), sleb128_tests[i].decoded) << " i = " << i;
- }
-}
-
-TEST(Leb128Test, SignedStreamVector) {
- // Encode a number of entries.
- Leb128EncodingVector<> builder;
- for (size_t i = 0; i < arraysize(sleb128_tests); ++i) {
- builder.PushBackSigned(sleb128_tests[i].decoded);
- }
- const uint8_t* encoded_data_ptr = &builder.GetData()[0];
- for (size_t i = 0; i < arraysize(sleb128_tests); ++i) {
- const uint8_t* data_ptr = &sleb128_tests[i].leb128_data[0];
- for (size_t j = 0; j < SignedLeb128Size(sleb128_tests[i].decoded); ++j) {
- EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j;
- }
- for (size_t j = SignedLeb128Size(sleb128_tests[i].decoded); j < 5; ++j) {
- EXPECT_EQ(data_ptr[j], 0) << " i = " << i << " j = " << j;
- }
- EXPECT_EQ(DecodeSignedLeb128(&encoded_data_ptr), sleb128_tests[i].decoded) << " i = " << i;
- }
- EXPECT_EQ(builder.GetData().size(),
- static_cast<size_t>(encoded_data_ptr - &builder.GetData()[0]));
-}
-
-TEST(Leb128Test, SignedStream) {
- // Encode a number of entries.
- uint8_t encoded_data[5 * arraysize(sleb128_tests)];
- uint8_t* end = encoded_data;
- for (size_t i = 0; i < arraysize(sleb128_tests); ++i) {
- end = EncodeSignedLeb128(end, sleb128_tests[i].decoded);
- }
- size_t data_size = static_cast<size_t>(end - encoded_data);
- const uint8_t* encoded_data_ptr = encoded_data;
- for (size_t i = 0; i < arraysize(sleb128_tests); ++i) {
- const uint8_t* data_ptr = &sleb128_tests[i].leb128_data[0];
- for (size_t j = 0; j < SignedLeb128Size(sleb128_tests[i].decoded); ++j) {
- EXPECT_EQ(data_ptr[j], encoded_data_ptr[j]) << " i = " << i << " j = " << j;
- }
- for (size_t j = SignedLeb128Size(sleb128_tests[i].decoded); j < 5; ++j) {
- EXPECT_EQ(data_ptr[j], 0) << " i = " << i << " j = " << j;
- }
- EXPECT_EQ(DecodeSignedLeb128(&encoded_data_ptr), sleb128_tests[i].decoded) << " i = " << i;
- }
- EXPECT_EQ(data_size, static_cast<size_t>(encoded_data_ptr - encoded_data));
-}
-
-TEST(Leb128Test, UnsignedUpdate) {
- for (size_t i = 0; i < arraysize(uleb128_tests); ++i) {
- for (size_t j = 0; j < arraysize(uleb128_tests); ++j) {
- uint32_t old_value = uleb128_tests[i].decoded;
- uint32_t new_value = uleb128_tests[j].decoded;
- // We can only make the encoded value smaller.
- if (new_value <= old_value) {
- uint8_t encoded_data[5];
- uint8_t* old_end = EncodeUnsignedLeb128(encoded_data, old_value);
- UpdateUnsignedLeb128(encoded_data, new_value);
- const uint8_t* new_end = encoded_data;
- EXPECT_EQ(DecodeUnsignedLeb128(&new_end), new_value);
- // Even if the new value needs fewer bytes, we should fill the space.
- EXPECT_EQ(new_end, old_end);
- }
- }
- }
-}
-
-TEST(Leb128Test, Speed) {
- std::unique_ptr<Histogram<uint64_t>> enc_hist(new Histogram<uint64_t>("Leb128EncodeSpeedTest", 5));
- std::unique_ptr<Histogram<uint64_t>> dec_hist(new Histogram<uint64_t>("Leb128DecodeSpeedTest", 5));
- Leb128EncodingVector<> builder;
- // Push back 1024 chunks of 1024 values measuring encoding speed.
- uint64_t last_time = NanoTime();
- for (size_t i = 0; i < 1024; i++) {
- for (size_t j = 0; j < 1024; j++) {
- builder.PushBackUnsigned((i * 1024) + j);
- }
- uint64_t cur_time = NanoTime();
- enc_hist->AddValue(cur_time - last_time);
- last_time = cur_time;
- }
- // Verify encoding and measure decode speed.
- const uint8_t* encoded_data_ptr = &builder.GetData()[0];
- last_time = NanoTime();
- for (size_t i = 0; i < 1024; i++) {
- for (size_t j = 0; j < 1024; j++) {
- EXPECT_EQ(DecodeUnsignedLeb128(&encoded_data_ptr), (i * 1024) + j);
- }
- uint64_t cur_time = NanoTime();
- dec_hist->AddValue(cur_time - last_time);
- last_time = cur_time;
- }
-
- Histogram<uint64_t>::CumulativeData enc_data;
- enc_hist->CreateHistogram(&enc_data);
- enc_hist->PrintConfidenceIntervals(std::cout, 0.99, enc_data);
-
- Histogram<uint64_t>::CumulativeData dec_data;
- dec_hist->CreateHistogram(&dec_data);
- dec_hist->PrintConfidenceIntervals(std::cout, 0.99, dec_data);
-}
-
-} // namespace art
diff --git a/runtime/mapping_table.h b/runtime/mapping_table.h
index dcd5f00..6686473 100644
--- a/runtime/mapping_table.h
+++ b/runtime/mapping_table.h
@@ -17,8 +17,8 @@
#ifndef ART_RUNTIME_MAPPING_TABLE_H_
#define ART_RUNTIME_MAPPING_TABLE_H_
+#include "base/leb128.h"
#include "base/logging.h"
-#include "leb128.h"
namespace art {
diff --git a/runtime/method_info.h b/runtime/method_info.h
index 6485af9..fe06256 100644
--- a/runtime/method_info.h
+++ b/runtime/method_info.h
@@ -19,8 +19,8 @@
#include <android-base/logging.h>
+#include "base/leb128.h"
#include "base/macros.h"
-#include "leb128.h"
#include "memory_region.h"
namespace art {
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index b9a31e5..a1d0ff7 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -26,12 +26,12 @@
#include "dex/dex_file.h"
#include "dex/dex_file_types.h"
#include "dex/modifiers.h"
+#include "dex/primitive.h"
#include "gc/allocator_type.h"
#include "gc_root.h"
#include "imtable.h"
#include "object.h"
#include "object_array.h"
-#include "primitive.h"
#include "read_barrier_option.h"
#include "stride_iterator.h"
#include "thread.h"
diff --git a/runtime/mirror/field.h b/runtime/mirror/field.h
index dd09be3..03fd031 100644
--- a/runtime/mirror/field.h
+++ b/runtime/mirror/field.h
@@ -20,10 +20,10 @@
#include "accessible_object.h"
#include "base/enums.h"
#include "dex/modifiers.h"
+#include "dex/primitive.h"
#include "gc_root.h"
#include "obj_ptr.h"
#include "object.h"
-#include "primitive.h"
#include "read_barrier_option.h"
namespace art {
diff --git a/runtime/oat.h b/runtime/oat.h
index af14b3e..292c9d6 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -21,9 +21,9 @@
#include "arch/instruction_set.h"
#include "base/macros.h"
+#include "base/safe_map.h"
#include "compiler_filter.h"
#include "dex/dex_file.h"
-#include "safe_map.h"
namespace art {
diff --git a/runtime/oat_file.h b/runtime/oat_file.h
index 802adc3..255a31b 100644
--- a/runtime/oat_file.h
+++ b/runtime/oat_file.h
@@ -23,7 +23,9 @@
#include "base/array_ref.h"
#include "base/mutex.h"
+#include "base/safe_map.h"
#include "base/stringpiece.h"
+#include "base/tracking_safe_map.h"
#include "class_status.h"
#include "compiler_filter.h"
#include "dex/dex_file.h"
diff --git a/runtime/primitive.cc b/runtime/primitive.cc
deleted file mode 100644
index 6f3571c..0000000
--- a/runtime/primitive.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-#include "primitive.h"
-
-namespace art {
-
-static const char* kTypeNames[] = {
- "PrimNot",
- "PrimBoolean",
- "PrimByte",
- "PrimChar",
- "PrimShort",
- "PrimInt",
- "PrimLong",
- "PrimFloat",
- "PrimDouble",
- "PrimVoid",
-};
-
-static const char* kBoxedDescriptors[] = {
- "Ljava/lang/Object;",
- "Ljava/lang/Boolean;",
- "Ljava/lang/Byte;",
- "Ljava/lang/Character;",
- "Ljava/lang/Short;",
- "Ljava/lang/Integer;",
- "Ljava/lang/Long;",
- "Ljava/lang/Float;",
- "Ljava/lang/Double;",
- "Ljava/lang/Void;",
-};
-
-#define COUNT_OF(x) (sizeof(x) / sizeof((x)[0]))
-
-const char* Primitive::PrettyDescriptor(Primitive::Type type) {
- static_assert(COUNT_OF(kTypeNames) == static_cast<size_t>(Primitive::kPrimLast) + 1,
- "Missing element");
- CHECK(Primitive::kPrimNot <= type && type <= Primitive::kPrimVoid) << static_cast<int>(type);
- return kTypeNames[type];
-}
-
-const char* Primitive::BoxedDescriptor(Primitive::Type type) {
- static_assert(COUNT_OF(kBoxedDescriptors) == static_cast<size_t>(Primitive::kPrimLast) + 1,
- "Missing element");
- CHECK(Primitive::kPrimNot <= type && type <= Primitive::kPrimVoid) << static_cast<int>(type);
- return kBoxedDescriptors[type];
-}
-
-std::ostream& operator<<(std::ostream& os, Primitive::Type type) {
- uint32_t int_type = static_cast<uint32_t>(type);
- if (type <= Primitive::kPrimLast) {
- os << kTypeNames[int_type];
- } else {
- os << "Type[" << int_type << "]";
- }
- return os;
-}
-
-} // namespace art
diff --git a/runtime/primitive.h b/runtime/primitive.h
deleted file mode 100644
index 38ad68d..0000000
--- a/runtime/primitive.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2011 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_RUNTIME_PRIMITIVE_H_
-#define ART_RUNTIME_PRIMITIVE_H_
-
-#include <sys/types.h>
-
-#include <android-base/logging.h>
-
-#include "base/macros.h"
-
-namespace art {
-
-static constexpr size_t kObjectReferenceSize = 4;
-
-constexpr size_t ComponentSizeShiftWidth(size_t component_size) {
- return component_size == 1u ? 0u :
- component_size == 2u ? 1u :
- component_size == 4u ? 2u :
- component_size == 8u ? 3u : 0u;
-}
-
-class Primitive {
- public:
- enum Type {
- kPrimNot = 0,
- kPrimBoolean,
- kPrimByte,
- kPrimChar,
- kPrimShort,
- kPrimInt,
- kPrimLong,
- kPrimFloat,
- kPrimDouble,
- kPrimVoid,
- kPrimLast = kPrimVoid
- };
-
- static constexpr Type GetType(char type) {
- switch (type) {
- case 'B':
- return kPrimByte;
- case 'C':
- return kPrimChar;
- case 'D':
- return kPrimDouble;
- case 'F':
- return kPrimFloat;
- case 'I':
- return kPrimInt;
- case 'J':
- return kPrimLong;
- case 'S':
- return kPrimShort;
- case 'Z':
- return kPrimBoolean;
- case 'V':
- return kPrimVoid;
- default:
- return kPrimNot;
- }
- }
-
- static constexpr size_t ComponentSizeShift(Type type) {
- switch (type) {
- case kPrimVoid:
- case kPrimBoolean:
- case kPrimByte: return 0;
- case kPrimChar:
- case kPrimShort: return 1;
- case kPrimInt:
- case kPrimFloat: return 2;
- case kPrimLong:
- case kPrimDouble: return 3;
- case kPrimNot: return ComponentSizeShiftWidth(kObjectReferenceSize);
- }
- LOG(FATAL) << "Invalid type " << static_cast<int>(type);
- UNREACHABLE();
- }
-
- static constexpr size_t ComponentSize(Type type) {
- switch (type) {
- case kPrimVoid: return 0;
- case kPrimBoolean:
- case kPrimByte: return 1;
- case kPrimChar:
- case kPrimShort: return 2;
- case kPrimInt:
- case kPrimFloat: return 4;
- case kPrimLong:
- case kPrimDouble: return 8;
- case kPrimNot: return kObjectReferenceSize;
- }
- LOG(FATAL) << "Invalid type " << static_cast<int>(type);
- UNREACHABLE();
- }
-
- static const char* Descriptor(Type type) {
- switch (type) {
- case kPrimBoolean:
- return "Z";
- case kPrimByte:
- return "B";
- case kPrimChar:
- return "C";
- case kPrimShort:
- return "S";
- case kPrimInt:
- return "I";
- case kPrimFloat:
- return "F";
- case kPrimLong:
- return "J";
- case kPrimDouble:
- return "D";
- case kPrimVoid:
- return "V";
- default:
- LOG(FATAL) << "Primitive char conversion on invalid type " << static_cast<int>(type);
- return nullptr;
- }
- }
-
- static const char* PrettyDescriptor(Type type);
-
- // Returns the descriptor corresponding to the boxed type of |type|.
- static const char* BoxedDescriptor(Type type);
-
- // Returns true if |type| is an numeric type.
- static constexpr bool IsNumericType(Type type) {
- switch (type) {
- case Primitive::Type::kPrimNot: return false;
- case Primitive::Type::kPrimBoolean: return false;
- case Primitive::Type::kPrimByte: return true;
- case Primitive::Type::kPrimChar: return true;
- case Primitive::Type::kPrimShort: return true;
- case Primitive::Type::kPrimInt: return true;
- case Primitive::Type::kPrimLong: return true;
- case Primitive::Type::kPrimFloat: return true;
- case Primitive::Type::kPrimDouble: return true;
- case Primitive::Type::kPrimVoid: return false;
- }
- LOG(FATAL) << "Invalid type " << static_cast<int>(type);
- UNREACHABLE();
- }
-
- // Return trues if |type| is a signed numeric type.
- static constexpr bool IsSignedNumericType(Type type) {
- switch (type) {
- case Primitive::Type::kPrimNot: return false;
- case Primitive::Type::kPrimBoolean: return false;
- case Primitive::Type::kPrimByte: return true;
- case Primitive::Type::kPrimChar: return false;
- case Primitive::Type::kPrimShort: return true;
- case Primitive::Type::kPrimInt: return true;
- case Primitive::Type::kPrimLong: return true;
- case Primitive::Type::kPrimFloat: return true;
- case Primitive::Type::kPrimDouble: return true;
- case Primitive::Type::kPrimVoid: return false;
- }
- LOG(FATAL) << "Invalid type " << static_cast<int>(type);
- UNREACHABLE();
- }
-
- // Returns the number of bits required to hold the largest
- // positive number that can be represented by |type|.
- static constexpr size_t BitsRequiredForLargestValue(Type type) {
- switch (type) {
- case Primitive::Type::kPrimNot: return 0u;
- case Primitive::Type::kPrimBoolean: return 1u;
- case Primitive::Type::kPrimByte: return 7u;
- case Primitive::Type::kPrimChar: return 16u;
- case Primitive::Type::kPrimShort: return 15u;
- case Primitive::Type::kPrimInt: return 31u;
- case Primitive::Type::kPrimLong: return 63u;
- case Primitive::Type::kPrimFloat: return 128u;
- case Primitive::Type::kPrimDouble: return 1024u;
- case Primitive::Type::kPrimVoid: return 0u;
- }
- }
-
- // Returns true if it is possible to widen type |from| to type |to|. Both |from| and
- // |to| should be numeric primitive types.
- static bool IsWidenable(Type from, Type to) {
- if (!IsNumericType(from) || !IsNumericType(to)) {
- // Widening is only applicable between numeric types.
- return false;
- }
- if (IsSignedNumericType(from) && !IsSignedNumericType(to)) {
- // Nowhere to store the sign bit in |to|.
- return false;
- }
- if (BitsRequiredForLargestValue(from) > BitsRequiredForLargestValue(to)) {
- // The from,to pair corresponds to a narrowing.
- return false;
- }
- return true;
- }
-
- static bool Is64BitType(Type type) {
- return type == kPrimLong || type == kPrimDouble;
- }
-
- private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(Primitive);
-};
-
-std::ostream& operator<<(std::ostream& os, Primitive::Type state);
-
-} // namespace art
-
-#endif // ART_RUNTIME_PRIMITIVE_H_
diff --git a/runtime/primitive_test.cc b/runtime/primitive_test.cc
deleted file mode 100644
index e433b15..0000000
--- a/runtime/primitive_test.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include "primitive.h"
-
-#include "gtest/gtest.h"
-
-namespace art {
-
-namespace {
-
-void CheckPrimitiveTypeWidensTo(Primitive::Type from,
- const std::vector<Primitive::Type>& expected_to_types) {
- std::vector<Primitive::Type> actual_to_types;
- int last = static_cast<int>(Primitive::Type::kPrimLast);
- for (int i = 0; i <= last; ++i) {
- Primitive::Type to = static_cast<Primitive::Type>(i);
- if (Primitive::IsWidenable(from, to)) {
- actual_to_types.push_back(to);
- }
- }
- EXPECT_EQ(expected_to_types, actual_to_types);
-}
-
-} // namespace
-
-TEST(PrimitiveTest, NotWidensTo) {
- const std::vector<Primitive::Type> to_types = {};
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimNot, to_types);
-}
-
-TEST(PrimitiveTest, BooleanWidensTo) {
- const std::vector<Primitive::Type> to_types = {};
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimBoolean, to_types);
-}
-
-TEST(PrimitiveTest, ByteWidensTo) {
- const std::vector<Primitive::Type> to_types = {
- Primitive::Type::kPrimByte,
- Primitive::Type::kPrimShort,
- Primitive::Type::kPrimInt,
- Primitive::Type::kPrimLong,
- Primitive::Type::kPrimFloat,
- Primitive::Type::kPrimDouble,
- };
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimByte, to_types);
-}
-
-TEST(PrimitiveTest, CharWidensTo) {
- const std::vector<Primitive::Type> to_types = {
- Primitive::Type::kPrimChar,
- Primitive::Type::kPrimInt,
- Primitive::Type::kPrimLong,
- Primitive::Type::kPrimFloat,
- Primitive::Type::kPrimDouble,
- };
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimChar, to_types);
-}
-
-TEST(PrimitiveTest, ShortWidensTo) {
- const std::vector<Primitive::Type> to_types = {
- Primitive::Type::kPrimShort,
- Primitive::Type::kPrimInt,
- Primitive::Type::kPrimLong,
- Primitive::Type::kPrimFloat,
- Primitive::Type::kPrimDouble,
- };
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimShort, to_types);
-}
-
-TEST(PrimitiveTest, IntWidensTo) {
- const std::vector<Primitive::Type> to_types = {
- Primitive::Type::kPrimInt,
- Primitive::Type::kPrimLong,
- Primitive::Type::kPrimFloat,
- Primitive::Type::kPrimDouble,
- };
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimInt, to_types);
-}
-
-TEST(PrimitiveTest, LongWidensTo) {
- const std::vector<Primitive::Type> to_types = {
- Primitive::Type::kPrimLong,
- Primitive::Type::kPrimFloat,
- Primitive::Type::kPrimDouble,
- };
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimLong, to_types);
-}
-
-TEST(PrimitiveTest, FloatWidensTo) {
- const std::vector<Primitive::Type> to_types = {
- Primitive::Type::kPrimFloat,
- Primitive::Type::kPrimDouble,
- };
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimFloat, to_types);
-}
-
-TEST(PrimitiveTest, DoubleWidensTo) {
- const std::vector<Primitive::Type> to_types = {
- Primitive::Type::kPrimDouble,
- };
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimDouble, to_types);
-}
-
-TEST(PrimitiveTest, VoidWidensTo) {
- const std::vector<Primitive::Type> to_types = {};
- CheckPrimitiveTypeWidensTo(Primitive::Type::kPrimVoid, to_types);
-}
-
-} // namespace art
diff --git a/runtime/quicken_info.h b/runtime/quicken_info.h
index f20aa0c..6c18590 100644
--- a/runtime/quicken_info.h
+++ b/runtime/quicken_info.h
@@ -18,9 +18,9 @@
#define ART_RUNTIME_QUICKEN_INFO_H_
#include "base/array_ref.h"
+#include "base/leb128.h"
#include "dex/compact_offset_table.h"
#include "dex/dex_instruction.h"
-#include "leb128.h"
namespace art {
diff --git a/runtime/reference_table_test.cc b/runtime/reference_table_test.cc
index 1e7fc3e..06ea384 100644
--- a/runtime/reference_table_test.cc
+++ b/runtime/reference_table_test.cc
@@ -23,12 +23,12 @@
#include "art_method-inl.h"
#include "class_linker.h"
#include "common_runtime_test.h"
+#include "dex/primitive.h"
#include "handle_scope-inl.h"
#include "mirror/array-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "mirror/string.h"
-#include "primitive.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"
diff --git a/runtime/reflection-inl.h b/runtime/reflection-inl.h
index 6edb12f..87432ab 100644
--- a/runtime/reflection-inl.h
+++ b/runtime/reflection-inl.h
@@ -23,10 +23,10 @@
#include "common_throws.h"
#include "dex/descriptors_names.h"
+#include "dex/primitive.h"
#include "jvalue-inl.h"
#include "mirror/object-inl.h"
#include "obj_ptr-inl.h"
-#include "primitive.h"
#include "utils.h"
namespace art {
diff --git a/runtime/reflection.h b/runtime/reflection.h
index 2da2917..4560a39 100644
--- a/runtime/reflection.h
+++ b/runtime/reflection.h
@@ -18,9 +18,9 @@
#define ART_RUNTIME_REFLECTION_H_
#include "base/mutex.h"
+#include "dex/primitive.h"
#include "jni.h"
#include "obj_ptr.h"
-#include "primitive.h"
namespace art {
namespace mirror {
diff --git a/runtime/safe_map.h b/runtime/safe_map.h
deleted file mode 100644
index 33e45bd..0000000
--- a/runtime/safe_map.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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_RUNTIME_SAFE_MAP_H_
-#define ART_RUNTIME_SAFE_MAP_H_
-
-#include <map>
-#include <memory>
-#include <type_traits>
-
-#include <android-base/logging.h>
-
-#include "base/allocator.h"
-
-namespace art {
-
-// Equivalent to std::map, but without operator[] and its bug-prone semantics (in particular,
-// the implicit insertion of a default-constructed value on failed lookups).
-template <typename K, typename V, typename Comparator = std::less<K>,
- typename Allocator = TrackingAllocator<std::pair<const K, V>, kAllocatorTagSafeMap>>
-class SafeMap {
- private:
- typedef SafeMap<K, V, Comparator, Allocator> Self;
-
- public:
- typedef typename ::std::map<K, V, Comparator, Allocator>::key_compare key_compare;
- typedef typename ::std::map<K, V, Comparator, Allocator>::value_compare value_compare;
- typedef typename ::std::map<K, V, Comparator, Allocator>::allocator_type allocator_type;
- typedef typename ::std::map<K, V, Comparator, Allocator>::iterator iterator;
- typedef typename ::std::map<K, V, Comparator, Allocator>::const_iterator const_iterator;
- typedef typename ::std::map<K, V, Comparator, Allocator>::size_type size_type;
- typedef typename ::std::map<K, V, Comparator, Allocator>::key_type key_type;
- typedef typename ::std::map<K, V, Comparator, Allocator>::value_type value_type;
-
- SafeMap() = default;
- SafeMap(const SafeMap&) = default;
- SafeMap(SafeMap&&) = default;
- explicit SafeMap(const key_compare& cmp, const allocator_type& allocator = allocator_type())
- : map_(cmp, allocator) {
- }
-
- Self& operator=(const Self& rhs) {
- map_ = rhs.map_;
- return *this;
- }
-
- allocator_type get_allocator() const { return map_.get_allocator(); }
- key_compare key_comp() const { return map_.key_comp(); }
- value_compare value_comp() const { return map_.value_comp(); }
-
- iterator begin() { return map_.begin(); }
- const_iterator begin() const { return map_.begin(); }
- iterator end() { return map_.end(); }
- const_iterator end() const { return map_.end(); }
-
- bool empty() const { return map_.empty(); }
- size_type size() const { return map_.size(); }
-
- void swap(Self& other) { map_.swap(other.map_); }
- void clear() { map_.clear(); }
- iterator erase(iterator it) { return map_.erase(it); }
- size_type erase(const K& k) { return map_.erase(k); }
-
- iterator find(const K& k) { return map_.find(k); }
- const_iterator find(const K& k) const { return map_.find(k); }
-
- iterator lower_bound(const K& k) { return map_.lower_bound(k); }
- const_iterator lower_bound(const K& k) const { return map_.lower_bound(k); }
-
- iterator upper_bound(const K& k) { return map_.upper_bound(k); }
- const_iterator upper_bound(const K& k) const { return map_.upper_bound(k); }
-
- size_type count(const K& k) const { return map_.count(k); }
-
- // Note that unlike std::map's operator[], this doesn't return a reference to the value.
- V Get(const K& k) const {
- const_iterator it = map_.find(k);
- DCHECK(it != map_.end());
- return it->second;
- }
-
- // Used to insert a new mapping.
- iterator Put(const K& k, const V& v) {
- std::pair<iterator, bool> result = map_.emplace(k, v);
- DCHECK(result.second); // Check we didn't accidentally overwrite an existing value.
- return result.first;
- }
- iterator Put(const K& k, V&& v) {
- std::pair<iterator, bool> result = map_.emplace(k, std::move(v));
- DCHECK(result.second); // Check we didn't accidentally overwrite an existing value.
- return result.first;
- }
-
- // Used to insert a new mapping at a known position for better performance.
- iterator PutBefore(const_iterator pos, const K& k, const V& v) {
- // Check that we're using the correct position and the key is not in the map.
- DCHECK(pos == map_.end() || map_.key_comp()(k, pos->first));
- DCHECK(pos == map_.begin() || map_.key_comp()((--const_iterator(pos))->first, k));
- return map_.emplace_hint(pos, k, v);
- }
- iterator PutBefore(const_iterator pos, const K& k, V&& v) {
- // Check that we're using the correct position and the key is not in the map.
- DCHECK(pos == map_.end() || map_.key_comp()(k, pos->first));
- DCHECK(pos == map_.begin() || map_.key_comp()((--const_iterator(pos))->first, k));
- return map_.emplace_hint(pos, k, std::move(v));
- }
-
- // Used to insert a new mapping or overwrite an existing mapping. Note that if the value type
- // of this container is a pointer, any overwritten pointer will be lost and if this container
- // was the owner, you have a leak. Returns iterator pointing to the new or overwritten entry.
- iterator Overwrite(const K& k, const V& v) {
- std::pair<iterator, bool> result = map_.insert(std::make_pair(k, v));
- if (!result.second) {
- // Already there - update the value for the existing key
- result.first->second = v;
- }
- return result.first;
- }
-
- template <typename CreateFn>
- V GetOrCreate(const K& k, CreateFn create) {
- static_assert(std::is_same<V, typename std::result_of<CreateFn()>::type>::value,
- "Argument `create` should return a value of type V.");
- auto lb = lower_bound(k);
- if (lb != end() && !key_comp()(k, lb->first)) {
- return lb->second;
- }
- auto it = PutBefore(lb, k, create());
- return it->second;
- }
-
- iterator FindOrAdd(const K& k, const V& v) {
- iterator it = find(k);
- return it == end() ? Put(k, v) : it;
- }
-
- iterator FindOrAdd(const K& k) {
- iterator it = find(k);
- return it == end() ? Put(k, V()) : it;
- }
-
- bool Equals(const Self& rhs) const {
- return map_ == rhs.map_;
- }
-
- template <class... Args>
- std::pair<iterator, bool> emplace(Args&&... args) {
- return map_.emplace(std::forward<Args>(args)...);
- }
-
- private:
- ::std::map<K, V, Comparator, Allocator> map_;
-};
-
-template <typename K, typename V, typename Comparator, typename Allocator>
-bool operator==(const SafeMap<K, V, Comparator, Allocator>& lhs,
- const SafeMap<K, V, Comparator, Allocator>& rhs) {
- return lhs.Equals(rhs);
-}
-
-template <typename K, typename V, typename Comparator, typename Allocator>
-bool operator!=(const SafeMap<K, V, Comparator, Allocator>& lhs,
- const SafeMap<K, V, Comparator, Allocator>& rhs) {
- return !(lhs == rhs);
-}
-
-template<class Key, class T, AllocatorTag kTag, class Compare = std::less<Key>>
-class AllocationTrackingSafeMap : public SafeMap<
- Key, T, Compare, TrackingAllocator<std::pair<const Key, T>, kTag>> {
-};
-
-} // namespace art
-
-#endif // ART_RUNTIME_SAFE_MAP_H_
diff --git a/runtime/stack_map.h b/runtime/stack_map.h
index 62fb54f..bde3462 100644
--- a/runtime/stack_map.h
+++ b/runtime/stack_map.h
@@ -22,9 +22,9 @@
#include "arch/code_offset.h"
#include "base/bit_utils.h"
#include "base/bit_vector.h"
+#include "base/leb128.h"
#include "bit_memory_region.h"
#include "dex/dex_file_types.h"
-#include "leb128.h"
#include "memory_region.h"
#include "method_info.h"
diff --git a/runtime/trace.h b/runtime/trace.h
index a888dcb..7ce12da 100644
--- a/runtime/trace.h
+++ b/runtime/trace.h
@@ -28,10 +28,10 @@
#include "atomic.h"
#include "base/macros.h"
+#include "base/safe_map.h"
#include "globals.h"
#include "instrumentation.h"
#include "os.h"
-#include "safe_map.h"
namespace art {
diff --git a/runtime/transaction.h b/runtime/transaction.h
index 8539ebc..7adf140 100644
--- a/runtime/transaction.h
+++ b/runtime/transaction.h
@@ -19,12 +19,12 @@
#include "base/macros.h"
#include "base/mutex.h"
+#include "base/safe_map.h"
#include "base/value_object.h"
#include "dex/dex_file_types.h"
+#include "dex/primitive.h"
#include "gc_root.h"
#include "offsets.h"
-#include "primitive.h"
-#include "safe_map.h"
#include <list>
#include <map>
diff --git a/runtime/type_lookup_table.h b/runtime/type_lookup_table.h
index a1f9519..3352d60 100644
--- a/runtime/type_lookup_table.h
+++ b/runtime/type_lookup_table.h
@@ -17,9 +17,9 @@
#ifndef ART_RUNTIME_TYPE_LOOKUP_TABLE_H_
#define ART_RUNTIME_TYPE_LOOKUP_TABLE_H_
+#include "base/leb128.h"
#include "dex/dex_file_types.h"
#include "dex/utf.h"
-#include "leb128.h"
namespace art {
diff --git a/runtime/utils.h b/runtime/utils.h
index 7dc8f35..0c3a0a2 100644
--- a/runtime/utils.h
+++ b/runtime/utils.h
@@ -28,8 +28,8 @@
#include "arch/instruction_set.h"
#include "base/casts.h"
#include "base/stringpiece.h"
+#include "dex/primitive.h"
#include "globals.h"
-#include "primitive.h"
namespace art {
diff --git a/runtime/utils/dex_cache_arrays_layout-inl.h b/runtime/utils/dex_cache_arrays_layout-inl.h
index 855b856..68a5760 100644
--- a/runtime/utils/dex_cache_arrays_layout-inl.h
+++ b/runtime/utils/dex_cache_arrays_layout-inl.h
@@ -22,10 +22,10 @@
#include <android-base/logging.h>
#include "base/bit_utils.h"
+#include "dex/primitive.h"
#include "gc_root.h"
#include "globals.h"
#include "mirror/dex_cache.h"
-#include "primitive.h"
namespace art {
diff --git a/runtime/vdex_file.cc b/runtime/vdex_file.cc
index 34b9fcc..ba64055 100644
--- a/runtime/vdex_file.cc
+++ b/runtime/vdex_file.cc
@@ -24,14 +24,14 @@
#include <android-base/logging.h>
#include "base/bit_utils.h"
+#include "base/leb128.h"
#include "base/stl_util.h"
#include "base/unix_file/fd_file.h"
#include "dex/art_dex_file_loader.h"
#include "dex/dex_file.h"
#include "dex/dex_file_loader.h"
+#include "dex/hidden_api_access_flags.h"
#include "dex_to_dex_decompiler.h"
-#include "hidden_api_access_flags.h"
-#include "leb128.h"
#include "quicken_info.h"
namespace art {
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 9a393ea..52bd736 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -24,6 +24,7 @@
#include "art_method-inl.h"
#include "base/aborting.h"
#include "base/enums.h"
+#include "base/leb128.h"
#include "base/logging.h" // For VLOG.
#include "base/mutex-inl.h"
#include "base/stl_util.h"
@@ -41,7 +42,6 @@
#include "handle_scope-inl.h"
#include "indenter.h"
#include "intern_table.h"
-#include "leb128.h"
#include "mirror/class-inl.h"
#include "mirror/class.h"
#include "mirror/dex_cache-inl.h"
diff --git a/runtime/verifier/reg_type.h b/runtime/verifier/reg_type.h
index 9055849..3e99407 100644
--- a/runtime/verifier/reg_type.h
+++ b/runtime/verifier/reg_type.h
@@ -27,10 +27,10 @@
#include "base/macros.h"
#include "base/mutex.h"
#include "base/stringpiece.h"
+#include "dex/primitive.h"
#include "gc_root.h"
#include "handle_scope.h"
#include "obj_ptr.h"
-#include "primitive.h"
namespace art {
namespace mirror {
diff --git a/runtime/verifier/reg_type_cache.h b/runtime/verifier/reg_type_cache.h
index 5277676..b32dc11 100644
--- a/runtime/verifier/reg_type_cache.h
+++ b/runtime/verifier/reg_type_cache.h
@@ -23,8 +23,8 @@
#include "base/casts.h"
#include "base/macros.h"
#include "base/scoped_arena_containers.h"
+#include "dex/primitive.h"
#include "gc_root.h"
-#include "primitive.h"
namespace art {
namespace mirror {
diff --git a/runtime/verifier/register_line.h b/runtime/verifier/register_line.h
index 82f63b2..18ad6b5 100644
--- a/runtime/verifier/register_line.h
+++ b/runtime/verifier/register_line.h
@@ -22,8 +22,8 @@
#include <android-base/logging.h>
+#include "base/safe_map.h"
#include "base/scoped_arena_containers.h"
-#include "safe_map.h"
namespace art {
diff --git a/runtime/verifier/verifier_deps.cc b/runtime/verifier/verifier_deps.cc
index 7d8c5aa..4772e53 100644
--- a/runtime/verifier/verifier_deps.cc
+++ b/runtime/verifier/verifier_deps.cc
@@ -20,11 +20,11 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
+#include "base/leb128.h"
#include "base/stl_util.h"
#include "compiler_callbacks.h"
#include "dex/dex_file-inl.h"
#include "indenter.h"
-#include "leb128.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "obj_ptr-inl.h"
diff --git a/runtime/zip_archive.h b/runtime/zip_archive.h
index 2ca4aa2..7b45690 100644
--- a/runtime/zip_archive.h
+++ b/runtime/zip_archive.h
@@ -23,11 +23,11 @@
#include <android-base/logging.h>
+#include "base/safe_map.h"
#include "base/unix_file/random_access_file.h"
#include "globals.h"
#include "mem_map.h"
#include "os.h"
-#include "safe_map.h"
// system/core/zip_archive definitions.
struct ZipEntry;