Move containing_scope and ret_address to .cpp

This commit is contained in:
John Keiser 2020-06-01 12:14:09 -07:00
parent 3d22a2d845
commit b75fa26dc1
9 changed files with 78 additions and 186 deletions

View File

@ -13,18 +13,6 @@ class document;
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.
*
@ -130,15 +118,6 @@ public:
/** Structural indices passed from stage 1 to stage 2 */
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.
*

View File

@ -7,43 +7,7 @@
namespace simdjson {
namespace arm64 {
class dom_parser_implementation final : public internal::dom_parser_implementation {
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;
}
#include "generic/dom_parser_implementation.h"
} // namespace arm64
} // namespace simdjson

View File

@ -7,43 +7,7 @@
namespace simdjson {
namespace fallback {
class dom_parser_implementation final : public internal::dom_parser_implementation {
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;
}
#include "generic/dom_parser_implementation.h"
} // namespace fallback
} // namespace simdjson

View File

@ -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;
}

View File

@ -5,8 +5,8 @@ namespace allocate {
// 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) {
parser.containing_scope.reset(new (std::nothrow) internal::scope_descriptor[max_depth]);
parser.ret_address.reset(new (std::nothrow) internal::ret_address[max_depth]);
parser.containing_scope.reset(new (std::nothrow) scope_descriptor[max_depth]);
parser.ret_address.reset(new (std::nothrow) ret_address_t[max_depth]);
if (!parser.ret_address || !parser.containing_scope) {
return MEMALLOC;

View File

@ -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) {}
// 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();
init(); // sets is_valid to false
// Capacity ain't no thang for streaming, so we don't check it.

View File

@ -5,8 +5,6 @@
namespace stage2 {
using internal::ret_address;
#ifdef SIMDJSON_USE_COMPUTED_GOTO
#define INIT_ADDRESSES() { &&array_begin, &&array_continue, &&error, &&finish, &&object_begin, &&object_continue }
#define GOTO(address) { goto *(address); }
@ -36,12 +34,12 @@ using internal::ret_address;
#endif // SIMDJSON_USE_COMPUTED_GOTO
struct unified_machine_addresses {
ret_address array_begin;
ret_address array_continue;
ret_address error;
ret_address finish;
ret_address object_begin;
ret_address object_continue;
ret_address_t array_begin;
ret_address_t array_continue;
ret_address_t error;
ret_address_t finish;
ret_address_t object_begin;
ret_address_t object_continue;
};
#undef FAIL_IF
@ -82,7 +80,7 @@ struct structural_parser {
uint32_t next_structural = 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].count = 0;
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;
}
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");
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");
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");
return start_scope(continue_state);
}
@ -241,7 +239,7 @@ struct structural_parser {
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()) {
case '"':
FAIL_IF( parse_string() );
@ -333,7 +331,7 @@ struct structural_parser {
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();
init(); // sets is_valid to false
if (len > parser.capacity()) {

View File

@ -3,46 +3,11 @@
#include "simdjson.h"
#include "isadetection.h"
namespace simdjson {
namespace haswell {
class dom_parser_implementation final : public internal::dom_parser_implementation {
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;
}
#include "generic/dom_parser_implementation.h"
} // namespace haswell
} // namespace simdjson

View File

@ -7,43 +7,7 @@
namespace simdjson {
namespace westmere {
class dom_parser_implementation final : public internal::dom_parser_implementation {
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;
}
#include "generic/dom_parser_implementation.h"
} // namespace westmere
} // namespace simdjson