Skip to content

Commit

Permalink
The beginnings
Browse files Browse the repository at this point in the history
  • Loading branch information
grendello committed Feb 14, 2024
1 parent 8d9ca39 commit 9a3a2ec
Show file tree
Hide file tree
Showing 9 changed files with 515 additions and 603 deletions.
3 changes: 2 additions & 1 deletion build-tools/scripts/generate-pinvoke-tables.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ GENERATOR_BINARY="${MONODROID_SOURCE_DIR}/generate-pinvoke-tables"
TARGET_FILE="${MONODROID_SOURCE_DIR}/pinvoke-tables.include"
GENERATED_FILE="${TARGET_FILE}.generated"
DIFF_FILE="${TARGET_FILE}.diff"
EXTERNAL_DIR="${MY_DIR}/../../external/"

function die()
{
Expand Down Expand Up @@ -62,7 +63,7 @@ case ${HOST} in
*) die Unsupported OS ;;
esac

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

FILES_DIFFER="no"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public AssemblyStoreIndexEntry (string name, uint blobID, uint mappingIndex, uin

byte[] nameBytes = Encoding.UTF8.GetBytes (name);
NameHash32 = XxHash32.HashToUInt32 (nameBytes);
NameHash64 = XxHash64.HashToUInt64 (nameBytes);
NameHash64 = XxHash3.HashToUInt64 (nameBytes);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public static ulong GetXxHash (string str, bool is64Bit)
{
byte[] stringBytes = Encoding.UTF8.GetBytes (str);
if (is64Bit) {
return XxHash64.HashToUInt64 (stringBytes);
return XxHash3.HashToUInt64 (stringBytes);
}

return (ulong)XxHash32.HashToUInt32 (stringBytes);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -415,16 +415,7 @@ ulong HashName (string name, bool is64Bit)

// 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
// the same
return HashBytes (Encoding.Unicode.GetBytes (name), is64Bit);
}

ulong HashBytes (byte[] bytes, bool is64Bit)
{
if (is64Bit) {
return XxHash64.HashToUInt64 (bytes);
}

return (ulong)XxHash32.HashToUInt32 (bytes);
return GetXxHash (name, is64Bit);
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/monodroid/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ set(LZ4_INCLUDE_DIR ${LZ4_SRC_DIR})
set(XA_BIN_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/${XA_BUILD_CONFIGURATION}")
set(XA_BUILD_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/Build${XA_BUILD_CONFIGURATION}")
set(ROBIN_MAP_DIR "${EXTERNAL_DIR}/robin-map")
set(XXHASH_DIR "${EXTERNAL_DIR}/xxHash")
set(CONSTEXPR_XXH3_DIR "${EXTERNAL_DIR}/constexpr-xxh3")

if(NOT ANDROID)
if(WIN32 OR MINGW)
Expand Down Expand Up @@ -202,6 +204,8 @@ set(LZ4_SOURCES
# Include directories
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/ ${CMAKE_SOURCE_DIR}/include)
include_directories(${ROBIN_MAP_DIR}/include)
include_directories(${EXTERNAL_DIR})
include_directories(${CONSTEXPR_XXH3_DIR})

if(NOT ANDROID)
string(REPLACE " " ";" JDK_INCLUDE_LIST ${JDK_INCLUDE})
Expand Down
8 changes: 4 additions & 4 deletions src/monodroid/jni/generate-pinvoke-tables.cc
Original file line number Diff line number Diff line change
Expand Up @@ -688,9 +688,9 @@ struct constexpr_test {

constexpr_test<xxhash32::hash<0> ("", 0), 0x2CC5D05U> constexprTest_1;
constexpr_test<xxhash32::hash<2654435761U> ("", 0), 0x36B78AE7U> constexprTest_2;
constexpr_test<xxhash64::hash<0> ("", 0), 0xEF46DB3751D8E999ULL> constexprTest_3;
constexpr_test<xxhash64::hash<2654435761U> ("", 0), 0xAC75FDA2929B17EFULL> constexprTest_4;
//constexpr_test<xxhash64::hash<0> ("", 0), 0xEF46DB3751D8E999ULL> constexprTest_3;
//constexpr_test<xxhash64::hash<2654435761U> ("", 0), 0xAC75FDA2929B17EFULL> constexprTest_4;
constexpr_test<xxhash32::hash<0> ("test", 4), 0x3E2023CFU> constexprTest32_5;
constexpr_test<xxhash32::hash<2654435761U> ("test", 4), 0xA9C14438U> constexprTest32_6;
constexpr_test<xxhash64::hash<0> ("test", 4), 0x4fdcca5ddb678139ULL> constexprTest64_7;
constexpr_test<xxhash64::hash<2654435761U> ("test", 4), 0x5A183B8150E2F651ULL> constexprTest64_8;
//constexpr_test<xxhash64::hash<0> ("test", 4), 0x4fdcca5ddb678139ULL> constexprTest64_7;
//constexpr_test<xxhash64::hash<2654435761U> ("test", 4), 0x5A183B8150E2F651ULL> constexprTest64_8;
964 changes: 482 additions & 482 deletions src/monodroid/jni/pinvoke-tables.include

Large diffs are not rendered by default.

4 changes: 0 additions & 4 deletions src/monodroid/jni/platform-compat.hh
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,6 @@ typedef struct dirent monodroid_dirent_t;
#define never_inline
#endif

#ifndef inline
#define inline inline
#endif

#ifndef XA_LIKELY
#define XA_LIKELY(expr) (expr)
#endif
Expand Down
120 changes: 20 additions & 100 deletions src/monodroid/jni/xxhash.hh
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
#if !defined (__XXHASH_HH)
#define __XXHASH_HH

#if INTPTR_MAX == INT64_MAX
#define XXH_NO_STREAM
#define XXH_INLINE_ALL
#define XXH_NAMESPACE xaInternal_
#include <xxHash/xxhash.h>
#include <constexpr-xxh3.h>
#endif

#include <type_traits>

//
// Based on original code at https://github.com/ekpyron/xxhashct
//
Expand Down Expand Up @@ -135,116 +145,26 @@ namespace xamarin::android
}
};

#if INTPTR_MAX == INT64_MAX
class xxhash64 final
{
static constexpr uint64_t PRIME1 = 11400714785074694791ULL;
static constexpr uint64_t PRIME2 = 14029467366897019727ULL;
static constexpr uint64_t PRIME3 = 1609587929392839161ULL;
static constexpr uint64_t PRIME4 = 9650029242287828579ULL;
static constexpr uint64_t PRIME5 = 2870177450012600261ULL;

public:
// We don't use any special seed in XA, the template parameter is just to keep the algorithm more easily
// understood and to run compile-time algorithm correctness tests
template<uint64_t Seed = 0>
force_inline static constexpr uint64_t hash (const char *p, size_t len) noexcept
{
return finalize ((len >= 32 ? h32bytes<Seed> (p, len) : Seed + PRIME5) + len, p + (len & ~0x1FU), len & 0x1F);
}

template<size_t Size, uint64_t Seed = 0>
force_inline static constexpr uint64_t hash (const char (&input)[Size]) noexcept
{
return hash<Seed> (input, Size - 1);
}

private:
template<int Bits>
force_inline static constexpr uint64_t rotl (uint64_t x) noexcept
{
return ((x << Bits) | (x >> (64 - Bits)));
}

template<int RShift>
force_inline static constexpr uint64_t mix1 (const uint64_t h, const uint64_t prime) noexcept
{
return (h ^ (h >> RShift)) * prime;
}

force_inline static constexpr uint64_t mix2 (const uint64_t p, const uint64_t v = 0) noexcept
{
return rotl<31> (v + p * PRIME2) * PRIME1;
}

force_inline static constexpr uint64_t mix3 (const uint64_t h, const uint64_t v) noexcept
{
return (h ^ mix2 (v)) * PRIME1 + PRIME4;
}

// little-endian versions: all our target platforms are little-endian
force_inline static constexpr uint32_t endian32 (const char *v) noexcept
force_inline static constexpr XXH64_hash_t hash (const char *p, size_t len) noexcept
{
return
static_cast<uint32_t>(static_cast<uint8_t>(v[0])) |
(static_cast<uint32_t>(static_cast<uint8_t>(v[1])) << 8) |
(static_cast<uint32_t>(static_cast<uint8_t>(v[2])) << 16) |
(static_cast<uint32_t>(static_cast<uint8_t>(v[3])) << 24);
return XXH3_64bits (static_cast<const void*>(p), len);
}

force_inline static constexpr uint64_t endian64 (const char *v)
// The C XXH64_64bits function from xxhash.h is not `constexpr` or `consteval`, so we cannot call it here.
// At the same time, at build time performance is not that important, so we call the "unoptmized" `consteval`
// C++ implementation here
template<size_t Size>
force_inline static consteval XXH64_hash_t hash (const char (&input)[Size]) noexcept
{
return
static_cast<uint64_t>(static_cast<uint8_t>(v[0])) |
(static_cast<uint64_t>(static_cast<uint8_t>(v[1])) << 8) |
(static_cast<uint64_t>(static_cast<uint8_t>(v[2])) << 16) |
(static_cast<uint64_t>(static_cast<uint8_t>(v[3])) << 24) |
(static_cast<uint64_t>(static_cast<uint8_t>(v[4])) << 32) |
(static_cast<uint64_t>(static_cast<uint8_t>(v[5])) << 40) |
(static_cast<uint64_t>(static_cast<uint8_t>(v[6])) << 48) |
(static_cast<uint64_t>(static_cast<uint8_t>(v[7])) << 56);
}

force_inline static constexpr uint64_t fetch64 (const char *p, const uint64_t v = 0) noexcept
{
return mix2 (endian64 (p), v);
}

force_inline static constexpr uint64_t fetch32 (const char *p) noexcept
{
return static_cast<uint64_t>(endian32 (p)) * PRIME1;
}

force_inline static constexpr uint64_t fetch8 (const char *p) noexcept
{
return static_cast<uint8_t> (*p) * PRIME5;
}

force_inline static constexpr uint64_t finalize (const uint64_t h, const char *p, size_t len) noexcept
{
return
(len >= 8) ? (finalize (rotl<27> (h ^ fetch64 (p)) * PRIME1 + PRIME4, p + 8, len - 8)) :
((len >= 4) ? (finalize (rotl<23> (h ^ fetch32 (p)) * PRIME2 + PRIME3, p + 4, len - 4)) :
((len > 0) ? (finalize (rotl<11> (h ^ fetch8 (p)) * PRIME1, p + 1, len - 1)) :
(mix1<32> (mix1<29> (mix1<33> (h, PRIME2), PRIME3), 1))));
}

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
{
return (len >= 32) ? h32bytes (p + 32, len - 32, fetch64 (p, v1), fetch64 (p + 8, v2), fetch64 (p + 16, v3), fetch64 (p + 24, v4)) :
mix3 (mix3 (mix3 (mix3 (rotl<1> (v1) + rotl<7> (v2) + rotl<12> (v3) + rotl<18> (v4), v1), v2), v3), v4);
}

// We don't use any special seed in XA, the template parameter is just to keep the algorithm more easily
// understood
template<uint64_t Seed = 0>
force_inline static constexpr uint64_t h32bytes (const char *p, size_t len) noexcept
{
return h32bytes (p, len, Seed + PRIME1 + PRIME2, Seed + PRIME2, Seed, Seed - PRIME1);
return constexpr_xxh3::XXH3_64bits_const (input);
}
};

#if INTPTR_MAX == INT64_MAX
using hash_t = uint64_t;
using hash_t = XXH64_hash_t;
using xxhash = xxhash64;
#else
using hash_t = uint32_t;
Expand Down

0 comments on commit 9a3a2ec

Please sign in to comment.