Move containing_scope and ret_address to .cpp
This commit is contained in:
parent
3d22a2d845
commit
b75fa26dc1
|
@ -13,18 +13,6 @@ class document;
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
// expectation: sizeof(scope_descriptor) = 64/8.
|
|
||||||
struct scope_descriptor {
|
|
||||||
uint32_t tape_index; // where, on the tape, does the scope ([,{) begins
|
|
||||||
uint32_t count; // how many elements in the scope
|
|
||||||
}; // struct scope_descriptor
|
|
||||||
|
|
||||||
#ifdef SIMDJSON_USE_COMPUTED_GOTO
|
|
||||||
typedef void* ret_address;
|
|
||||||
#else
|
|
||||||
typedef char ret_address;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of simdjson's DOM parser for a particular CPU architecture.
|
* An implementation of simdjson's DOM parser for a particular CPU architecture.
|
||||||
*
|
*
|
||||||
|
@ -130,15 +118,6 @@ public:
|
||||||
/** Structural indices passed from stage 1 to stage 2 */
|
/** Structural indices passed from stage 1 to stage 2 */
|
||||||
std::unique_ptr<uint32_t[]> structural_indexes{};
|
std::unique_ptr<uint32_t[]> structural_indexes{};
|
||||||
|
|
||||||
/** Tape location of each open { or [ */
|
|
||||||
std::unique_ptr<internal::scope_descriptor[]> containing_scope{};
|
|
||||||
|
|
||||||
/** Return address of each open { or [ */
|
|
||||||
std::unique_ptr<internal::ret_address[]> ret_address{};
|
|
||||||
|
|
||||||
/** Error code, used ENTIRELY to make gcc not be slower than before. Not actually consumed. */
|
|
||||||
error_code error{UNINITIALIZED};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The largest document this parser can support without reallocating.
|
* The largest document this parser can support without reallocating.
|
||||||
*
|
*
|
||||||
|
|
|
@ -7,43 +7,7 @@
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
namespace arm64 {
|
namespace arm64 {
|
||||||
|
|
||||||
class dom_parser_implementation final : public internal::dom_parser_implementation {
|
#include "generic/dom_parser_implementation.h"
|
||||||
public:
|
|
||||||
const uint8_t *buf{}; // Buffer passed to stage 1
|
|
||||||
size_t len{0}; // Length passed to stage 1
|
|
||||||
dom::document *doc{}; // Document passed to stage 2
|
|
||||||
|
|
||||||
really_inline dom_parser_implementation();
|
|
||||||
dom_parser_implementation(const dom_parser_implementation &) = delete;
|
|
||||||
dom_parser_implementation & operator=(const dom_parser_implementation &) = delete;
|
|
||||||
|
|
||||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, bool streaming) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage2(dom::document &doc) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::document &doc, size_t &next_json) noexcept final;
|
|
||||||
WARN_UNUSED error_code set_capacity(size_t capacity) noexcept final;
|
|
||||||
WARN_UNUSED error_code set_max_depth(size_t max_depth) noexcept final;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "generic/stage1/allocate.h"
|
|
||||||
#include "generic/stage2/allocate.h"
|
|
||||||
|
|
||||||
really_inline dom_parser_implementation::dom_parser_implementation() {}
|
|
||||||
|
|
||||||
// Leaving these here so they can be inlined if so desired
|
|
||||||
WARN_UNUSED error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept {
|
|
||||||
error_code err = stage1::allocate::set_capacity(*this, capacity);
|
|
||||||
if (err) { _capacity = 0; return err; }
|
|
||||||
_capacity = capacity;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN_UNUSED error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept {
|
|
||||||
error_code err = stage2::allocate::set_max_depth(*this, max_depth);
|
|
||||||
if (err) { _max_depth = 0; return err; }
|
|
||||||
_max_depth = max_depth;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace arm64
|
} // namespace arm64
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
|
@ -7,43 +7,7 @@
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
namespace fallback {
|
namespace fallback {
|
||||||
|
|
||||||
class dom_parser_implementation final : public internal::dom_parser_implementation {
|
#include "generic/dom_parser_implementation.h"
|
||||||
public:
|
|
||||||
const uint8_t *buf{}; // Buffer passed to stage 1
|
|
||||||
size_t len{0}; // Length passed to stage 1
|
|
||||||
dom::document *doc{}; // Document passed to stage 2
|
|
||||||
|
|
||||||
really_inline dom_parser_implementation();
|
|
||||||
dom_parser_implementation(const dom_parser_implementation &) = delete;
|
|
||||||
dom_parser_implementation & operator=(const dom_parser_implementation &) = delete;
|
|
||||||
|
|
||||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, bool streaming) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage2(dom::document &doc) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::document &doc, size_t &next_json) noexcept final;
|
|
||||||
WARN_UNUSED error_code set_capacity(size_t capacity) noexcept final;
|
|
||||||
WARN_UNUSED error_code set_max_depth(size_t max_depth) noexcept final;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "generic/stage1/allocate.h"
|
|
||||||
#include "generic/stage2/allocate.h"
|
|
||||||
|
|
||||||
really_inline dom_parser_implementation::dom_parser_implementation() {}
|
|
||||||
|
|
||||||
// Leaving these here so they can be inlined if so desired
|
|
||||||
WARN_UNUSED error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept {
|
|
||||||
error_code err = stage1::allocate::set_capacity(*this, capacity);
|
|
||||||
if (err) { _capacity = 0; return err; }
|
|
||||||
_capacity = capacity;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN_UNUSED error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept {
|
|
||||||
error_code err = stage2::allocate::set_max_depth(*this, max_depth);
|
|
||||||
if (err) { _max_depth = 0; return err; }
|
|
||||||
_max_depth = max_depth;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace fallback
|
} // namespace fallback
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
// expectation: sizeof(scope_descriptor) = 64/8.
|
||||||
|
struct scope_descriptor {
|
||||||
|
uint32_t tape_index; // where, on the tape, does the scope ([,{) begins
|
||||||
|
uint32_t count; // how many elements in the scope
|
||||||
|
}; // struct scope_descriptor
|
||||||
|
|
||||||
|
#ifdef SIMDJSON_USE_COMPUTED_GOTO
|
||||||
|
typedef void* ret_address_t;
|
||||||
|
#else
|
||||||
|
typedef char ret_address_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class dom_parser_implementation final : public internal::dom_parser_implementation {
|
||||||
|
public:
|
||||||
|
/** Tape location of each open { or [ */
|
||||||
|
std::unique_ptr<scope_descriptor[]> containing_scope{};
|
||||||
|
/** Return address of each open { or [ */
|
||||||
|
std::unique_ptr<ret_address_t[]> ret_address{};
|
||||||
|
/** 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{};
|
||||||
|
/** Error code (TODO remove, this is not even used, we just set it so the g++ optimizer doesn't get confused) */
|
||||||
|
error_code error{UNINITIALIZED};
|
||||||
|
|
||||||
|
really_inline dom_parser_implementation();
|
||||||
|
dom_parser_implementation(const dom_parser_implementation &) = delete;
|
||||||
|
dom_parser_implementation & operator=(const dom_parser_implementation &) = delete;
|
||||||
|
|
||||||
|
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final;
|
||||||
|
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, bool streaming) noexcept final;
|
||||||
|
WARN_UNUSED error_code stage2(dom::document &doc) noexcept final;
|
||||||
|
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::document &doc, size_t &next_json) noexcept final;
|
||||||
|
WARN_UNUSED error_code set_capacity(size_t capacity) noexcept final;
|
||||||
|
WARN_UNUSED error_code set_max_depth(size_t max_depth) noexcept final;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "generic/stage1/allocate.h"
|
||||||
|
#include "generic/stage2/allocate.h"
|
||||||
|
|
||||||
|
really_inline dom_parser_implementation::dom_parser_implementation() {}
|
||||||
|
|
||||||
|
// Leaving these here so they can be inlined if so desired
|
||||||
|
WARN_UNUSED error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept {
|
||||||
|
error_code err = stage1::allocate::set_capacity(*this, capacity);
|
||||||
|
if (err) { _capacity = 0; return err; }
|
||||||
|
_capacity = capacity;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN_UNUSED error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept {
|
||||||
|
error_code err = stage2::allocate::set_max_depth(*this, max_depth);
|
||||||
|
if (err) { _max_depth = 0; return err; }
|
||||||
|
_max_depth = max_depth;
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
|
@ -5,8 +5,8 @@ namespace allocate {
|
||||||
// Allocates stage 2 internal state and outputs in the parser
|
// Allocates stage 2 internal state and outputs in the parser
|
||||||
//
|
//
|
||||||
really_inline error_code set_max_depth(dom_parser_implementation &parser, size_t max_depth) {
|
really_inline error_code set_max_depth(dom_parser_implementation &parser, size_t max_depth) {
|
||||||
parser.containing_scope.reset(new (std::nothrow) internal::scope_descriptor[max_depth]);
|
parser.containing_scope.reset(new (std::nothrow) scope_descriptor[max_depth]);
|
||||||
parser.ret_address.reset(new (std::nothrow) internal::ret_address[max_depth]);
|
parser.ret_address.reset(new (std::nothrow) ret_address_t[max_depth]);
|
||||||
|
|
||||||
if (!parser.ret_address || !parser.containing_scope) {
|
if (!parser.ret_address || !parser.containing_scope) {
|
||||||
return MEMALLOC;
|
return MEMALLOC;
|
||||||
|
|
|
@ -4,7 +4,7 @@ struct streaming_structural_parser: structural_parser {
|
||||||
really_inline streaming_structural_parser(dom_parser_implementation &_parser, uint32_t next_structural) : structural_parser(_parser, next_structural) {}
|
really_inline streaming_structural_parser(dom_parser_implementation &_parser, uint32_t next_structural) : structural_parser(_parser, next_structural) {}
|
||||||
|
|
||||||
// override to add streaming
|
// override to add streaming
|
||||||
WARN_UNUSED really_inline error_code start(ret_address finish_parser) {
|
WARN_UNUSED really_inline error_code start(ret_address_t finish_parser) {
|
||||||
log_start();
|
log_start();
|
||||||
init(); // sets is_valid to false
|
init(); // sets is_valid to false
|
||||||
// Capacity ain't no thang for streaming, so we don't check it.
|
// Capacity ain't no thang for streaming, so we don't check it.
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
namespace stage2 {
|
namespace stage2 {
|
||||||
|
|
||||||
using internal::ret_address;
|
|
||||||
|
|
||||||
#ifdef SIMDJSON_USE_COMPUTED_GOTO
|
#ifdef SIMDJSON_USE_COMPUTED_GOTO
|
||||||
#define INIT_ADDRESSES() { &&array_begin, &&array_continue, &&error, &&finish, &&object_begin, &&object_continue }
|
#define INIT_ADDRESSES() { &&array_begin, &&array_continue, &&error, &&finish, &&object_begin, &&object_continue }
|
||||||
#define GOTO(address) { goto *(address); }
|
#define GOTO(address) { goto *(address); }
|
||||||
|
@ -36,12 +34,12 @@ using internal::ret_address;
|
||||||
#endif // SIMDJSON_USE_COMPUTED_GOTO
|
#endif // SIMDJSON_USE_COMPUTED_GOTO
|
||||||
|
|
||||||
struct unified_machine_addresses {
|
struct unified_machine_addresses {
|
||||||
ret_address array_begin;
|
ret_address_t array_begin;
|
||||||
ret_address array_continue;
|
ret_address_t array_continue;
|
||||||
ret_address error;
|
ret_address_t error;
|
||||||
ret_address finish;
|
ret_address_t finish;
|
||||||
ret_address object_begin;
|
ret_address_t object_begin;
|
||||||
ret_address object_continue;
|
ret_address_t object_continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef FAIL_IF
|
#undef FAIL_IF
|
||||||
|
@ -82,7 +80,7 @@ struct structural_parser {
|
||||||
uint32_t next_structural = 0
|
uint32_t next_structural = 0
|
||||||
) : structurals(_parser.buf, _parser.len, _parser.structural_indexes.get(), next_structural), parser{_parser}, depth{0} {}
|
) : structurals(_parser.buf, _parser.len, _parser.structural_indexes.get(), next_structural), parser{_parser}, depth{0} {}
|
||||||
|
|
||||||
WARN_UNUSED really_inline bool start_scope(ret_address continue_state) {
|
WARN_UNUSED really_inline bool start_scope(ret_address_t continue_state) {
|
||||||
parser.containing_scope[depth].tape_index = parser.current_loc;
|
parser.containing_scope[depth].tape_index = parser.current_loc;
|
||||||
parser.containing_scope[depth].count = 0;
|
parser.containing_scope[depth].count = 0;
|
||||||
parser.current_loc++; // We don't actually *write* the start element until the end.
|
parser.current_loc++; // We don't actually *write* the start element until the end.
|
||||||
|
@ -93,17 +91,17 @@ struct structural_parser {
|
||||||
return exceeded_max_depth;
|
return exceeded_max_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_UNUSED really_inline bool start_document(ret_address continue_state) {
|
WARN_UNUSED really_inline bool start_document(ret_address_t continue_state) {
|
||||||
log_start_value("document");
|
log_start_value("document");
|
||||||
return start_scope(continue_state);
|
return start_scope(continue_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_UNUSED really_inline bool start_object(ret_address continue_state) {
|
WARN_UNUSED really_inline bool start_object(ret_address_t continue_state) {
|
||||||
log_start_value("object");
|
log_start_value("object");
|
||||||
return start_scope(continue_state);
|
return start_scope(continue_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_UNUSED really_inline bool start_array(ret_address continue_state) {
|
WARN_UNUSED really_inline bool start_array(ret_address_t continue_state) {
|
||||||
log_start_value("array");
|
log_start_value("array");
|
||||||
return start_scope(continue_state);
|
return start_scope(continue_state);
|
||||||
}
|
}
|
||||||
|
@ -241,7 +239,7 @@ struct structural_parser {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_UNUSED really_inline ret_address parse_value(const unified_machine_addresses &addresses, ret_address continue_state) {
|
WARN_UNUSED really_inline ret_address_t parse_value(const unified_machine_addresses &addresses, ret_address_t continue_state) {
|
||||||
switch (structurals.current_char()) {
|
switch (structurals.current_char()) {
|
||||||
case '"':
|
case '"':
|
||||||
FAIL_IF( parse_string() );
|
FAIL_IF( parse_string() );
|
||||||
|
@ -333,7 +331,7 @@ struct structural_parser {
|
||||||
parser.error = UNINITIALIZED;
|
parser.error = UNINITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
WARN_UNUSED really_inline error_code start(size_t len, ret_address finish_state) {
|
WARN_UNUSED really_inline error_code start(size_t len, ret_address_t finish_state) {
|
||||||
log_start();
|
log_start();
|
||||||
init(); // sets is_valid to false
|
init(); // sets is_valid to false
|
||||||
if (len > parser.capacity()) {
|
if (len > parser.capacity()) {
|
||||||
|
|
|
@ -3,46 +3,11 @@
|
||||||
|
|
||||||
#include "simdjson.h"
|
#include "simdjson.h"
|
||||||
#include "isadetection.h"
|
#include "isadetection.h"
|
||||||
|
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
namespace haswell {
|
namespace haswell {
|
||||||
|
|
||||||
class dom_parser_implementation final : public internal::dom_parser_implementation {
|
#include "generic/dom_parser_implementation.h"
|
||||||
public:
|
|
||||||
const uint8_t *buf{}; // Buffer passed to stage 1
|
|
||||||
size_t len{0}; // Length passed to stage 1
|
|
||||||
dom::document *doc{}; // Document passed to stage 2
|
|
||||||
|
|
||||||
really_inline dom_parser_implementation();
|
|
||||||
dom_parser_implementation(const dom_parser_implementation &) = delete;
|
|
||||||
dom_parser_implementation & operator=(const dom_parser_implementation &) = delete;
|
|
||||||
|
|
||||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, bool streaming) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage2(dom::document &doc) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::document &doc, size_t &next_json) noexcept final;
|
|
||||||
WARN_UNUSED error_code set_capacity(size_t capacity) noexcept final;
|
|
||||||
WARN_UNUSED error_code set_max_depth(size_t max_depth) noexcept final;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "generic/stage1/allocate.h"
|
|
||||||
#include "generic/stage2/allocate.h"
|
|
||||||
|
|
||||||
really_inline dom_parser_implementation::dom_parser_implementation() {}
|
|
||||||
|
|
||||||
// Leaving these here so they can be inlined if so desired
|
|
||||||
WARN_UNUSED error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept {
|
|
||||||
error_code err = stage1::allocate::set_capacity(*this, capacity);
|
|
||||||
if (err) { _capacity = 0; return err; }
|
|
||||||
_capacity = capacity;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN_UNUSED error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept {
|
|
||||||
error_code err = stage2::allocate::set_max_depth(*this, max_depth);
|
|
||||||
if (err) { _max_depth = 0; return err; }
|
|
||||||
_max_depth = max_depth;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace haswell
|
} // namespace haswell
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
|
@ -7,43 +7,7 @@
|
||||||
namespace simdjson {
|
namespace simdjson {
|
||||||
namespace westmere {
|
namespace westmere {
|
||||||
|
|
||||||
class dom_parser_implementation final : public internal::dom_parser_implementation {
|
#include "generic/dom_parser_implementation.h"
|
||||||
public:
|
|
||||||
const uint8_t *buf{}; // Buffer passed to stage 1
|
|
||||||
size_t len{0}; // Length passed to stage 1
|
|
||||||
dom::document *doc{}; // Document passed to stage 2
|
|
||||||
|
|
||||||
really_inline dom_parser_implementation();
|
|
||||||
dom_parser_implementation(const dom_parser_implementation &) = delete;
|
|
||||||
dom_parser_implementation & operator=(const dom_parser_implementation &) = delete;
|
|
||||||
|
|
||||||
WARN_UNUSED error_code parse(const uint8_t *buf, size_t len, dom::document &doc) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage1(const uint8_t *buf, size_t len, bool streaming) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage2(dom::document &doc) noexcept final;
|
|
||||||
WARN_UNUSED error_code stage2(const uint8_t *buf, size_t len, dom::document &doc, size_t &next_json) noexcept final;
|
|
||||||
WARN_UNUSED error_code set_capacity(size_t capacity) noexcept final;
|
|
||||||
WARN_UNUSED error_code set_max_depth(size_t max_depth) noexcept final;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "generic/stage1/allocate.h"
|
|
||||||
#include "generic/stage2/allocate.h"
|
|
||||||
|
|
||||||
really_inline dom_parser_implementation::dom_parser_implementation() {}
|
|
||||||
|
|
||||||
// Leaving these here so they can be inlined if so desired
|
|
||||||
WARN_UNUSED error_code dom_parser_implementation::set_capacity(size_t capacity) noexcept {
|
|
||||||
error_code err = stage1::allocate::set_capacity(*this, capacity);
|
|
||||||
if (err) { _capacity = 0; return err; }
|
|
||||||
_capacity = capacity;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
WARN_UNUSED error_code dom_parser_implementation::set_max_depth(size_t max_depth) noexcept {
|
|
||||||
error_code err = stage2::allocate::set_max_depth(*this, max_depth);
|
|
||||||
if (err) { _max_depth = 0; return err; }
|
|
||||||
_max_depth = max_depth;
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace westmere
|
} // namespace westmere
|
||||||
} // namespace simdjson
|
} // namespace simdjson
|
||||||
|
|
Loading…
Reference in New Issue