From 3d22a2d84501fdee27fa8f89f9de01ad9cb117ed Mon Sep 17 00:00:00 2001 From: John Keiser Date: Mon, 1 Jun 2020 12:14:09 -0700 Subject: [PATCH] One weird trick: set a bogus error value in the parser impl This makes us faster under both gcc and clang somehow. --- .../internal/dom_parser_implementation.h | 3 +++ .../stage2/streaming_structural_parser.h | 8 +++--- src/generic/stage2/structural_parser.h | 25 ++++++++++--------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/include/simdjson/internal/dom_parser_implementation.h b/include/simdjson/internal/dom_parser_implementation.h index e984e9b6..c651f7fc 100644 --- a/include/simdjson/internal/dom_parser_implementation.h +++ b/include/simdjson/internal/dom_parser_implementation.h @@ -136,6 +136,9 @@ public: /** Return address of each open { or [ */ std::unique_ptr 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. * diff --git a/src/generic/stage2/streaming_structural_parser.h b/src/generic/stage2/streaming_structural_parser.h index 69f802d5..5e27ef90 100755 --- a/src/generic/stage2/streaming_structural_parser.h +++ b/src/generic/stage2/streaming_structural_parser.h @@ -12,7 +12,7 @@ struct streaming_structural_parser: structural_parser { advance_char(); // Push the root scope (there is always at least one scope) if (start_document(finish_parser)) { - return DEPTH_ERROR; + return parser.error = DEPTH_ERROR; } return SUCCESS; } @@ -21,16 +21,16 @@ struct streaming_structural_parser: structural_parser { WARN_UNUSED really_inline error_code finish() { if ( structurals.past_end(parser.n_structural_indexes) ) { log_error("IMPOSSIBLE: past the end of the JSON!"); - return TAPE_ERROR; + return parser.error = TAPE_ERROR; } end_document(); if (depth != 0) { log_error("Unclosed objects or arrays!"); - return TAPE_ERROR; + return parser.error = TAPE_ERROR; } if (parser.containing_scope[depth].tape_index != 0) { log_error("IMPOSSIBLE: root scope tape index did not start at 0!"); - return TAPE_ERROR; + return parser.error = TAPE_ERROR; } bool finished = structurals.at_end(parser.n_structural_indexes); if (!finished) { log_value("(and has more)"); } diff --git a/src/generic/stage2/structural_parser.h b/src/generic/stage2/structural_parser.h index 4eccc601..60031b7d 100644 --- a/src/generic/stage2/structural_parser.h +++ b/src/generic/stage2/structural_parser.h @@ -272,16 +272,16 @@ struct structural_parser { // the string might not be NULL terminated. if ( !structurals.at_end(parser.n_structural_indexes) ) { log_error("More than one JSON value at the root of the document, or extra characters at the end of the JSON!"); - return TAPE_ERROR; + return parser.error = TAPE_ERROR; } end_document(); if (depth != 0) { log_error("Unclosed objects or arrays!"); - return TAPE_ERROR; + return parser.error = TAPE_ERROR; } if (parser.containing_scope[depth].tape_index != 0) { log_error("IMPOSSIBLE: root scope tape index did not start at 0!"); - return TAPE_ERROR; + return parser.error = TAPE_ERROR; } return SUCCESS; @@ -299,11 +299,11 @@ struct structural_parser { * carefully, * all without any added cost. */ if (depth >= parser.max_depth()) { - return DEPTH_ERROR; + return parser.error = DEPTH_ERROR; } switch (structurals.current_char()) { case '"': - return STRING_ERROR; + return parser.error = STRING_ERROR; case '0': case '1': case '2': @@ -315,34 +315,35 @@ struct structural_parser { case '8': case '9': case '-': - return NUMBER_ERROR; + return parser.error = NUMBER_ERROR; case 't': - return T_ATOM_ERROR; + return parser.error = T_ATOM_ERROR; case 'n': - return N_ATOM_ERROR; + return parser.error = N_ATOM_ERROR; case 'f': - return F_ATOM_ERROR; + return parser.error = F_ATOM_ERROR; default: - return TAPE_ERROR; + return parser.error = TAPE_ERROR; } } really_inline void init() { current_string_buf_loc = parser.doc->string_buf.get(); parser.current_loc = 0; + parser.error = UNINITIALIZED; } WARN_UNUSED really_inline error_code start(size_t len, ret_address finish_state) { log_start(); init(); // sets is_valid to false if (len > parser.capacity()) { - return CAPACITY; + return parser.error = CAPACITY; } // Advance to the first character as soon as possible structurals.advance_char(); // Push the root scope (there is always at least one scope) if (start_document(finish_state)) { - return DEPTH_ERROR; + return parser.error = DEPTH_ERROR; } return SUCCESS; }