aboutsummaryrefslogtreecommitdiffstats
path: root/fsa
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@yahooinc.com>2022-06-23 15:17:01 +0000
committerHåvard Pettersen <havardpe@yahooinc.com>2022-06-24 09:33:15 +0000
commit6ca427c5d03ac29344b0bc7685052a89a1e29b04 (patch)
tree02fd2328218a677ce79f22026e19e21257373073 /fsa
parent645c3722a5d7380eaef2937b69d8148499d57773 (diff)
well defined unaligned access
Diffstat (limited to 'fsa')
-rw-r--r--fsa/src/vespa/fsa/automaton.cpp8
-rw-r--r--fsa/src/vespa/fsa/fsa.cpp16
-rw-r--r--fsa/src/vespa/fsa/fsa.h15
-rw-r--r--fsa/src/vespa/fsa/unaligned.h56
4 files changed, 76 insertions, 19 deletions
diff --git a/fsa/src/vespa/fsa/automaton.cpp b/fsa/src/vespa/fsa/automaton.cpp
index 91592078c98..57bcfb180a8 100644
--- a/fsa/src/vespa/fsa/automaton.cpp
+++ b/fsa/src/vespa/fsa/automaton.cpp
@@ -11,7 +11,7 @@
#include "fsa.h"
#include "automaton.h"
#include "checksum.h"
-
+#include "unaligned.h"
namespace fsa {
@@ -354,7 +354,7 @@ void Automaton::PackedAutomaton::finalize()
uint32_t j=lastsize;
bool fixedsize = true;
while(i<_blob_used){
- currsize = *((uint32_t*)(void *)(_blob+i));
+ currsize = Unaligned<uint32_t>::at(_blob+i);
if(currsize!=lastsize){
fixedsize = false;
break;
@@ -597,14 +597,14 @@ bool Automaton::PackedAutomaton::getFSA(FSA::Descriptor &d)
d._version = FSA::VER;
d._serial = 0;
- d._state = _packed_idx;
+ d._state = Unaligned<state_t>::ptr(_packed_idx);
d._symbol = _symbol;
d._size = size;
d._data = _blob;
d._data_size = _blob_used;
d._data_type = _blob_type;
d._fixed_data_size = _fixed_blob_size;
- d._perf_hash = _perf_hash;
+ d._perf_hash = Unaligned<hash_t>::ptr(_perf_hash);
d._start = _start_state;
_symbol = NULL;
diff --git a/fsa/src/vespa/fsa/fsa.cpp b/fsa/src/vespa/fsa/fsa.cpp
index 50fd8bff85d..4abc6f979d8 100644
--- a/fsa/src/vespa/fsa/fsa.cpp
+++ b/fsa/src/vespa/fsa/fsa.cpp
@@ -227,7 +227,7 @@ bool FSA::read(const char *file, FileAccessMethod fam)
checksum += Checksum::compute(_symbol,_size*sizeof(symbol_t));
if(_mmap_addr==NULL){
- _state = (state_t*)malloc(_size*sizeof(state_t));
+ _state = Unaligned<state_t>::ptr(malloc(_size*sizeof(state_t)));
r=::read(fd,_state,_size*sizeof(state_t));
if(r!=_size*sizeof(state_t)){
::close(fd);
@@ -236,8 +236,8 @@ bool FSA::read(const char *file, FileAccessMethod fam)
}
}
else {
- _state = (state_t*)(void *)((uint8_t*)_mmap_addr + sizeof(header) +
- _size*sizeof(symbol_t));
+ _state = Unaligned<state_t>::ptr((uint8_t*)_mmap_addr + sizeof(header) +
+ _size*sizeof(symbol_t));
}
checksum += Checksum::compute(_state,_size*sizeof(state_t));
@@ -259,7 +259,7 @@ bool FSA::read(const char *file, FileAccessMethod fam)
if(header._has_perfect_hash){
if(_mmap_addr==NULL){
- _perf_hash = (hash_t*)malloc(_size*sizeof(hash_t));
+ _perf_hash = Unaligned<hash_t>::ptr(malloc(_size*sizeof(hash_t)));
r=::read(fd,_perf_hash,_size*sizeof(hash_t));
if(r!=_size*sizeof(hash_t)){
::close(fd);
@@ -268,10 +268,10 @@ bool FSA::read(const char *file, FileAccessMethod fam)
}
}
else {
- _perf_hash = (hash_t*)(void *)((uint8_t*)_mmap_addr + sizeof(header) +
- _size*sizeof(symbol_t) +
- _size*sizeof(state_t) +
- _data_size);
+ _perf_hash = Unaligned<hash_t>::ptr((uint8_t*)_mmap_addr + sizeof(header) +
+ _size*sizeof(symbol_t) +
+ _size*sizeof(state_t) +
+ _data_size);
}
checksum += Checksum::compute(_perf_hash,_size*sizeof(hash_t));
_has_perfect_hash = true;
diff --git a/fsa/src/vespa/fsa/fsa.h b/fsa/src/vespa/fsa/fsa.h
index 915aeb17a17..f3703b398ba 100644
--- a/fsa/src/vespa/fsa/fsa.h
+++ b/fsa/src/vespa/fsa/fsa.h
@@ -15,6 +15,7 @@
#include <inttypes.h>
#include "file.h" // for FileAccessMethod
+#include "unaligned.h"
namespace fsa {
@@ -614,10 +615,10 @@ public:
return (uint32_t)((const uint8_t*)da)[0];
case 2:
case 3:
- return (uint32_t)((const uint16_t*)(const void *)da)[0];
+ return (uint32_t)Unaligned<uint16_t>::at(da).read();
case 4:
default:
- return ((const uint32_t*)(const void *) da)[0];
+ return Unaligned<uint32_t>::at(da).read();
}
}
@@ -2019,14 +2020,14 @@ public:
struct Descriptor {
uint32_t _version;
uint32_t _serial;
- state_t *_state;
+ Unaligned<state_t> *_state;
symbol_t *_symbol;
uint32_t _size;
data_t *_data;
uint32_t _data_size;
uint32_t _data_type;
uint32_t _fixed_data_size;
- hash_t *_perf_hash;
+ Unaligned<hash_t> *_perf_hash;
uint32_t _start;
};
@@ -2040,7 +2041,7 @@ private:
uint32_t _version; /**< Version of fsalib used to build this fsa. */
uint32_t _serial; /**< Serial number of this fsa. */
- state_t *_state; /**< State table for transitions. */
+ Unaligned<state_t> *_state; /**< State table for transitions. */
symbol_t *_symbol; /**< Symbol table for transitions. */
uint32_t _size; /**< Size (number of cells). */
@@ -2050,7 +2051,7 @@ private:
uint32_t _fixed_data_size; /**< Size of data items if fixed. */
bool _has_perfect_hash; /**< Indicator of perfect hash present. */
- hash_t *_perf_hash; /**< Perfect hash table, if present. */
+ Unaligned<hash_t> *_perf_hash; /**< Perfect hash table, if present. */
state_t _start; /**< Index of start state. */
@@ -2205,7 +2206,7 @@ public:
if(_data_type==DATA_FIXED)
return _fixed_data_size;
else
- return (int)(*((uint32_t*)(void *)(_data+_state[fs+FINAL_SYMBOL])));
+ return (int)Unaligned<uint32_t>::at(_data+_state[fs+FINAL_SYMBOL]).read();
}
return -1;
}
diff --git a/fsa/src/vespa/fsa/unaligned.h b/fsa/src/vespa/fsa/unaligned.h
new file mode 100644
index 00000000000..ff645194e4f
--- /dev/null
+++ b/fsa/src/vespa/fsa/unaligned.h
@@ -0,0 +1,56 @@
+// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <cstring>
+
+namespace fsa {
+
+template <typename T>
+class Unaligned {
+private:
+ char _data[sizeof(T)];
+
+public:
+ Unaligned() = delete;
+ Unaligned(const Unaligned &) = delete;
+ Unaligned(Unaligned &&) = delete;
+
+ Unaligned &operator=(const Unaligned &) = default;
+ Unaligned &operator=(Unaligned &&) = default;
+
+ static_assert(std::is_trivial_v<T>);
+ static_assert(alignof(T) > 1, "value is always aligned");
+
+ constexpr static Unaligned &at(void *p) noexcept {
+ return *reinterpret_cast<Unaligned*>(p);
+ }
+ constexpr static const Unaligned &at(const void *p) noexcept {
+ return *reinterpret_cast<const Unaligned*>(p);
+ }
+
+ constexpr static Unaligned *ptr(void *p) noexcept {
+ return reinterpret_cast<Unaligned*>(p);
+ }
+ constexpr static const Unaligned *ptr(const void *p) noexcept {
+ return reinterpret_cast<const Unaligned*>(p);
+ }
+
+ T read() const noexcept {
+ T value;
+ static_assert(sizeof(_data) == sizeof(value));
+ memcpy(&value, _data, sizeof(value));
+ return value;
+ }
+ void write(const T &value) noexcept {
+ static_assert(sizeof(_data) == sizeof(value));
+ memcpy(_data, &value, sizeof(value));
+ }
+ operator T () const noexcept { return read(); }
+ Unaligned &operator=(const T &value) noexcept {
+ write(value);
+ return *this;
+ }
+};
+
+}