Skip to content

Commit 5f20d3e

Browse files
ioioioiolemire
authored andcommitted
Merging No duplicate tail (PR#223) (simdjson#232)
* Use __forceinline on Windows for really_inline https://docs.microsoft.com/en-us/cpp/cpp/inline-functions-cpp?view=vs-2019#inline-__inline-and-__forceinline * Don't duplicate find_structural_bits for final chunk * writing coherent macro definitions
1 parent 3c0f5a3 commit 5f20d3e

2 files changed

Lines changed: 61 additions & 63 deletions

File tree

include/simdjson/stage1_find_marks.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,6 @@ int find_structural_bits(const char *buf, size_t len, simdjson::ParsedJson &pj)
122122
return find_structural_bits((const uint8_t*)buf, len, pj);
123123
}
124124

125-
126125
} // namespace simdjson
127126

128-
129-
130-
131-
132-
133-
134127
#endif

include/simdjson/stage1_find_marks_macros.h

Lines changed: 61 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,60 @@
8282
return quote_mask; \
8383
} \
8484

85+
// Find structural bits in a 64-byte chunk.
86+
// We need to compile that code for multiple architectures. However, target attributes can be used
87+
// only once by function definition. Huge macro seemed better than huge code duplication.
88+
// void FIND_STRUCTURAL_BITS_64(architecture T,
89+
// const uint8_t *buf,
90+
// size_t idx,
91+
// uint32_t *base_ptr,
92+
// uint32_t &base,
93+
// uint64_t &prev_iter_ends_odd_backslash,
94+
// uint64_t &prev_iter_inside_quote,
95+
// uint64_t &prev_iter_ends_pseudo_pred,
96+
// uint64_t &structurals,
97+
// uint64_t &error_mask,
98+
// utf8_checking_state<T> &utf8_state, flatten function)
99+
#define FIND_STRUCTURAL_BITS_64(T, \
100+
buf, \
101+
idx, \
102+
base_ptr, \
103+
base, \
104+
prev_iter_ends_odd_backslash, \
105+
prev_iter_inside_quote, \
106+
prev_iter_ends_pseudo_pred, \
107+
structurals, \
108+
error_mask, \
109+
utf8_state, \
110+
flat \
111+
) { \
112+
simd_input<T> in = fill_input<T>(buf); \
113+
check_utf8<T>(in, utf8_state); \
114+
/* detect odd sequences of backslashes */ \
115+
uint64_t odd_ends = find_odd_backslash_sequences<T>(in, prev_iter_ends_odd_backslash); \
116+
\
117+
/* detect insides of quote pairs ("quote_mask") and also our quote_bits */ \
118+
/* themselves */ \
119+
uint64_t quote_bits; \
120+
uint64_t quote_mask = find_quote_mask_and_bits<T>( \
121+
in, odd_ends, prev_iter_inside_quote, quote_bits, error_mask); \
122+
\
123+
/* take the previous iterations structural bits, not our current iteration, */ \
124+
/* and flatten */ \
125+
flat(base_ptr, base, idx, structurals); \
126+
\
127+
uint64_t whitespace; \
128+
find_whitespace_and_structurals<T>(in, whitespace, structurals); \
129+
\
130+
/* fixup structurals to reflect quotes and add pseudo-structural characters */ \
131+
structurals = finalize_structurals(structurals, whitespace, quote_mask, \
132+
quote_bits, prev_iter_ends_pseudo_pred); \
133+
} \
85134

86135

87136
// We need to compile that code for multiple architectures. However, target attributes can be used
88137
// only once by function definition. Huge macro seemed better than huge code duplication.
89-
// FIND_STRUCTURAL_BITS(architecture T, const uint8_t *buf, size_t len, ParsedJson &pj)
138+
// errorValues FIND_STRUCTURAL_BITS(architecture T, const uint8_t *buf, size_t len, ParsedJson &pj, flatten functio )
90139
#define FIND_STRUCTURAL_BITS(T, buf, len, pj, flat) { \
91140
if (len > pj.bytecapacity) { \
92141
std::cerr << "Your ParsedJson object only supports documents up to " \
@@ -96,7 +145,7 @@
96145
} \
97146
uint32_t *base_ptr = pj.structural_indexes; \
98147
uint32_t base = 0; \
99-
utf8_checking_state<T> state; \
148+
utf8_checking_state<T> utf8_state; \
100149
\
101150
/* we have padded the input out to 64 byte multiple with the remainder being */ \
102151
/* zeros */ \
@@ -126,63 +175,19 @@
126175
uint64_t error_mask = 0; /* for unescaped characters within strings (ASCII code points < 0x20) */ \
127176
\
128177
for (; idx < lenminus64; idx += 64) { \
129-
\
130-
simd_input<T> in = fill_input<T>(buf+idx); \
131-
check_utf8<T>(in, state); \
132-
/* detect odd sequences of backslashes */ \
133-
uint64_t odd_ends = find_odd_backslash_sequences<T>( \
134-
in, prev_iter_ends_odd_backslash); \
135-
\
136-
/* detect insides of quote pairs ("quote_mask") and also our quote_bits */ \
137-
/* themselves */ \
138-
uint64_t quote_bits; \
139-
uint64_t quote_mask = find_quote_mask_and_bits<T>( \
140-
in, odd_ends, prev_iter_inside_quote, quote_bits, error_mask); \
141-
\
142-
/* take the previous iterations structural bits, not our current iteration, */ \
143-
/* and flatten */ \
144-
flat(base_ptr, base, idx, structurals); \
145-
\
146-
uint64_t whitespace; \
147-
find_whitespace_and_structurals<T>(in, whitespace, structurals); \
148-
\
149-
/* fixup structurals to reflect quotes and add pseudo-structural characters */ \
150-
structurals = finalize_structurals(structurals, whitespace, quote_mask, \
151-
quote_bits, prev_iter_ends_pseudo_pred); \
178+
FIND_STRUCTURAL_BITS_64(T, &buf[idx], idx, base_ptr, base, prev_iter_ends_odd_backslash, \
179+
prev_iter_inside_quote, prev_iter_ends_pseudo_pred, structurals, \
180+
error_mask, utf8_state, flat); \
152181
} \
153-
\
154-
/*////////////// */ \
155-
/*/ we use a giant copy-paste which is ugly. */ \
156-
/*/ but otherwise the string needs to be properly padded or else we */ \
157-
/*/ risk invalidating the UTF-8 checks. */ \
158-
/*////////// */ \
182+
/* If we have a final chunk of less than 64 bytes, pad it to 64 with spaces */ \
183+
/* before processing it (otherwise, we risk invalidating the UTF-8 checks). */ \
159184
if (idx < len) { \
160185
uint8_t tmpbuf[64]; \
161186
memset(tmpbuf, 0x20, 64); \
162187
memcpy(tmpbuf, buf + idx, len - idx); \
163-
simd_input<T> in = fill_input<T>(tmpbuf); \
164-
check_utf8<T>(in, state); \
165-
\
166-
/* detect odd sequences of backslashes */ \
167-
uint64_t odd_ends = find_odd_backslash_sequences<T>( \
168-
in, prev_iter_ends_odd_backslash); \
169-
\
170-
/* detect insides of quote pairs ("quote_mask") and also our quote_bits */ \
171-
/* themselves */ \
172-
uint64_t quote_bits; \
173-
uint64_t quote_mask = find_quote_mask_and_bits<T>( \
174-
in, odd_ends, prev_iter_inside_quote, quote_bits, error_mask); \
175-
\
176-
/* take the previous iterations structural bits, not our current iteration, */ \
177-
/* and flatten */ \
178-
flat(base_ptr, base, idx, structurals); \
179-
\
180-
uint64_t whitespace; \
181-
find_whitespace_and_structurals<T>(in, whitespace, structurals); \
182-
\
183-
/* fixup structurals to reflect quotes and add pseudo-structural characters */ \
184-
structurals = finalize_structurals(structurals, whitespace, quote_mask, \
185-
quote_bits, prev_iter_ends_pseudo_pred); \
188+
FIND_STRUCTURAL_BITS_64(T, &tmpbuf[0], idx, base_ptr, base, prev_iter_ends_odd_backslash, \
189+
prev_iter_inside_quote, prev_iter_ends_pseudo_pred, structurals, \
190+
error_mask, utf8_state, flat); \
186191
idx += 64; \
187192
} \
188193
\
@@ -192,7 +197,7 @@
192197
} \
193198
\
194199
/* finally, flatten out the remaining structurals from the last iteration */ \
195-
flat(base_ptr, base, idx, structurals); \
200+
flat(base_ptr, base, idx, structurals); \
196201
\
197202
pj.n_structural_indexes = base; \
198203
/* a valid JSON file cannot have zero structural indexes - we should have */ \
@@ -213,7 +218,7 @@
213218
if (error_mask) { \
214219
return simdjson::UNESCAPED_CHARS; \
215220
} \
216-
return check_utf8_errors<T>(state); \
221+
return check_utf8_errors<T>(utf8_state); \
217222
}
218223

219224

0 commit comments

Comments
 (0)