Skip to content

Commit 9a3a2ec

Browse files
committed
The beginnings
1 parent 8d9ca39 commit 9a3a2ec

File tree

9 files changed

+515
-603
lines changed

9 files changed

+515
-603
lines changed

build-tools/scripts/generate-pinvoke-tables.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ GENERATOR_BINARY="${MONODROID_SOURCE_DIR}/generate-pinvoke-tables"
88
TARGET_FILE="${MONODROID_SOURCE_DIR}/pinvoke-tables.include"
99
GENERATED_FILE="${TARGET_FILE}.generated"
1010
DIFF_FILE="${TARGET_FILE}.diff"
11+
EXTERNAL_DIR="${MY_DIR}/../../external/"
1112

1213
function die()
1314
{
@@ -62,7 +63,7 @@ case ${HOST} in
6263
*) die Unsupported OS ;;
6364
esac
6465

65-
${COMPILER} -O2 -std=c++20 "${GENERATOR_SOURCE}" -o "${GENERATOR_BINARY}"
66+
${COMPILER} -O2 -std=c++20 -I${EXTERNAL_DIR}/xxHash -I${EXTERNAL_DIR}/constexpr-xxh3 "${GENERATOR_SOURCE}" -o "${GENERATOR_BINARY}"
6667
"${GENERATOR_BINARY}" "${GENERATED_FILE}"
6768

6869
FILES_DIFFER="no"

src/Xamarin.Android.Build.Tasks/Utilities/AssemblyStoreIndexEntry.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public AssemblyStoreIndexEntry (string name, uint blobID, uint mappingIndex, uin
3737

3838
byte[] nameBytes = Encoding.UTF8.GetBytes (name);
3939
NameHash32 = XxHash32.HashToUInt32 (nameBytes);
40-
NameHash64 = XxHash64.HashToUInt64 (nameBytes);
40+
NameHash64 = XxHash3.HashToUInt64 (nameBytes);
4141
}
4242
}
4343
}

src/Xamarin.Android.Build.Tasks/Utilities/LlvmIrGenerator/LlvmIrComposer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public static ulong GetXxHash (string str, bool is64Bit)
3838
{
3939
byte[] stringBytes = Encoding.UTF8.GetBytes (str);
4040
if (is64Bit) {
41-
return XxHash64.HashToUInt64 (stringBytes);
41+
return XxHash3.HashToUInt64 (stringBytes);
4242
}
4343

4444
return (ulong)XxHash32.HashToUInt32 (stringBytes);

src/Xamarin.Android.Build.Tasks/Utilities/TypeMappingReleaseNativeAssemblyGenerator.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -415,16 +415,7 @@ ulong HashName (string name, bool is64Bit)
415415

416416
// Native code (EmbeddedAssemblies::typemap_java_to_managed in embedded-assemblies.cc) will operate on wchar_t cast to a byte array, we need to do
417417
// the same
418-
return HashBytes (Encoding.Unicode.GetBytes (name), is64Bit);
419-
}
420-
421-
ulong HashBytes (byte[] bytes, bool is64Bit)
422-
{
423-
if (is64Bit) {
424-
return XxHash64.HashToUInt64 (bytes);
425-
}
426-
427-
return (ulong)XxHash32.HashToUInt32 (bytes);
418+
return GetXxHash (name, is64Bit);
428419
}
429420
}
430421
}

src/monodroid/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ set(LZ4_INCLUDE_DIR ${LZ4_SRC_DIR})
162162
set(XA_BIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/${XA_BUILD_CONFIGURATION}")
163163
set(XA_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/Build${XA_BUILD_CONFIGURATION}")
164164
set(ROBIN_MAP_DIR "${EXTERNAL_DIR}/robin-map")
165+
set(XXHASH_DIR "${EXTERNAL_DIR}/xxHash")
166+
set(CONSTEXPR_XXH3_DIR "${EXTERNAL_DIR}/constexpr-xxh3")
165167

166168
if(NOT ANDROID)
167169
if(WIN32 OR MINGW)
@@ -202,6 +204,8 @@ set(LZ4_SOURCES
202204
# Include directories
203205
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/ ${CMAKE_SOURCE_DIR}/include)
204206
include_directories(${ROBIN_MAP_DIR}/include)
207+
include_directories(${EXTERNAL_DIR})
208+
include_directories(${CONSTEXPR_XXH3_DIR})
205209

206210
if(NOT ANDROID)
207211
string(REPLACE " " ";" JDK_INCLUDE_LIST ${JDK_INCLUDE})

src/monodroid/jni/generate-pinvoke-tables.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -688,9 +688,9 @@ struct constexpr_test {
688688

689689
constexpr_test<xxhash32::hash<0> ("", 0), 0x2CC5D05U> constexprTest_1;
690690
constexpr_test<xxhash32::hash<2654435761U> ("", 0), 0x36B78AE7U> constexprTest_2;
691-
constexpr_test<xxhash64::hash<0> ("", 0), 0xEF46DB3751D8E999ULL> constexprTest_3;
692-
constexpr_test<xxhash64::hash<2654435761U> ("", 0), 0xAC75FDA2929B17EFULL> constexprTest_4;
691+
//constexpr_test<xxhash64::hash<0> ("", 0), 0xEF46DB3751D8E999ULL> constexprTest_3;
692+
//constexpr_test<xxhash64::hash<2654435761U> ("", 0), 0xAC75FDA2929B17EFULL> constexprTest_4;
693693
constexpr_test<xxhash32::hash<0> ("test", 4), 0x3E2023CFU> constexprTest32_5;
694694
constexpr_test<xxhash32::hash<2654435761U> ("test", 4), 0xA9C14438U> constexprTest32_6;
695-
constexpr_test<xxhash64::hash<0> ("test", 4), 0x4fdcca5ddb678139ULL> constexprTest64_7;
696-
constexpr_test<xxhash64::hash<2654435761U> ("test", 4), 0x5A183B8150E2F651ULL> constexprTest64_8;
695+
//constexpr_test<xxhash64::hash<0> ("test", 4), 0x4fdcca5ddb678139ULL> constexprTest64_7;
696+
//constexpr_test<xxhash64::hash<2654435761U> ("test", 4), 0x5A183B8150E2F651ULL> constexprTest64_8;

src/monodroid/jni/pinvoke-tables.include

Lines changed: 482 additions & 482 deletions
Large diffs are not rendered by default.

src/monodroid/jni/platform-compat.hh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ typedef struct dirent monodroid_dirent_t;
4848
#define never_inline
4949
#endif
5050

51-
#ifndef inline
52-
#define inline inline
53-
#endif
54-
5551
#ifndef XA_LIKELY
5652
#define XA_LIKELY(expr) (expr)
5753
#endif

src/monodroid/jni/xxhash.hh

Lines changed: 20 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
#if !defined (__XXHASH_HH)
22
#define __XXHASH_HH
33

4+
#if INTPTR_MAX == INT64_MAX
5+
#define XXH_NO_STREAM
6+
#define XXH_INLINE_ALL
7+
#define XXH_NAMESPACE xaInternal_
8+
#include <xxHash/xxhash.h>
9+
#include <constexpr-xxh3.h>
10+
#endif
11+
12+
#include <type_traits>
13+
414
//
515
// Based on original code at https://github.com/ekpyron/xxhashct
616
//
@@ -135,116 +145,26 @@ namespace xamarin::android
135145
}
136146
};
137147

148+
#if INTPTR_MAX == INT64_MAX
138149
class xxhash64 final
139150
{
140-
static constexpr uint64_t PRIME1 = 11400714785074694791ULL;
141-
static constexpr uint64_t PRIME2 = 14029467366897019727ULL;
142-
static constexpr uint64_t PRIME3 = 1609587929392839161ULL;
143-
static constexpr uint64_t PRIME4 = 9650029242287828579ULL;
144-
static constexpr uint64_t PRIME5 = 2870177450012600261ULL;
145-
146151
public:
147-
// We don't use any special seed in XA, the template parameter is just to keep the algorithm more easily
148-
// understood and to run compile-time algorithm correctness tests
149-
template<uint64_t Seed = 0>
150-
force_inline static constexpr uint64_t hash (const char *p, size_t len) noexcept
151-
{
152-
return finalize ((len >= 32 ? h32bytes<Seed> (p, len) : Seed + PRIME5) + len, p + (len & ~0x1FU), len & 0x1F);
153-
}
154-
155-
template<size_t Size, uint64_t Seed = 0>
156-
force_inline static constexpr uint64_t hash (const char (&input)[Size]) noexcept
157-
{
158-
return hash<Seed> (input, Size - 1);
159-
}
160-
161-
private:
162-
template<int Bits>
163-
force_inline static constexpr uint64_t rotl (uint64_t x) noexcept
164-
{
165-
return ((x << Bits) | (x >> (64 - Bits)));
166-
}
167-
168-
template<int RShift>
169-
force_inline static constexpr uint64_t mix1 (const uint64_t h, const uint64_t prime) noexcept
170-
{
171-
return (h ^ (h >> RShift)) * prime;
172-
}
173-
174-
force_inline static constexpr uint64_t mix2 (const uint64_t p, const uint64_t v = 0) noexcept
175-
{
176-
return rotl<31> (v + p * PRIME2) * PRIME1;
177-
}
178-
179-
force_inline static constexpr uint64_t mix3 (const uint64_t h, const uint64_t v) noexcept
180-
{
181-
return (h ^ mix2 (v)) * PRIME1 + PRIME4;
182-
}
183-
184-
// little-endian versions: all our target platforms are little-endian
185-
force_inline static constexpr uint32_t endian32 (const char *v) noexcept
152+
force_inline static constexpr XXH64_hash_t hash (const char *p, size_t len) noexcept
186153
{
187-
return
188-
static_cast<uint32_t>(static_cast<uint8_t>(v[0])) |
189-
(static_cast<uint32_t>(static_cast<uint8_t>(v[1])) << 8) |
190-
(static_cast<uint32_t>(static_cast<uint8_t>(v[2])) << 16) |
191-
(static_cast<uint32_t>(static_cast<uint8_t>(v[3])) << 24);
154+
return XXH3_64bits (static_cast<const void*>(p), len);
192155
}
193156

194-
force_inline static constexpr uint64_t endian64 (const char *v)
157+
// The C XXH64_64bits function from xxhash.h is not `constexpr` or `consteval`, so we cannot call it here.
158+
// At the same time, at build time performance is not that important, so we call the "unoptmized" `consteval`
159+
// C++ implementation here
160+
template<size_t Size>
161+
force_inline static consteval XXH64_hash_t hash (const char (&input)[Size]) noexcept
195162
{
196-
return
197-
static_cast<uint64_t>(static_cast<uint8_t>(v[0])) |
198-
(static_cast<uint64_t>(static_cast<uint8_t>(v[1])) << 8) |
199-
(static_cast<uint64_t>(static_cast<uint8_t>(v[2])) << 16) |
200-
(static_cast<uint64_t>(static_cast<uint8_t>(v[3])) << 24) |
201-
(static_cast<uint64_t>(static_cast<uint8_t>(v[4])) << 32) |
202-
(static_cast<uint64_t>(static_cast<uint8_t>(v[5])) << 40) |
203-
(static_cast<uint64_t>(static_cast<uint8_t>(v[6])) << 48) |
204-
(static_cast<uint64_t>(static_cast<uint8_t>(v[7])) << 56);
205-
}
206-
207-
force_inline static constexpr uint64_t fetch64 (const char *p, const uint64_t v = 0) noexcept
208-
{
209-
return mix2 (endian64 (p), v);
210-
}
211-
212-
force_inline static constexpr uint64_t fetch32 (const char *p) noexcept
213-
{
214-
return static_cast<uint64_t>(endian32 (p)) * PRIME1;
215-
}
216-
217-
force_inline static constexpr uint64_t fetch8 (const char *p) noexcept
218-
{
219-
return static_cast<uint8_t> (*p) * PRIME5;
220-
}
221-
222-
force_inline static constexpr uint64_t finalize (const uint64_t h, const char *p, size_t len) noexcept
223-
{
224-
return
225-
(len >= 8) ? (finalize (rotl<27> (h ^ fetch64 (p)) * PRIME1 + PRIME4, p + 8, len - 8)) :
226-
((len >= 4) ? (finalize (rotl<23> (h ^ fetch32 (p)) * PRIME2 + PRIME3, p + 4, len - 4)) :
227-
((len > 0) ? (finalize (rotl<11> (h ^ fetch8 (p)) * PRIME1, p + 1, len - 1)) :
228-
(mix1<32> (mix1<29> (mix1<33> (h, PRIME2), PRIME3), 1))));
229-
}
230-
231-
force_inline static constexpr uint64_t h32bytes (const char *p, size_t len, const uint64_t v1,const uint64_t v2, const uint64_t v3, const uint64_t v4) noexcept
232-
{
233-
return (len >= 32) ? h32bytes (p + 32, len - 32, fetch64 (p, v1), fetch64 (p + 8, v2), fetch64 (p + 16, v3), fetch64 (p + 24, v4)) :
234-
mix3 (mix3 (mix3 (mix3 (rotl<1> (v1) + rotl<7> (v2) + rotl<12> (v3) + rotl<18> (v4), v1), v2), v3), v4);
235-
}
236-
237-
// We don't use any special seed in XA, the template parameter is just to keep the algorithm more easily
238-
// understood
239-
template<uint64_t Seed = 0>
240-
force_inline static constexpr uint64_t h32bytes (const char *p, size_t len) noexcept
241-
{
242-
return h32bytes (p, len, Seed + PRIME1 + PRIME2, Seed + PRIME2, Seed, Seed - PRIME1);
163+
return constexpr_xxh3::XXH3_64bits_const (input);
243164
}
244165
};
245166

246-
#if INTPTR_MAX == INT64_MAX
247-
using hash_t = uint64_t;
167+
using hash_t = XXH64_hash_t;
248168
using xxhash = xxhash64;
249169
#else
250170
using hash_t = uint32_t;

0 commit comments

Comments
 (0)