mirror of
https://github.com/simdjson/simdjson
synced 2026-06-08 17:27:07 +00:00
5510089d45
* Rename simdjson_really_inline -> simdjson_inline I want to change the simdjson_really_inline macro to sometimes not force inlining. After that upcoming change, the name simdjson_really_inline will no longer makes sense. Rename simdjson_really_inline to simdjson_inline. This patch should not change semantics; simdjson_inline still forces inlining as before. Some functions still need to be really inlined for ABI reasons. (GCC's -Wpsabi complains otherwise.) Leave those functions marked as simdjson_really_inline. * Improve build times for debug builds simdjson_inline is used for most simdjson functions. It forces inlining. In unoptimized/debug builds, this can lead to a lot of machine code being generated (especially with Address Sanitizer), causing slow compilation. Change simdjson_inline to force inlining only for optimized builds. Sometimes, the programmer might want a slightly-optimized build and want fast compilation (e.g. GCC's -Og mode). Allow simdjson users to define the simdjson_inline macro themselves (e.g. on the command line: -Dsimdjson_inline=inline) in cases where the default behavior is undesired. This patch reduced build times by over 75% for ondemand_object_tests.cpp with GCC 9.4.0 and CMAKE_BUILD_TYPE=Debug on my AMD 5950X: Before: 6.885 6.683 6.971 6.957 6.949 seconds (5 samples) After: 1.492 1.551 1.494 1.490 1.531 seconds (5 samples)
82 lines
3.4 KiB
C++
82 lines
3.4 KiB
C++
#include "simdjson/base.h"
|
|
#include "simdjson/internal/isadetection.h"
|
|
|
|
namespace simdjson {
|
|
namespace SIMDJSON_IMPLEMENTATION {
|
|
|
|
// expectation: sizeof(open_container) = 64/8.
|
|
struct open_container {
|
|
uint32_t tape_index; // where, on the tape, does the scope ([,{) begins
|
|
uint32_t count; // how many elements in the scope
|
|
}; // struct open_container
|
|
|
|
static_assert(sizeof(open_container) == 64/8, "Open container must be 64 bits");
|
|
|
|
class dom_parser_implementation final : public internal::dom_parser_implementation {
|
|
public:
|
|
/** Tape location of each open { or [ */
|
|
std::unique_ptr<open_container[]> open_containers{};
|
|
/** Whether each open container is a [ or { */
|
|
std::unique_ptr<bool[]> is_array{};
|
|
/** Buffer passed to stage 1 */
|
|
const uint8_t *buf{};
|
|
/** Length passed to stage 1 */
|
|
size_t len{0};
|
|
/** Document passed to stage 2 */
|
|
dom::document *doc{};
|
|
|
|
inline dom_parser_implementation() noexcept;
|
|
inline dom_parser_implementation(dom_parser_implementation &&other) noexcept;
|
|
inline dom_parser_implementation &operator=(dom_parser_implementation &&other) noexcept;
|
|
dom_parser_implementation(const dom_parser_implementation &) = delete;
|
|
dom_parser_implementation &operator=(const dom_parser_implementation &) = delete;
|
|
|
|
simdjson_warn_unused error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final;
|
|
simdjson_warn_unused error_code stage1(const uint8_t *buf, size_t len, stage1_mode partial) noexcept final;
|
|
simdjson_warn_unused error_code stage2(dom::document &doc) noexcept final;
|
|
simdjson_warn_unused error_code stage2_next(dom::document &doc) noexcept final;
|
|
simdjson_warn_unused uint8_t *parse_string(const uint8_t *src, uint8_t *dst) const noexcept final;
|
|
inline simdjson_warn_unused error_code set_capacity(size_t capacity) noexcept final;
|
|
inline simdjson_warn_unused error_code set_max_depth(size_t max_depth) noexcept final;
|
|
private:
|
|
simdjson_inline simdjson_warn_unused error_code set_capacity_stage1(size_t capacity);
|
|
|
|
};
|
|
|
|
} // namespace SIMDJSON_IMPLEMENTATION
|
|
} // namespace simdjson
|
|
|
|
namespace simdjson {
|
|
namespace SIMDJSON_IMPLEMENTATION {
|
|
|
|
inline dom_parser_implementation::dom_parser_implementation() noexcept = default;
|
|
inline dom_parser_implementation::dom_parser_implementation(dom_parser_implementation &&other) noexcept = default;
|
|
inline dom_parser_implementation &dom_parser_implementation::operator=(dom_parser_implementation &&other) noexcept = default;
|
|
|
|
// Leaving these here so they can be inlined if so desired
|
|
inline simdjson_warn_unused error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept {
|
|
if(capacity > SIMDJSON_MAXSIZE_BYTES) { return CAPACITY; }
|
|
// Stage 1 index output
|
|
size_t max_structures = SIMDJSON_ROUNDUP_N(capacity, 64) + 2 + 7;
|
|
structural_indexes.reset( new (std::nothrow) uint32_t[max_structures] );
|
|
if (!structural_indexes) { _capacity = 0; return MEMALLOC; }
|
|
structural_indexes[0] = 0;
|
|
n_structural_indexes = 0;
|
|
|
|
_capacity = capacity;
|
|
return SUCCESS;
|
|
}
|
|
|
|
inline simdjson_warn_unused error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept {
|
|
// Stage 2 stacks
|
|
open_containers.reset(new (std::nothrow) open_container[max_depth]);
|
|
is_array.reset(new (std::nothrow) bool[max_depth]);
|
|
if (!is_array || !open_containers) { _max_depth = 0; return MEMALLOC; }
|
|
|
|
_max_depth = max_depth;
|
|
return SUCCESS;
|
|
}
|
|
|
|
} // namespace SIMDJSON_IMPLEMENTATION
|
|
} // namespace simdjson
|