diff --git a/Makefile b/Makefile index d96661107..96ad583ee 100644 --- a/Makefile +++ b/Makefile @@ -145,6 +145,7 @@ parsehisto: benchmark/parse.cpp $(HEADERS) $(LIBFILES) cppcheck: cppcheck --enable=all src/*.cpp benchmarks/*.cpp tests/*.cpp -Iinclude -I. -Ibenchmark/linux +everything: $(MAINEXECUTABLES) $(EXTRA_EXECUTABLES) $(TESTEXECUTABLES) $(COMPARISONEXECUTABLES) $(SUPPLEMENTARYEXECUTABLES) clean: rm -f $(EXTRAOBJECTS) $(MAINEXECUTABLES) $(EXTRA_EXECUTABLES) $(TESTEXECUTABLES) $(COMPARISONEXECUTABLES) $(SUPPLEMENTARYEXECUTABLES) diff --git a/benchmark/minifiercompetition.cpp b/benchmark/minifiercompetition.cpp index 170d41f8c..ca86e2517 100644 --- a/benchmark/minifiercompetition.cpp +++ b/benchmark/minifiercompetition.cpp @@ -140,7 +140,7 @@ int main(int argc, char *argv[]) { printf("failed to allocate memory\n"); return EXIT_FAILURE; } - BEST_TIME("simdjson orig", json_parse((const u8*)buffer, p.size(), pj), true, memcpy(buffer, p.data(), p.size()), repeat, volume, !justdata); + BEST_TIME("simdjson orig", json_parse((const uint8_t*)buffer, p.size(), pj), true, memcpy(buffer, p.data(), p.size()), repeat, volume, !justdata); ParsedJson pj2; bool isallocok2 = pj2.allocateCapacity(p.size(), 1024); @@ -149,7 +149,7 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - BEST_TIME("simdjson despaced", json_parse((const u8*)buffer, minisize, pj2), true, memcpy(buffer, minibuffer, p.size()), repeat, volume, !justdata); + BEST_TIME("simdjson despaced", json_parse((const uint8_t*)buffer, minisize, pj2), true, memcpy(buffer, minibuffer, p.size()), repeat, volume, !justdata); free((void*)p.data()); free(buffer); free(ast_buffer); diff --git a/benchmark/parse.cpp b/benchmark/parse.cpp index 3efe71a1c..078b016d4 100644 --- a/benchmark/parse.cpp +++ b/benchmark/parse.cpp @@ -85,9 +85,9 @@ int main(int argc, char *argv[]) { cout << "[verbose] loaded " << filename << " (" << p.size() << " bytes)" << endl; #if defined(DEBUG) - const u32 iterations = 1; + const uint32_t iterations = 1; #else - const u32 iterations = + const uint32_t iterations = forceoneiteration ? 1 : (p.size() < 1 * 1000 * 1000 ? 1000 : 10); #endif vector res; @@ -108,7 +108,7 @@ int main(int argc, char *argv[]) { evts.push_back(PERF_COUNT_HW_CACHE_REFERENCES); evts.push_back(PERF_COUNT_HW_CACHE_MISSES); LinuxEvents unified(evts); - vector results; + vector results; results.resize(evts.size()); unsigned long cy0 = 0, cy1 = 0, cy2 = 0, cy3 = 0; unsigned long cl0 = 0, cl1 = 0, cl2 = 0, cl3 = 0; @@ -118,7 +118,7 @@ int main(int argc, char *argv[]) { #endif bool isok = true; - for (u32 i = 0; i < iterations; i++) { + for (uint32_t i = 0; i < iterations; i++) { if (verbose) cout << "[verbose] iteration # " << i << endl; #ifndef SQUASH_COUNTERS diff --git a/benchmark/parseandstatcompetition.cpp b/benchmark/parseandstatcompetition.cpp index f85f1cb45..2c80db0b8 100644 --- a/benchmark/parseandstatcompetition.cpp +++ b/benchmark/parseandstatcompetition.cpp @@ -59,14 +59,14 @@ stat_t simdjson_computestats(const std::string_view &p) { answer.true_count = 0; answer.false_count = 0; size_t tapeidx = 0; - u64 tape_val = pj.tape[tapeidx++]; - u8 type = (tape_val >> 56); + uint64_t tape_val = pj.tape[tapeidx++]; + uint8_t type = (tape_val >> 56); size_t howmany = 0; assert(type == 'r'); howmany = tape_val & JSONVALUEMASK; for (; tapeidx < howmany; tapeidx++) { tape_val = pj.tape[tapeidx]; - // u64 payload = tape_val & JSONVALUEMASK; + // uint64_t payload = tape_val & JSONVALUEMASK; type = (tape_val >> 56); switch (type) { case 'l': // we have a long int diff --git a/benchmark/statisticalmodel.cpp b/benchmark/statisticalmodel.cpp index bf8136240..e121d15c7 100644 --- a/benchmark/statisticalmodel.cpp +++ b/benchmark/statisticalmodel.cpp @@ -9,7 +9,7 @@ using namespace std; -size_t count_nonasciibytes(const u8 *input, size_t length) { +size_t count_nonasciibytes(const uint8_t *input, size_t length) { size_t count = 0; for (size_t i = 0; i < length; i++) { count += input[i] >> 7; @@ -17,7 +17,7 @@ size_t count_nonasciibytes(const u8 *input, size_t length) { return count; } -size_t count_backslash(const u8 *input, size_t length) { +size_t count_backslash(const uint8_t *input, size_t length) { size_t count = 0; for (size_t i = 0; i < length; i++) { count += (input[i] == '\\') ? 1 : 0; @@ -50,9 +50,9 @@ stat_t simdjson_computestats(const std::string_view &p) { if (!answer.valid) { return answer; } - answer.backslash_count = count_backslash((const u8 *)p.data(), p.size()); + answer.backslash_count = count_backslash((const uint8_t *)p.data(), p.size()); answer.nonasciibyte_count = - count_nonasciibytes((const u8 *)p.data(), p.size()); + count_nonasciibytes((const uint8_t *)p.data(), p.size()); answer.byte_count = p.size(); answer.integer_count = 0; answer.float_count = 0; @@ -64,14 +64,14 @@ stat_t simdjson_computestats(const std::string_view &p) { answer.string_count = 0; answer.structural_indexes_count = pj.n_structural_indexes; size_t tapeidx = 0; - u64 tape_val = pj.tape[tapeidx++]; - u8 type = (tape_val >> 56); + uint64_t tape_val = pj.tape[tapeidx++]; + uint8_t type = (tape_val >> 56); size_t howmany = 0; assert(type == 'r'); howmany = tape_val & JSONVALUEMASK; for (; tapeidx < howmany; tapeidx++) { tape_val = pj.tape[tapeidx]; - // u64 payload = tape_val & JSONVALUEMASK; + // uint64_t payload = tape_val & JSONVALUEMASK; type = (tape_val >> 56); switch (type) { case 'l': // we have a long int @@ -173,7 +173,7 @@ int main(int argc, char *argv[]) { LinuxEvents unified(evts); unsigned long cy1 = 0, cy2 = 0, cy3 = 0; unsigned long cl1 = 0, cl2 = 0, cl3 = 0; - vector results; + vector results; results.resize(evts.size()); for (u32 i = 0; i < iterations; i++) { unified.start(); diff --git a/include/simdjson/common_defs.h b/include/simdjson/common_defs.h index 4f95877e5..408dd6b56 100644 --- a/include/simdjson/common_defs.h +++ b/include/simdjson/common_defs.h @@ -6,14 +6,7 @@ #define SIMDJSON_PADDING sizeof(__m256i) -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long u64; -typedef signed char s8; -typedef signed short s16; -typedef signed int s32; -typedef signed long long s64; + #ifdef _MSC_VER /* Microsoft C/C++-compatible compiler */ @@ -22,8 +15,6 @@ typedef signed long long s64; #include #endif -typedef __m128i m128; -typedef __m256i m256; // Align to N-byte boundary #define ROUNDUP_N(a, n) (((a) + ((n)-1)) & ~((n)-1)) @@ -44,20 +35,3 @@ typedef __m256i m256; #define unlikely(x) __builtin_expect(!!(x), 0) #endif -/*static inline u32 ctz64(u64 x) { - assert(x); // behaviour not defined for x == 0 -#if defined(_WIN64) - unsigned long r; - _BitScanForward64(&r, x); - return r; -#elif defined(_WIN32) - unsigned long r; - if (_BitScanForward(&r, (u32)x)) { - return (u32)r; - } - _BitScanForward(&r, x >> 32); - return (u32)(r + 32); -#else - return (u32)__builtin_ctzll(x); -#endif -}*/ diff --git a/include/simdjson/jsoncharutils.h b/include/simdjson/jsoncharutils.h index 8fa1b3a9b..cbbe1391a 100644 --- a/include/simdjson/jsoncharutils.h +++ b/include/simdjson/jsoncharutils.h @@ -10,7 +10,7 @@ // these are the chars that can follow a true/false/null or number atom // and nothing else -const u32 structural_or_whitespace_negated[256] = { +const uint32_t structural_or_whitespace_negated[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, @@ -29,11 +29,11 @@ const u32 structural_or_whitespace_negated[256] = { // return non-zero if not a structural or whitespace char // zero otherwise -really_inline u32 is_not_structural_or_whitespace(u8 c) { +really_inline uint32_t is_not_structural_or_whitespace(uint8_t c) { return structural_or_whitespace_negated[c]; } -const u32 structural_or_whitespace[256] = { +const uint32_t structural_or_whitespace[256] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -46,7 +46,7 @@ const u32 structural_or_whitespace[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -really_inline u32 is_structural_or_whitespace(u8 c) { +really_inline uint32_t is_structural_or_whitespace(uint8_t c) { return structural_or_whitespace[c]; } @@ -67,22 +67,22 @@ const char digittoval[256] = { -1, -1, -1, -1, -1, -1, -1, -1, -1}; // return true if we have a valid hex between 0000 and FFFF -/*inline bool hex_to_u32(const u8 *src, u32 *res) { - u8 v1 = src[0]; - u8 v2 = src[1]; - u8 v3 = src[2]; - u8 v4 = src[3]; +/*inline bool hex_to_u32(const uint8_t *src, uint32_t *res) { + uint8_t v1 = src[0]; + uint8_t v2 = src[1]; + uint8_t v3 = src[2]; + uint8_t v4 = src[3]; *res = digittoval[v1] << 12 | digittoval[v2] << 8 | digittoval[v3] << 4 | digittoval[v4]; return (int32_t)(*res) >= 0; }*/ // returns a value with the highest bit set if it is not valid -uint32_t hex_to_u32_nocheck(const u8 *src) { - u8 v1 = src[0]; - u8 v2 = src[1]; - u8 v3 = src[2]; - u8 v4 = src[3]; +uint32_t hex_to_u32_nocheck(const uint8_t *src) { + uint8_t v1 = src[0]; + uint8_t v2 = src[1]; + uint8_t v3 = src[2]; + uint8_t v4 = src[3]; return digittoval[v1] << 12 | digittoval[v2] << 8 | digittoval[v3] << 4 | digittoval[v4]; } @@ -99,7 +99,7 @@ uint32_t hex_to_u32_nocheck(const u8 *src) { // // Note: we assume that surrogates are treated separately // -inline size_t codepoint_to_utf8(uint32_t cp, u8 *c) { +inline size_t codepoint_to_utf8(uint32_t cp, uint8_t *c) { if (cp <= 0x7F) { c[0] = cp; return 1; // ascii diff --git a/include/simdjson/jsonparser.h b/include/simdjson/jsonparser.h index 62b3c404f..574142a62 100644 --- a/include/simdjson/jsonparser.h +++ b/include/simdjson/jsonparser.h @@ -19,7 +19,7 @@ // The input buf should be readable up to buf + len + SIMDJSON_PADDING if reallocifneeded is false, // all bytes at and after buf + len are ignored (can be garbage). WARN_UNUSED -bool json_parse(const u8 *buf, size_t len, ParsedJson &pj, bool reallocifneeded = true); +bool json_parse(const uint8_t *buf, size_t len, ParsedJson &pj, bool reallocifneeded = true); // Parse a document found in buf, need to preallocate ParsedJson. // Return false in case of a failure. You can also check validity @@ -31,7 +31,7 @@ bool json_parse(const u8 *buf, size_t len, ParsedJson &pj, bool reallocifneeded // all bytes at and after buf + len are ignored (can be garbage). WARN_UNUSED static inline bool json_parse(const char * buf, size_t len, ParsedJson &pj, bool reallocifneeded = true) { - return json_parse((const u8 *) buf, len, pj, reallocifneeded); + return json_parse((const uint8_t *) buf, len, pj, reallocifneeded); } // Parse a document found in buf, need to preallocate ParsedJson. @@ -56,7 +56,7 @@ static inline bool json_parse(const std::string_view &s, ParsedJson &pj, bool re // the input buf should be readable up to buf + len + SIMDJSON_PADDING if reallocifneeded is false, // all bytes at and after buf + len are ignored (can be garbage). WARN_UNUSED -ParsedJson build_parsed_json(const u8 *buf, size_t len, bool reallocifneeded = true); +ParsedJson build_parsed_json(const uint8_t *buf, size_t len, bool reallocifneeded = true); WARN_UNUSED // Build a ParsedJson object. You can check validity @@ -66,7 +66,7 @@ WARN_UNUSED // The input buf should be readable up to buf + len + SIMDJSON_PADDING if reallocifneeded is false, // all bytes at and after buf + len are ignored (can be garbage). static inline ParsedJson build_parsed_json(const char * buf, size_t len, bool reallocifneeded = true) { - return build_parsed_json((const u8 *) buf, len, reallocifneeded); + return build_parsed_json((const uint8_t *) buf, len, reallocifneeded); } // convenience function diff --git a/include/simdjson/numberparsing.h b/include/simdjson/numberparsing.h index ce3ab68b4..6ec56532a 100644 --- a/include/simdjson/numberparsing.h +++ b/include/simdjson/numberparsing.h @@ -159,8 +159,8 @@ static inline uint32_t parse_eight_digits_unrolled(const char *chars) { // Note: a redesign could avoid this function entirely. // static never_inline bool -parse_float(const u8 *const buf, - ParsedJson &pj, const u32 offset, +parse_float(const uint8_t *const buf, + ParsedJson &pj, const uint32_t offset, bool found_minus) { const char *p = (const char *)(buf + offset); bool negative = false; @@ -261,9 +261,9 @@ parse_float(const u8 *const buf, // // This function will almost never be called!!! // -static never_inline bool parse_large_integer(const u8 *const buf, +static never_inline bool parse_large_integer(const uint8_t *const buf, ParsedJson &pj, - const u32 offset, + const uint32_t offset, bool found_minus) { const char *p = (const char *)(buf + offset); @@ -336,9 +336,9 @@ static never_inline bool parse_large_integer(const u8 *const buf, // parse the number at buf + offset // define JSON_TEST_NUMBERS for unit testing -static really_inline bool parse_number(const u8 *const buf, +static really_inline bool parse_number(const uint8_t *const buf, ParsedJson &pj, - const u32 offset, + const uint32_t offset, bool found_minus) { #ifdef SIMDJSON_SKIPNUMBERPARSING // for performance analysis, it is sometimes useful to skip parsing pj.write_tape_s64(0); // always write zero diff --git a/include/simdjson/parsedjson.h b/include/simdjson/parsedjson.h index 582ee2cd3..37ab44193 100644 --- a/include/simdjson/parsedjson.h +++ b/include/simdjson/parsedjson.h @@ -54,13 +54,13 @@ public: return false; }; n_structural_indexes = 0; - u32 max_structures = ROUNDUP_N(len, 64) + 2 + 7; - structural_indexes = new u32[max_structures]; + uint32_t max_structures = ROUNDUP_N(len, 64) + 2 + 7; + structural_indexes = new uint32_t[max_structures]; size_t localtapecapacity = ROUNDUP_N(len, 64); size_t localstringcapacity = ROUNDUP_N(len, 64); - string_buf = new u8[localstringcapacity]; - tape = new u64[localtapecapacity]; - containing_scope_offset = new u32[maxdepth]; + string_buf = new uint8_t[localstringcapacity]; + tape = new uint64_t[localtapecapacity]; + containing_scope_offset = new uint32_t[maxdepth]; ret_address = new void *[maxdepth]; if ((string_buf == NULL) || (tape == NULL) || @@ -118,8 +118,8 @@ public: bool printjson(std::ostream &os) { if(!isvalid) return false; size_t tapeidx = 0; - u64 tape_val = tape[tapeidx]; - u8 type = (tape_val >> 56); + uint64_t tape_val = tape[tapeidx]; + uint8_t type = (tape_val >> 56); size_t howmany = 0; if (type == 'r') { howmany = tape_val & JSONVALUEMASK; @@ -140,7 +140,7 @@ public: inobject[depth] = false; for (; tapeidx < howmany; tapeidx++) { tape_val = tape[tapeidx]; - u64 payload = tape_val & JSONVALUEMASK; + uint64_t payload = tape_val & JSONVALUEMASK; type = (tape_val >> 56); if (!inobject[depth]) { if ((inobjectidx[depth] > 0) && (type != ']')) @@ -222,8 +222,8 @@ public: bool dump_raw_tape(std::ostream &os) { if(!isvalid) return false; size_t tapeidx = 0; - u64 tape_val = tape[tapeidx]; - u8 type = (tape_val >> 56); + uint64_t tape_val = tape[tapeidx]; + uint8_t type = (tape_val >> 56); os << tapeidx << " : " << type; tapeidx++; size_t howmany = 0; @@ -234,7 +234,7 @@ public: return false; } os << "\t// pointing to " << howmany <<" (right after last node)\n"; - u64 payload; + uint64_t payload; for (; tapeidx < howmany; tapeidx++) { os << tapeidx << " : "; tape_val = tape[tapeidx]; @@ -311,25 +311,25 @@ public: // // this should be considered a private function - really_inline void write_tape(u64 val, u8 c) { - tape[current_loc++] = val | (((u64)c) << 56); + really_inline void write_tape(uint64_t val, uint8_t c) { + tape[current_loc++] = val | (((uint64_t)c) << 56); } - really_inline void write_tape_s64(s64 i) { + really_inline void write_tape_s64(int64_t i) { write_tape(0, 'l'); - tape[current_loc++] = *((u64 *)&i); + tape[current_loc++] = *((uint64_t *)&i); } really_inline void write_tape_double(double d) { write_tape(0, 'd'); static_assert(sizeof(d) == sizeof(tape[current_loc]), "mismatch size"); memcpy(& tape[current_loc++], &d, sizeof(double)); - //tape[current_loc++] = *((u64 *)&d); + //tape[current_loc++] = *((uint64_t *)&d); } - really_inline u32 get_current_loc() { return current_loc; } + really_inline uint32_t get_current_loc() { return current_loc; } - really_inline void annotate_previousloc(u32 saved_loc, u64 val) { + really_inline void annotate_previousloc(uint32_t saved_loc, uint64_t val) { tape[saved_loc] |= val; } @@ -403,7 +403,7 @@ public: // A scope is a series of nodes at the same depth, typically it is either an object ({) or an array ([). // The root node has type 'r'. - u8 get_scope_type() const { + uint8_t get_scope_type() const { return depthindex[depth].scope_type; } @@ -439,14 +439,14 @@ public: // retrieve the character code of what we're looking at: // [{"sltfn are the possibilities - really_inline u8 get_type() const { + really_inline uint8_t get_type() const { return current_type; } - // get the s64 value at this node; valid only if we're at "l" - really_inline s64 get_integer() const { + // get the int64_t value at this node; valid only if we're at "l" + really_inline int64_t get_integer() const { if(location + 1 >= tape_length) return 0;// default value in case of error - return (s64) pj.tape[location + 1]; + return (int64_t) pj.tape[location + 1]; } // get the double value at this node; valid only if @@ -482,7 +482,7 @@ public: return get_type() == 'd'; } - static bool is_object_or_array(u8 type) { + static bool is_object_or_array(uint8_t type) { return (type == '[' || (type == '{')); } @@ -525,8 +525,8 @@ public: if(npos >= tape_length) { return false; // shoud never happen unless at the root } - u64 nextval = pj.tape[npos]; - u8 nexttype = (nextval >> 56); + uint64_t nextval = pj.tape[npos]; + uint8_t nexttype = (nextval >> 56); if((nexttype == ']') || (nexttype == '}')) { return false; // we reached the end of the scope } @@ -537,8 +537,8 @@ public: } else { size_t increment = (current_type == 'd' || current_type == 'l') ? 2 : 1; if(location + increment >= tape_length) return false; - u64 nextval = pj.tape[location + increment]; - u8 nexttype = (nextval >> 56); + uint64_t nextval = pj.tape[location + increment]; + uint8_t nexttype = (nextval >> 56); if((nexttype == ']') || (nexttype == '}')) { return false; // we reached the end of the scope } @@ -665,7 +665,7 @@ public: return true; } - typedef struct {size_t start_of_scope; u8 scope_type;} scopeindex_t; + typedef struct {size_t start_of_scope; uint8_t scope_type;} scopeindex_t; private: @@ -675,8 +675,8 @@ private: size_t depth; size_t location; // our current location on a tape size_t tape_length; - u8 current_type; - u64 current_val; + uint8_t current_type; + uint64_t current_val; scopeindex_t *depthindex; }; @@ -688,18 +688,18 @@ private: size_t depthcapacity; // how deep we can go size_t tapecapacity; size_t stringcapacity; - u32 current_loc; - u8 *structurals; - u32 n_structural_indexes; + uint32_t current_loc; + uint8_t *structurals; + uint32_t n_structural_indexes; - u32 *structural_indexes; + uint32_t *structural_indexes; - u64 *tape; - u32 *containing_scope_offset; + uint64_t *tape; + uint32_t *containing_scope_offset; void **ret_address; - u8 *string_buf; // should be at least bytecapacity - u8 *current_string_buf_loc; + uint8_t *string_buf; // should be at least bytecapacity + uint8_t *current_string_buf_loc; bool isvalid; ParsedJson(const ParsedJson && p); @@ -715,8 +715,8 @@ private : #ifdef DEBUG inline void dump256(m256 d, const std::string &msg) { - for (u32 i = 0; i < 32; i++) { - std::cout << std::setw(3) << (int)*(((u8 *)(&d)) + i); + for (uint32_t i = 0; i < 32; i++) { + std::cout << std::setw(3) << (int)*(((uint8_t *)(&d)) + i); if (!((i + 1) % 8)) std::cout << "|"; else if (!((i + 1) % 4)) @@ -728,16 +728,16 @@ inline void dump256(m256 d, const std::string &msg) { } // dump bits low to high -inline void dumpbits(u64 v, const std::string &msg) { - for (u32 i = 0; i < 64; i++) { - std::cout << (((v >> (u64)i) & 0x1ULL) ? "1" : "_"); +inline void dumpbits(uint64_t v, const std::string &msg) { + for (uint32_t i = 0; i < 64; i++) { + std::cout << (((v >> (uint64_t)i) & 0x1ULL) ? "1" : "_"); } std::cout << " " << msg << "\n"; } -inline void dumpbits32(u32 v, const std::string &msg) { - for (u32 i = 0; i < 32; i++) { - std::cout << (((v >> (u32)i) & 0x1ULL) ? "1" : "_"); +inline void dumpbits32(uint32_t v, const std::string &msg) { + for (uint32_t i = 0; i < 32; i++) { + std::cout << (((v >> (uint32_t)i) & 0x1ULL) ? "1" : "_"); } std::cout << " " << msg << "\n"; } @@ -748,16 +748,16 @@ inline void dumpbits32(u32 v, const std::string &msg) { #endif // dump bits low to high -inline void dumpbits_always(u64 v, const std::string &msg) { - for (u32 i = 0; i < 64; i++) { - std::cout << (((v >> (u64)i) & 0x1ULL) ? "1" : "_"); +inline void dumpbits_always(uint64_t v, const std::string &msg) { + for (uint32_t i = 0; i < 64; i++) { + std::cout << (((v >> (uint64_t)i) & 0x1ULL) ? "1" : "_"); } std::cout << " " << msg << "\n"; } -inline void dumpbits32_always(u32 v, const std::string &msg) { - for (u32 i = 0; i < 32; i++) { - std::cout << (((v >> (u32)i) & 0x1ULL) ? "1" : "_"); +inline void dumpbits32_always(uint32_t v, const std::string &msg) { + for (uint32_t i = 0; i < 32; i++) { + std::cout << (((v >> (uint32_t)i) & 0x1ULL) ? "1" : "_"); } std::cout << " " << msg << "\n"; } diff --git a/include/simdjson/stage1_find_marks.h b/include/simdjson/stage1_find_marks.h index 5ac2c4ab1..1071b4e6a 100644 --- a/include/simdjson/stage1_find_marks.h +++ b/include/simdjson/stage1_find_marks.h @@ -4,9 +4,9 @@ #include "parsedjson.h" WARN_UNUSED -bool find_structural_bits(const u8 *buf, size_t len, ParsedJson &pj); +bool find_structural_bits(const uint8_t *buf, size_t len, ParsedJson &pj); WARN_UNUSED static inline bool find_structural_bits(const char *buf, size_t len, ParsedJson &pj) { - return find_structural_bits((const u8 *)buf, len, pj); + return find_structural_bits((const uint8_t *)buf, len, pj); } diff --git a/include/simdjson/stage34_unified.h b/include/simdjson/stage34_unified.h index 309e75f70..4cc11349d 100644 --- a/include/simdjson/stage34_unified.h +++ b/include/simdjson/stage34_unified.h @@ -6,10 +6,10 @@ void init_state_machine(); WARN_UNUSED -bool unified_machine(const u8 *buf, size_t len, ParsedJson &pj); +bool unified_machine(const uint8_t *buf, size_t len, ParsedJson &pj); WARN_UNUSED static inline bool unified_machine(const char *buf, size_t len, ParsedJson &pj) { - return unified_machine((const u8 *)buf,len,pj); + return unified_machine((const uint8_t *)buf,len,pj); } diff --git a/include/simdjson/stringparsing.h b/include/simdjson/stringparsing.h index bfb1b8d3c..474485481 100644 --- a/include/simdjson/stringparsing.h +++ b/include/simdjson/stringparsing.h @@ -9,7 +9,7 @@ // These chars yield themselves: " \ / // b -> backspace, f -> formfeed, n -> newline, r -> cr, t -> horizontal tab // u not handled in this table as it's complex -static const u8 escape_map[256] = { +static const uint8_t escape_map[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2f, @@ -39,8 +39,8 @@ static const u8 escape_map[256] = { // return true if the unicode codepoint was valid // We work in little-endian then swap at write time WARN_UNUSED -really_inline bool handle_unicode_codepoint(const u8 **src_ptr, u8 **dst_ptr) { - u32 code_point = hex_to_u32_nocheck(*src_ptr + 2); +really_inline bool handle_unicode_codepoint(const uint8_t **src_ptr, uint8_t **dst_ptr) { + uint32_t code_point = hex_to_u32_nocheck(*src_ptr + 2); *src_ptr += 6; // check for low surrogate for characters outside the Basic // Multilingual Plane. @@ -48,7 +48,7 @@ really_inline bool handle_unicode_codepoint(const u8 **src_ptr, u8 **dst_ptr) { if (((*src_ptr)[0] != '\\') || (*src_ptr)[1] != 'u') { return false; } - u32 code_point_2 = hex_to_u32_nocheck(*src_ptr + 2); + uint32_t code_point_2 = hex_to_u32_nocheck(*src_ptr + 2); code_point = (((code_point - 0xd800) << 10) | (code_point_2 - 0xdc00)) + 0x10000; *src_ptr += 6; @@ -59,23 +59,23 @@ really_inline bool handle_unicode_codepoint(const u8 **src_ptr, u8 **dst_ptr) { } WARN_UNUSED -really_inline bool parse_string(const u8 *buf, UNUSED size_t len, - ParsedJson &pj, UNUSED const u32 depth, u32 offset) { +really_inline bool parse_string(const uint8_t *buf, UNUSED size_t len, + ParsedJson &pj, UNUSED const uint32_t depth, uint32_t offset) { #ifdef SIMDJSON_SKIPSTRINGPARSING // for performance analysis, it is sometimes useful to skip parsing pj.write_tape(0, '"');// don't bother with the string parsing at all return true; // always succeeds #else - const u8 *src = &buf[offset + 1]; // we know that buf at offset is a " - u8 *dst = pj.current_string_buf_loc; + const uint8_t *src = &buf[offset + 1]; // we know that buf at offset is a " + uint8_t *dst = pj.current_string_buf_loc; #ifdef JSON_TEST_STRINGS // for unit testing - u8 *const start_of_string = dst; + uint8_t *const start_of_string = dst; #endif #ifdef DEBUG cout << "Entering parse string with offset " << offset << "\n"; #endif while (1) { #ifdef DEBUG - for (u32 j = 0; j < 32; j++) { + for (uint32_t j = 0; j < 32; j++) { char c = *(src + j); if (isprint(c)) { cout << c; @@ -85,12 +85,12 @@ really_inline bool parse_string(const u8 *buf, UNUSED size_t len, } cout << "| ... string handling input\n"; #endif - m256 v = _mm256_loadu_si256((const m256 *)(src)); - u32 bs_bits = - (u32)_mm256_movemask_epi8(_mm256_cmpeq_epi8(v, _mm256_set1_epi8('\\'))); + __m256i v = _mm256_loadu_si256((const __m256i *)(src)); + uint32_t bs_bits = + (uint32_t)_mm256_movemask_epi8(_mm256_cmpeq_epi8(v, _mm256_set1_epi8('\\'))); dumpbits32(bs_bits, "backslash bits 2"); - u32 quote_bits = - (u32)_mm256_movemask_epi8(_mm256_cmpeq_epi8(v, _mm256_set1_epi8('"'))); + uint32_t quote_bits = + (uint32_t)_mm256_movemask_epi8(_mm256_cmpeq_epi8(v, _mm256_set1_epi8('"'))); dumpbits32(quote_bits, "quote_bits"); #define CHECKUNESCAPED // All Unicode characters may be placed within the @@ -99,15 +99,15 @@ really_inline bool parse_string(const u8 *buf, UNUSED size_t len, //through U+001F). // https://tools.ietf.org/html/rfc8259 #ifdef CHECKUNESCAPED - m256 unitsep = _mm256_set1_epi8(0x1F); - m256 unescaped_vec = _mm256_cmpeq_epi8(_mm256_max_epu8(unitsep,v),unitsep);// could do it with saturated subtraction + __m256i unitsep = _mm256_set1_epi8(0x1F); + __m256i unescaped_vec = _mm256_cmpeq_epi8(_mm256_max_epu8(unitsep,v),unitsep);// could do it with saturated subtraction #endif // CHECKUNESCAPED - u32 quote_dist = __tzcnt_u64(quote_bits); - u32 bs_dist = __tzcnt_u64(bs_bits); + uint32_t quote_dist = __tzcnt_u64(quote_bits); + uint32_t bs_dist = __tzcnt_u64(bs_bits); // store to dest unconditionally - we can overwrite the bits we don't like // later - _mm256_storeu_si256((m256 *)(dst), v); + _mm256_storeu_si256((__m256i *)(dst), v); #ifdef DEBUG cout << "quote dist: " << quote_dist << " bs dist: " << bs_dist << "\n"; #endif @@ -124,7 +124,7 @@ really_inline bool parse_string(const u8 *buf, UNUSED size_t len, pj.current_string_buf_loc = dst + quote_dist + 1; // the +1 is due to the 0 value #ifdef CHECKUNESCAPED // check that there is no unescaped char before the quote - u32 unescaped_bits = (u32)_mm256_movemask_epi8(unescaped_vec); + uint32_t unescaped_bits = (uint32_t)_mm256_movemask_epi8(unescaped_vec); bool is_ok = ((quote_bits - 1) & (~ quote_bits) & unescaped_bits) == 0; #ifdef JSON_TEST_STRINGS // for unit testing if(is_ok) foundString(buf + offset,start_of_string,pj.current_string_buf_loc - 1); @@ -138,13 +138,13 @@ really_inline bool parse_string(const u8 *buf, UNUSED size_t len, return true; #endif //CHECKUNESCAPED } else if (quote_dist > bs_dist) { - u8 escape_char = src[bs_dist + 1]; + uint8_t escape_char = src[bs_dist + 1]; #ifdef DEBUG cout << "Found escape char: " << escape_char << "\n"; #endif #ifdef CHECKUNESCAPED // we are going to need the unescaped_bits to check for unescaped chars - u32 unescaped_bits = (u32)_mm256_movemask_epi8(unescaped_vec); + uint32_t unescaped_bits = (uint32_t)_mm256_movemask_epi8(unescaped_vec); if(((bs_bits - 1) & (~ bs_bits) & unescaped_bits) != 0) { #ifdef JSON_TEST_STRINGS // for unit testing foundBadString(buf + offset); @@ -169,7 +169,7 @@ really_inline bool parse_string(const u8 *buf, UNUSED size_t len, // write bs_dist+1 characters to output // note this may reach beyond the part of the buffer we've actually // seen. I think this is ok - u8 escape_result = escape_map[escape_char]; + uint8_t escape_result = escape_map[escape_char]; if (!escape_result) { #ifdef JSON_TEST_STRINGS // for unit testing foundBadString(buf + offset); diff --git a/src/jsonparser.cpp b/src/jsonparser.cpp index d0ef6232d..6e92c73d2 100644 --- a/src/jsonparser.cpp +++ b/src/jsonparser.cpp @@ -3,7 +3,7 @@ // parse a document found in buf, need to preallocate ParsedJson. WARN_UNUSED -bool json_parse(const u8 *buf, size_t len, ParsedJson &pj, bool reallocifneeded) { +bool json_parse(const uint8_t *buf, size_t len, ParsedJson &pj, bool reallocifneeded) { if (pj.bytecapacity < len) { std::cerr << "Your ParsedJson cannot support documents that big: " << len << std::endl; @@ -14,8 +14,8 @@ bool json_parse(const u8 *buf, size_t len, ParsedJson &pj, bool reallocifneeded) // realloc is needed if the end of the memory crosses a page long pagesize = sysconf (_SC_PAGESIZE); // on windows this should be SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); sysInfo.dwPageSize if ( (reinterpret_cast(buf + len - 1) % pagesize ) < SIMDJSON_PADDING ) { - const u8 *tmpbuf = buf; - buf = (u8 *) allocate_padded_buffer(len); + const uint8_t *tmpbuf = buf; + buf = (uint8_t *) allocate_padded_buffer(len); if(buf == NULL) return false; memcpy((void*)buf,tmpbuf,len); reallocated = true; @@ -39,7 +39,7 @@ bool json_parse(const u8 *buf, size_t len, ParsedJson &pj, bool reallocifneeded) } WARN_UNUSED -ParsedJson build_parsed_json(const u8 *buf, size_t len, bool reallocifneeded) { +ParsedJson build_parsed_json(const uint8_t *buf, size_t len, bool reallocifneeded) { ParsedJson pj; bool ok = pj.allocateCapacity(len); if(ok) { diff --git a/src/stage1_find_marks.cpp b/src/stage1_find_marks.cpp index 5f99e91cb..e4266d8f1 100644 --- a/src/stage1_find_marks.cpp +++ b/src/stage1_find_marks.cpp @@ -24,17 +24,17 @@ using namespace std; // a straightforward comparison of a mask against input. 5 uops; would be // cheaper in AVX512. -really_inline u64 cmp_mask_against_input(m256 input_lo, m256 input_hi, - m256 mask) { - m256 cmp_res_0 = _mm256_cmpeq_epi8(input_lo, mask); - u64 res_0 = (u32)_mm256_movemask_epi8(cmp_res_0); - m256 cmp_res_1 = _mm256_cmpeq_epi8(input_hi, mask); - u64 res_1 = _mm256_movemask_epi8(cmp_res_1); +really_inline uint64_t cmp_mask_against_input(__m256i input_lo, __m256i input_hi, + __m256i mask) { + __m256i cmp_res_0 = _mm256_cmpeq_epi8(input_lo, mask); + uint64_t res_0 = (uint32_t)_mm256_movemask_epi8(cmp_res_0); + __m256i cmp_res_1 = _mm256_cmpeq_epi8(input_hi, mask); + uint64_t res_1 = _mm256_movemask_epi8(cmp_res_1); return res_0 | (res_1 << 32); } WARN_UNUSED -/*never_inline*/ bool find_structural_bits(const u8 *buf, size_t len, +/*never_inline*/ bool find_structural_bits(const uint8_t *buf, size_t len, ParsedJson &pj) { if (len > pj.bytecapacity) { cerr << "Your ParsedJson object only supports documents up to "<< pj.bytecapacity << " bytes but you are trying to process " << len << " bytes\n"; @@ -49,27 +49,27 @@ WARN_UNUSED #endif // Useful constant masks - const u64 even_bits = 0x5555555555555555ULL; - const u64 odd_bits = ~even_bits; + const uint64_t even_bits = 0x5555555555555555ULL; + const uint64_t odd_bits = ~even_bits; // for now, just work in 64-byte chunks // we have padded the input out to 64 byte multiple with the remainder being // zeros // persistent state across loop - u64 prev_iter_ends_odd_backslash = 0ULL; // either 0 or 1, but a 64-bit value - u64 prev_iter_inside_quote = 0ULL; // either all zeros or all ones + uint64_t prev_iter_ends_odd_backslash = 0ULL; // either 0 or 1, but a 64-bit value + uint64_t prev_iter_inside_quote = 0ULL; // either all zeros or all ones // effectively the very first char is considered to follow "whitespace" for the // purposes of psuedo-structural character detection - u64 prev_iter_ends_pseudo_pred = 1ULL; + uint64_t prev_iter_ends_pseudo_pred = 1ULL; size_t lenminus64 = len < 64 ? 0 : len - 64; size_t idx = 0; for (; idx < lenminus64; idx += 64) { __builtin_prefetch(buf + idx + 128); #ifdef DEBUG cout << "Idx is " << idx << "\n"; - for (u32 j = 0; j < 64; j++) { + for (uint32_t j = 0; j < 64; j++) { char c = *(buf + idx + j); if (isprint(c)) { cout << c; @@ -79,10 +79,10 @@ WARN_UNUSED } cout << "| ... input\n"; #endif - m256 input_lo = _mm256_loadu_si256((const m256 *)(buf + idx + 0)); - m256 input_hi = _mm256_loadu_si256((const m256 *)(buf + idx + 32)); + __m256i input_lo = _mm256_loadu_si256((const __m256i *)(buf + idx + 0)); + __m256i input_hi = _mm256_loadu_si256((const __m256i *)(buf + idx + 32)); #ifdef SIMDJSON_UTF8VALIDATE - m256 highbit = _mm256_set1_epi8(0x80); + __m256i highbit = _mm256_set1_epi8(0x80); if((_mm256_testz_si256(_mm256_or_si256(input_lo, input_hi),highbit)) == 1) { // it is ascii, we just check continuation has_error = _mm256_or_si256( @@ -101,24 +101,24 @@ WARN_UNUSED // Step 1: detect odd sequences of backslashes //////////////////////////////////////////////////////////////////////////////////////////// - u64 bs_bits = + uint64_t bs_bits = cmp_mask_against_input(input_lo, input_hi, _mm256_set1_epi8('\\')); dumpbits(bs_bits, "backslash bits"); - u64 start_edges = bs_bits & ~(bs_bits << 1); + uint64_t start_edges = bs_bits & ~(bs_bits << 1); dumpbits(start_edges, "start_edges"); // flip lowest if we have an odd-length run at the end of the prior // iteration - u64 even_start_mask = even_bits ^ prev_iter_ends_odd_backslash; - u64 even_starts = start_edges & even_start_mask; - u64 odd_starts = start_edges & ~even_start_mask; + uint64_t even_start_mask = even_bits ^ prev_iter_ends_odd_backslash; + uint64_t even_starts = start_edges & even_start_mask; + uint64_t odd_starts = start_edges & ~even_start_mask; dumpbits(even_starts, "even_starts"); dumpbits(odd_starts, "odd_starts"); - u64 even_carries = bs_bits + even_starts; + uint64_t even_carries = bs_bits + even_starts; - u64 odd_carries; + uint64_t odd_carries; // must record the carry-out of our odd-carries out of bit 63; this // indicates whether the sense of any edge going to the next iteration // should be flipped @@ -134,31 +134,31 @@ WARN_UNUSED dumpbits(even_carries, "even_carries"); dumpbits(odd_carries, "odd_carries"); - u64 even_carry_ends = even_carries & ~bs_bits; - u64 odd_carry_ends = odd_carries & ~bs_bits; + uint64_t even_carry_ends = even_carries & ~bs_bits; + uint64_t odd_carry_ends = odd_carries & ~bs_bits; dumpbits(even_carry_ends, "even_carry_ends"); dumpbits(odd_carry_ends, "odd_carry_ends"); - u64 even_start_odd_end = even_carry_ends & odd_bits; - u64 odd_start_even_end = odd_carry_ends & even_bits; + uint64_t even_start_odd_end = even_carry_ends & odd_bits; + uint64_t odd_start_even_end = odd_carry_ends & even_bits; dumpbits(even_start_odd_end, "esoe"); dumpbits(odd_start_even_end, "osee"); - u64 odd_ends = even_start_odd_end | odd_start_even_end; + uint64_t odd_ends = even_start_odd_end | odd_start_even_end; dumpbits(odd_ends, "odd_ends"); //////////////////////////////////////////////////////////////////////////////////////////// // Step 2: detect insides of quote pairs //////////////////////////////////////////////////////////////////////////////////////////// - u64 quote_bits = + uint64_t quote_bits = cmp_mask_against_input(input_lo, input_hi, _mm256_set1_epi8('"')); quote_bits = quote_bits & ~odd_ends; dumpbits(quote_bits, "quote_bits"); - u64 quote_mask = _mm_cvtsi128_si64(_mm_clmulepi64_si128( + uint64_t quote_mask = _mm_cvtsi128_si64(_mm_clmulepi64_si128( _mm_set_epi64x(0ULL, quote_bits), _mm_set1_epi8(0xFF), 0)); quote_mask ^= prev_iter_inside_quote; - prev_iter_inside_quote = (u64)((s64)quote_mask >> 63); // right shift of a signed value expected to be well-defined and standard compliant as of C++20, John Regher from Utah U. says this is fine code + prev_iter_inside_quote = (uint64_t)((int64_t)quote_mask >> 63); // right shift of a signed value expected to be well-defined and standard compliant as of C++20, John Regher from Utah U. says this is fine code dumpbits(quote_mask, "quote_mask"); // How do we build up a user traversable data structure @@ -169,48 +169,48 @@ WARN_UNUSED // we are also interested in the four whitespace characters // space 0x20, linefeed 0x0a, horizontal tab 0x09 and carriage return 0x0d // these go into the next 2 buckets of the comparison (8/16) - const m256 low_nibble_mask = _mm256_setr_epi8( + const __m256i low_nibble_mask = _mm256_setr_epi8( // 0 9 a b c d 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 1, 2, 9, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 1, 2, 9, 0, 0); - const m256 high_nibble_mask = _mm256_setr_epi8( + const __m256i high_nibble_mask = _mm256_setr_epi8( // 0 2 3 5 7 8, 0, 18, 4, 0, 1, 0, 1, 0, 0, 0, 3, 2, 1, 0, 0, 8, 0, 18, 4, 0, 1, 0, 1, 0, 0, 0, 3, 2, 1, 0, 0); - m256 structural_shufti_mask = _mm256_set1_epi8(0x7); - m256 whitespace_shufti_mask = _mm256_set1_epi8(0x18); + __m256i structural_shufti_mask = _mm256_set1_epi8(0x7); + __m256i whitespace_shufti_mask = _mm256_set1_epi8(0x18); - m256 v_lo = _mm256_and_si256( + __m256i v_lo = _mm256_and_si256( _mm256_shuffle_epi8(low_nibble_mask, input_lo), _mm256_shuffle_epi8(high_nibble_mask, _mm256_and_si256(_mm256_srli_epi32(input_lo, 4), _mm256_set1_epi8(0x7f)))); - m256 v_hi = _mm256_and_si256( + __m256i v_hi = _mm256_and_si256( _mm256_shuffle_epi8(low_nibble_mask, input_hi), _mm256_shuffle_epi8(high_nibble_mask, _mm256_and_si256(_mm256_srli_epi32(input_hi, 4), _mm256_set1_epi8(0x7f)))); - m256 tmp_lo = _mm256_cmpeq_epi8( + __m256i tmp_lo = _mm256_cmpeq_epi8( _mm256_and_si256(v_lo, structural_shufti_mask), _mm256_set1_epi8(0)); - m256 tmp_hi = _mm256_cmpeq_epi8( + __m256i tmp_hi = _mm256_cmpeq_epi8( _mm256_and_si256(v_hi, structural_shufti_mask), _mm256_set1_epi8(0)); - u64 structural_res_0 = (u32)_mm256_movemask_epi8(tmp_lo); - u64 structural_res_1 = _mm256_movemask_epi8(tmp_hi); - u64 structurals = ~(structural_res_0 | (structural_res_1 << 32)); + uint64_t structural_res_0 = (uint32_t)_mm256_movemask_epi8(tmp_lo); + uint64_t structural_res_1 = _mm256_movemask_epi8(tmp_hi); + uint64_t structurals = ~(structural_res_0 | (structural_res_1 << 32)); // this additional mask and transfer is non-trivially expensive, // unfortunately - m256 tmp_ws_lo = _mm256_cmpeq_epi8( + __m256i tmp_ws_lo = _mm256_cmpeq_epi8( _mm256_and_si256(v_lo, whitespace_shufti_mask), _mm256_set1_epi8(0)); - m256 tmp_ws_hi = _mm256_cmpeq_epi8( + __m256i tmp_ws_hi = _mm256_cmpeq_epi8( _mm256_and_si256(v_hi, whitespace_shufti_mask), _mm256_set1_epi8(0)); - u64 ws_res_0 = (u32)_mm256_movemask_epi8(tmp_ws_lo); - u64 ws_res_1 = _mm256_movemask_epi8(tmp_ws_hi); - u64 whitespace = ~(ws_res_0 | (ws_res_1 << 32)); + uint64_t ws_res_0 = (uint32_t)_mm256_movemask_epi8(tmp_ws_lo); + uint64_t ws_res_1 = _mm256_movemask_epi8(tmp_ws_hi); + uint64_t whitespace = ~(ws_res_0 | (ws_res_1 << 32)); dumpbits(structurals, "structurals"); dumpbits(whitespace, "whitespace"); @@ -232,12 +232,12 @@ WARN_UNUSED // a qualified predecessor is something that can happen 1 position before an // psuedo-structural character - u64 pseudo_pred = structurals | whitespace; + uint64_t pseudo_pred = structurals | whitespace; dumpbits(pseudo_pred, "pseudo_pred"); - u64 shifted_pseudo_pred = (pseudo_pred << 1) | prev_iter_ends_pseudo_pred; + uint64_t shifted_pseudo_pred = (pseudo_pred << 1) | prev_iter_ends_pseudo_pred; dumpbits(shifted_pseudo_pred, "shifted_pseudo_pred"); prev_iter_ends_pseudo_pred = pseudo_pred >> 63; - u64 pseudo_structurals = + uint64_t pseudo_structurals = shifted_pseudo_pred & (~whitespace) & (~quote_mask); dumpbits(pseudo_structurals, "pseudo_structurals"); dumpbits(structurals, "final structurals without pseudos"); @@ -250,7 +250,7 @@ WARN_UNUSED dumpbits( structurals, "final structurals and pseudo structurals after close quote removal"); - *(u64 *)(pj.structurals + idx / 8) = structurals; + *(uint64_t *)(pj.structurals + idx / 8) = structurals; } //////////////// @@ -259,13 +259,13 @@ WARN_UNUSED /// risk invalidating the UTF-8 checks. //////////// if (idx < len) { - u8 tmpbuf[64]; + uint8_t tmpbuf[64]; memset(tmpbuf,0x20,64); memcpy(tmpbuf,buf+idx,len - idx); - m256 input_lo = _mm256_loadu_si256((const m256 *)(tmpbuf + 0)); - m256 input_hi = _mm256_loadu_si256((const m256 *)(tmpbuf + 32)); + __m256i input_lo = _mm256_loadu_si256((const __m256i *)(tmpbuf + 0)); + __m256i input_hi = _mm256_loadu_si256((const __m256i *)(tmpbuf + 32)); #ifdef SIMDJSON_UTF8VALIDATE - m256 highbit = _mm256_set1_epi8(0x80); + __m256i highbit = _mm256_set1_epi8(0x80); if((_mm256_testz_si256(_mm256_or_si256(input_lo, input_hi),highbit)) == 1) { // it is ascii, we just check continuation has_error = _mm256_or_si256( @@ -284,17 +284,17 @@ WARN_UNUSED // Step 1: detect odd sequences of backslashes //////////////////////////////////////////////////////////////////////////////////////////// - u64 bs_bits = + uint64_t bs_bits = cmp_mask_against_input(input_lo, input_hi, _mm256_set1_epi8('\\')); - u64 start_edges = bs_bits & ~(bs_bits << 1); + uint64_t start_edges = bs_bits & ~(bs_bits << 1); // flip lowest if we have an odd-length run at the end of the prior // iteration - u64 even_start_mask = even_bits ^ prev_iter_ends_odd_backslash; - u64 even_starts = start_edges & even_start_mask; - u64 odd_starts = start_edges & ~even_start_mask; - u64 even_carries = bs_bits + even_starts; + uint64_t even_start_mask = even_bits ^ prev_iter_ends_odd_backslash; + uint64_t even_starts = start_edges & even_start_mask; + uint64_t odd_starts = start_edges & ~even_start_mask; + uint64_t even_carries = bs_bits + even_starts; - u64 odd_carries; + uint64_t odd_carries; // must record the carry-out of our odd-carries out of bit 63; this // indicates whether the sense of any edge going to the next iteration // should be flipped @@ -306,23 +306,23 @@ WARN_UNUSED // if we had an odd-numbered run at the // end of the previous iteration //prev_iter_ends_odd_backslash = iter_ends_odd_backslash ? 0x1ULL : 0x0ULL; - u64 even_carry_ends = even_carries & ~bs_bits; - u64 odd_carry_ends = odd_carries & ~bs_bits; - u64 even_start_odd_end = even_carry_ends & odd_bits; - u64 odd_start_even_end = odd_carry_ends & even_bits; - u64 odd_ends = even_start_odd_end | odd_start_even_end; + uint64_t even_carry_ends = even_carries & ~bs_bits; + uint64_t odd_carry_ends = odd_carries & ~bs_bits; + uint64_t even_start_odd_end = even_carry_ends & odd_bits; + uint64_t odd_start_even_end = odd_carry_ends & even_bits; + uint64_t odd_ends = even_start_odd_end | odd_start_even_end; //////////////////////////////////////////////////////////////////////////////////////////// // Step 2: detect insides of quote pairs //////////////////////////////////////////////////////////////////////////////////////////// - u64 quote_bits = + uint64_t quote_bits = cmp_mask_against_input(input_lo, input_hi, _mm256_set1_epi8('"')); quote_bits = quote_bits & ~odd_ends; - u64 quote_mask = _mm_cvtsi128_si64(_mm_clmulepi64_si128( + uint64_t quote_mask = _mm_cvtsi128_si64(_mm_clmulepi64_si128( _mm_set_epi64x(0ULL, quote_bits), _mm_set1_epi8(0xFF), 0)); quote_mask ^= prev_iter_inside_quote; - //prev_iter_inside_quote = (u64)((s64)quote_mask >> 63); // right shift of a signed value expected to be well-defined and standard compliant as of C++20 + //prev_iter_inside_quote = (uint64_t)((int64_t)quote_mask >> 63); // right shift of a signed value expected to be well-defined and standard compliant as of C++20 // How do we build up a user traversable data structure // first, do a 'shufti' to detect structural JSON characters @@ -332,48 +332,48 @@ WARN_UNUSED // we are also interested in the four whitespace characters // space 0x20, linefeed 0x0a, horizontal tab 0x09 and carriage return 0x0d // these go into the next 2 buckets of the comparison (8/16) - const m256 low_nibble_mask = _mm256_setr_epi8( + const __m256i low_nibble_mask = _mm256_setr_epi8( // 0 9 a b c d 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 1, 2, 9, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 1, 2, 9, 0, 0); - const m256 high_nibble_mask = _mm256_setr_epi8( + const __m256i high_nibble_mask = _mm256_setr_epi8( // 0 2 3 5 7 8, 0, 18, 4, 0, 1, 0, 1, 0, 0, 0, 3, 2, 1, 0, 0, 8, 0, 18, 4, 0, 1, 0, 1, 0, 0, 0, 3, 2, 1, 0, 0); - m256 structural_shufti_mask = _mm256_set1_epi8(0x7); - m256 whitespace_shufti_mask = _mm256_set1_epi8(0x18); + __m256i structural_shufti_mask = _mm256_set1_epi8(0x7); + __m256i whitespace_shufti_mask = _mm256_set1_epi8(0x18); - m256 v_lo = _mm256_and_si256( + __m256i v_lo = _mm256_and_si256( _mm256_shuffle_epi8(low_nibble_mask, input_lo), _mm256_shuffle_epi8(high_nibble_mask, _mm256_and_si256(_mm256_srli_epi32(input_lo, 4), _mm256_set1_epi8(0x7f)))); - m256 v_hi = _mm256_and_si256( + __m256i v_hi = _mm256_and_si256( _mm256_shuffle_epi8(low_nibble_mask, input_hi), _mm256_shuffle_epi8(high_nibble_mask, _mm256_and_si256(_mm256_srli_epi32(input_hi, 4), _mm256_set1_epi8(0x7f)))); - m256 tmp_lo = _mm256_cmpeq_epi8( + __m256i tmp_lo = _mm256_cmpeq_epi8( _mm256_and_si256(v_lo, structural_shufti_mask), _mm256_set1_epi8(0)); - m256 tmp_hi = _mm256_cmpeq_epi8( + __m256i tmp_hi = _mm256_cmpeq_epi8( _mm256_and_si256(v_hi, structural_shufti_mask), _mm256_set1_epi8(0)); - u64 structural_res_0 = (u32)_mm256_movemask_epi8(tmp_lo); - u64 structural_res_1 = _mm256_movemask_epi8(tmp_hi); - u64 structurals = ~(structural_res_0 | (structural_res_1 << 32)); + uint64_t structural_res_0 = (uint32_t)_mm256_movemask_epi8(tmp_lo); + uint64_t structural_res_1 = _mm256_movemask_epi8(tmp_hi); + uint64_t structurals = ~(structural_res_0 | (structural_res_1 << 32)); // this additional mask and transfer is non-trivially expensive, // unfortunately - m256 tmp_ws_lo = _mm256_cmpeq_epi8( + __m256i tmp_ws_lo = _mm256_cmpeq_epi8( _mm256_and_si256(v_lo, whitespace_shufti_mask), _mm256_set1_epi8(0)); - m256 tmp_ws_hi = _mm256_cmpeq_epi8( + __m256i tmp_ws_hi = _mm256_cmpeq_epi8( _mm256_and_si256(v_hi, whitespace_shufti_mask), _mm256_set1_epi8(0)); - u64 ws_res_0 = (u32)_mm256_movemask_epi8(tmp_ws_lo); - u64 ws_res_1 = _mm256_movemask_epi8(tmp_ws_hi); - u64 whitespace = ~(ws_res_0 | (ws_res_1 << 32)); + uint64_t ws_res_0 = (uint32_t)_mm256_movemask_epi8(tmp_ws_lo); + uint64_t ws_res_1 = _mm256_movemask_epi8(tmp_ws_hi); + uint64_t whitespace = ~(ws_res_0 | (ws_res_1 << 32)); // mask off anything inside quotes @@ -393,17 +393,17 @@ WARN_UNUSED // a qualified predecessor is something that can happen 1 position before an // psuedo-structural character - u64 pseudo_pred = structurals | whitespace; - u64 shifted_pseudo_pred = (pseudo_pred << 1) | prev_iter_ends_pseudo_pred; + uint64_t pseudo_pred = structurals | whitespace; + uint64_t shifted_pseudo_pred = (pseudo_pred << 1) | prev_iter_ends_pseudo_pred; //prev_iter_ends_pseudo_pred = pseudo_pred >> 63; - u64 pseudo_structurals = + uint64_t pseudo_structurals = shifted_pseudo_pred & (~whitespace) & (~quote_mask); structurals |= pseudo_structurals; // now, we've used our close quotes all we need to. So let's switch them off // they will be off in the quote mask and on in quote bits. structurals &= ~(quote_bits & ~quote_mask); - *(u64 *)(pj.structurals + idx / 8) = structurals; + *(uint64_t *)(pj.structurals + idx / 8) = structurals; } #ifdef SIMDJSON_UTF8VALIDATE return _mm256_testz_si256(has_error, has_error); diff --git a/src/stage2_flatten.cpp b/src/stage2_flatten.cpp index a9c753786..eb0668566 100644 --- a/src/stage2_flatten.cpp +++ b/src/stage2_flatten.cpp @@ -20,7 +20,7 @@ #endif #define SET_BIT(i) \ - base_ptr[base + i] = (u32)idx + __tzcnt_u64(s); \ + base_ptr[base + i] = (uint32_t)idx + __tzcnt_u64(s); \ s = s & (s - 1); #define SET_BIT1 SET_BIT(0) @@ -50,16 +50,16 @@ // implementation WARN_UNUSED bool flatten_indexes(size_t len, ParsedJson &pj) { - u32 *base_ptr = pj.structural_indexes; - u32 base = 0; + uint32_t *base_ptr = pj.structural_indexes; + uint32_t base = 0; #ifdef BUILDHISTOGRAM uint32_t counters[66]; uint32_t total = 0; for (int k = 0; k < 66; k++) counters[k] = 0; for (size_t idx = 0; idx < len; idx += 64) { - u64 s = *(u64 *)(pj.structurals + idx / 8); - u32 cnt = __builtin_popcountll(s); + uint64_t s = *(uint64_t *)(pj.structurals + idx / 8); + uint32_t cnt = __builtin_popcountll(s); total++; counters[cnt]++; } @@ -71,46 +71,46 @@ bool flatten_indexes(size_t len, ParsedJson &pj) { printf("\n\n"); #endif for (size_t idx = 0; idx < len; idx += 64) { - u64 s = *(u64 *)(pj.structurals + idx / 8); + uint64_t s = *(uint64_t *)(pj.structurals + idx / 8); #ifdef SUPPRESS_CHEESY_FLATTEN while (s) { - base_ptr[base++] = (u32)idx + __builtin_ctzll(s); + base_ptr[base++] = (uint32_t)idx + __builtin_ctzll(s); s &= s - 1ULL; } #elif defined(NO_PDEP_PLEASE) - u32 cnt = __builtin_popcountll(s); - u32 next_base = base + cnt; + uint32_t cnt = __builtin_popcountll(s); + uint32_t next_base = base + cnt; while (s) { CALL(SET_BITLOOPN, NO_PDEP_WIDTH) /*for(size_t i = 0; i < NO_PDEP_WIDTH; i++) { - base_ptr[base+i] = (u32)idx + __builtin_ctzll(s); + base_ptr[base+i] = (uint32_t)idx + __builtin_ctzll(s); s = s & (s - 1); }*/ base += NO_PDEP_WIDTH; } base = next_base; #else - u32 cnt = __builtin_popcountll(s); - u32 next_base = base + cnt; + uint32_t cnt = __builtin_popcountll(s); + uint32_t next_base = base + cnt; while (s) { // spoil the suspense by reducing dependency chains; actually a win even // with cost of pdep - u64 s3 = _pdep_u64(~0x7ULL, s); // s3 will have bottom 3 1-bits unset - u64 s5 = _pdep_u64(~0x1fULL, s); // s5 will have bottom 5 1-bits unset + uint64_t s3 = _pdep_u64(~0x7ULL, s); // s3 will have bottom 3 1-bits unset + uint64_t s5 = _pdep_u64(~0x1fULL, s); // s5 will have bottom 5 1-bits unset - base_ptr[base + 0] = (u32)idx + __builtin_ctzll(s); - u64 s1 = s & (s - 1ULL); - base_ptr[base + 1] = (u32)idx + __builtin_ctzll(s1); - u64 s2 = s1 & (s1 - 1ULL); + base_ptr[base + 0] = (uint32_t)idx + __builtin_ctzll(s); + uint64_t s1 = s & (s - 1ULL); + base_ptr[base + 1] = (uint32_t)idx + __builtin_ctzll(s1); + uint64_t s2 = s1 & (s1 - 1ULL); base_ptr[base + 2] = - (u32)idx + __builtin_ctzll(s2); // u64 s3 = s2 & (s2 - 1ULL); - base_ptr[base + 3] = (u32)idx + __builtin_ctzll(s3); - u64 s4 = s3 & (s3 - 1ULL); + (uint32_t)idx + __builtin_ctzll(s2); // uint64_t s3 = s2 & (s2 - 1ULL); + base_ptr[base + 3] = (uint32_t)idx + __builtin_ctzll(s3); + uint64_t s4 = s3 & (s3 - 1ULL); base_ptr[base + 4] = - (u32)idx + __builtin_ctzll(s4); // u64 s5 = s4 & (s4 - 1ULL); - base_ptr[base + 5] = (u32)idx + __builtin_ctzll(s5); - u64 s6 = s5 & (s5 - 1ULL); + (uint32_t)idx + __builtin_ctzll(s4); // uint64_t s5 = s4 & (s4 - 1ULL); + base_ptr[base + 5] = (uint32_t)idx + __builtin_ctzll(s5); + uint64_t s6 = s5 & (s5 - 1ULL); s = s6; base += 6; } diff --git a/src/stage34_unified.cpp b/src/stage34_unified.cpp index 257864378..14c2e952d 100644 --- a/src/stage34_unified.cpp +++ b/src/stage34_unified.cpp @@ -33,36 +33,36 @@ using namespace std; WARN_UNUSED -really_inline bool is_valid_true_atom(const u8 *loc) { - u64 tv = *(const u64 *)"true "; - u64 mask4 = 0x00000000ffffffff; - u32 error = 0; - u64 locval; // we want to avoid unaligned 64-bit loads (undefined in C/C++) - std::memcpy(&locval, loc, sizeof(u64)); +really_inline bool is_valid_true_atom(const uint8_t *loc) { + uint64_t tv = *(const uint64_t *)"true "; + uint64_t mask4 = 0x00000000ffffffff; + uint32_t error = 0; + uint64_t locval; // we want to avoid unaligned 64-bit loads (undefined in C/C++) + std::memcpy(&locval, loc, sizeof(uint64_t)); error = (locval & mask4) ^ tv; error |= is_not_structural_or_whitespace(loc[4]); return error == 0; } WARN_UNUSED -really_inline bool is_valid_false_atom(const u8 *loc) { - u64 fv = *(const u64 *)"false "; - u64 mask5 = 0x000000ffffffffff; - u32 error = 0; - u64 locval; // we want to avoid unaligned 64-bit loads (undefined in C/C++) - std::memcpy(&locval, loc, sizeof(u64)); +really_inline bool is_valid_false_atom(const uint8_t *loc) { + uint64_t fv = *(const uint64_t *)"false "; + uint64_t mask5 = 0x000000ffffffffff; + uint32_t error = 0; + uint64_t locval; // we want to avoid unaligned 64-bit loads (undefined in C/C++) + std::memcpy(&locval, loc, sizeof(uint64_t)); error = (locval & mask5) ^ fv; error |= is_not_structural_or_whitespace(loc[5]); return error == 0; } WARN_UNUSED -really_inline bool is_valid_null_atom(const u8 *loc) { - u64 nv = *(const u64 *)"null "; - u64 mask4 = 0x00000000ffffffff; - u32 error = 0; - u64 locval; // we want to avoid unaligned 64-bit loads (undefined in C/C++) - std::memcpy(&locval, loc, sizeof(u64)); +really_inline bool is_valid_null_atom(const uint8_t *loc) { + uint64_t nv = *(const uint64_t *)"null "; + uint64_t mask4 = 0x00000000ffffffff; + uint32_t error = 0; + uint64_t locval; // we want to avoid unaligned 64-bit loads (undefined in C/C++) + std::memcpy(&locval, loc, sizeof(uint64_t)); error = (locval & mask4) ^ nv; error |= is_not_structural_or_whitespace(loc[4]); return error == 0; @@ -77,12 +77,12 @@ really_inline bool is_valid_null_atom(const u8 *loc) { // also in Intel's compiler), but won't work in MSVC. This would need to be // reimplemented differently if one wants to be standard compliant. WARN_UNUSED -bool unified_machine(const u8 *buf, size_t len, ParsedJson &pj) { - u32 i = 0; // index of the structural character (0,1,2,3...) - u32 idx; // location of the structural character in the input (buf) - u8 c; // used to track the (structural) character we are looking at, updated +bool unified_machine(const uint8_t *buf, size_t len, ParsedJson &pj) { + uint32_t i = 0; // index of the structural character (0,1,2,3...) + uint32_t idx; // location of the structural character in the input (buf) + uint8_t c; // used to track the (structural) character we are looking at, updated // by UPDATE_CHAR macro - u32 depth = 0; // could have an arbitrary starting depth + uint32_t depth = 0; // could have an arbitrary starting depth pj.init(); if(pj.bytecapacity < len) { printf("insufficient capacity\n"); @@ -151,7 +151,7 @@ bool unified_machine(const u8 *buf, size_t len, ParsedJson &pj) { if(copy == NULL) goto fail; memcpy(copy, buf, len); copy[len] = '\0'; - if (!is_valid_true_atom((const u8 *)copy + idx)) { + if (!is_valid_true_atom((const uint8_t *)copy + idx)) { free(copy); goto fail; } @@ -167,7 +167,7 @@ bool unified_machine(const u8 *buf, size_t len, ParsedJson &pj) { if(copy == NULL) goto fail; memcpy(copy, buf, len); copy[len] = '\0'; - if (!is_valid_false_atom((const u8 *)copy + idx)) { + if (!is_valid_false_atom((const uint8_t *)copy + idx)) { free(copy); goto fail; } @@ -183,7 +183,7 @@ bool unified_machine(const u8 *buf, size_t len, ParsedJson &pj) { if(copy == NULL) goto fail; memcpy(copy, buf, len); copy[len] = '\0'; - if (!is_valid_null_atom((const u8 *)copy + idx)) { + if (!is_valid_null_atom((const uint8_t *)copy + idx)) { free(copy); goto fail; } @@ -208,7 +208,7 @@ bool unified_machine(const u8 *buf, size_t len, ParsedJson &pj) { if(copy == NULL) goto fail; memcpy(copy, buf, len); copy[len] = '\0'; - if (!parse_number((const u8 *)copy, pj, idx, false)) { + if (!parse_number((const uint8_t *)copy, pj, idx, false)) { free(copy); goto fail; } @@ -223,7 +223,7 @@ bool unified_machine(const u8 *buf, size_t len, ParsedJson &pj) { if(copy == NULL) goto fail; memcpy(copy, buf, len); copy[len] = '\0'; - if (!parse_number((const u8 *)copy, pj, idx, true)) { + if (!parse_number((const uint8_t *)copy, pj, idx, true)) { free(copy); goto fail; } diff --git a/tests/numberparsingcheck.cpp b/tests/numberparsingcheck.cpp index 48acfa210..ba32ca16f 100644 --- a/tests/numberparsingcheck.cpp +++ b/tests/numberparsingcheck.cpp @@ -37,7 +37,7 @@ bool is_in_bad_list(const char *buf) { return false; } -inline void foundInvalidNumber(const u8 *buf) { +inline void foundInvalidNumber(const uint8_t *buf) { invalid_count++; char *endptr; double expected = strtod((const char *)buf, &endptr); @@ -52,7 +52,7 @@ inline void foundInvalidNumber(const u8 *buf) { } } -inline void foundInteger(int64_t result, const u8 *buf) { +inline void foundInteger(int64_t result, const uint8_t *buf) { int_count++; char *endptr; long long expected = strtoll((const char *)buf, &endptr, 10); @@ -63,7 +63,7 @@ inline void foundInteger(int64_t result, const u8 *buf) { } } -inline void foundFloat(double result, const u8 *buf) { +inline void foundFloat(double result, const uint8_t *buf) { char *endptr; float_count++; double expected = strtod((const char *)buf, &endptr); diff --git a/tests/stringparsingcheck.cpp b/tests/stringparsingcheck.cpp index 7c4f76290..2ea9788cb 100644 --- a/tests/stringparsingcheck.cpp +++ b/tests/stringparsingcheck.cpp @@ -202,7 +202,7 @@ static bool parse_string(const char *p, char *output, char **end) { // end of borrowed code char * bigbuffer; // global variable -inline void foundBadString(const u8 *buf) { +inline void foundBadString(const uint8_t *buf) { bad_string++; char *end; if (parse_string((const char *)buf, bigbuffer, &end)) { @@ -225,8 +225,8 @@ void print_cmp_hex(const char *s1, const char *s2, size_t len) { } } -inline void foundString(const u8 *buf, const u8 *parsed_begin, - const u8 *parsed_end) { +inline void foundString(const uint8_t *buf, const uint8_t *parsed_begin, + const uint8_t *parsed_end) { size_t thislen = parsed_end - parsed_begin; total_string_length += thislen; good_string++; diff --git a/tools/jsonstats.cpp b/tools/jsonstats.cpp index 4697242e0..63c37b830 100644 --- a/tools/jsonstats.cpp +++ b/tools/jsonstats.cpp @@ -6,7 +6,7 @@ using namespace std; -size_t count_nonasciibytes(const u8* input, size_t length) { +size_t count_nonasciibytes(const uint8_t* input, size_t length) { size_t count = 0; for(size_t i = 0; i < length; i++) { count += input[i] >> 7; @@ -15,7 +15,7 @@ size_t count_nonasciibytes(const u8* input, size_t length) { } -size_t count_backslash(const u8* input, size_t length) { +size_t count_backslash(const uint8_t* input, size_t length) { size_t count = 0; for(size_t i = 0; i < length; i++) { count += (input[i] == '\\') ? 1 : 0; @@ -51,8 +51,8 @@ stat_t simdjson_computestats(const std::string_view &p) { if (!answer.valid) { return answer; } - answer.backslash_count = count_backslash((const u8*)p.data(), p.size()); - answer.nonasciibyte_count = count_nonasciibytes((const u8*)p.data(), p.size()); + answer.backslash_count = count_backslash((const uint8_t*)p.data(), p.size()); + answer.nonasciibyte_count = count_nonasciibytes((const uint8_t*)p.data(), p.size()); answer.byte_count = p.size(); answer.integer_count = 0; answer.float_count = 0; @@ -64,14 +64,14 @@ stat_t simdjson_computestats(const std::string_view &p) { answer.string_count = 0; answer.structural_indexes_count = pj.n_structural_indexes; size_t tapeidx = 0; - u64 tape_val = pj.tape[tapeidx++]; - u8 type = (tape_val >> 56); + uint64_t tape_val = pj.tape[tapeidx++]; + uint8_t type = (tape_val >> 56); size_t howmany = 0; assert(type == 'r'); howmany = tape_val & JSONVALUEMASK; for (; tapeidx < howmany; tapeidx++) { tape_val = pj.tape[tapeidx]; - // u64 payload = tape_val & JSONVALUEMASK; + // uint64_t payload = tape_val & JSONVALUEMASK; type = (tape_val >> 56); switch (type) { case 'l': // we have a long int