diff --git a/appveyor.yml b/appveyor.yml index ce33743af..12cd4eac3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,4 +4,5 @@ build_script: - cmake .. - cmake --build . test_script: - - build/test/run-tests + - cd %APPVEYOR_BUILD_FOLDER%/build + - ctest --output-on-failure diff --git a/include/yaml-cpp/dll.h b/include/yaml-cpp/dll.h index fb9e3af12..f6ea6353a 100644 --- a/include/yaml-cpp/dll.h +++ b/include/yaml-cpp/dll.h @@ -22,3 +22,19 @@ #else // YAML_CPP_DLL #define YAML_CPP_API #endif // YAML_CPP_DLL + +#ifdef _MSC_VER +#define likely(x) (x) +#define unlikely(x) (x) +#else +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif + +#ifdef _MSC_VER +#define YAML_CPP_INLINE __forceinline +#define YAML_CPP_NOINLINE +#else +#define YAML_CPP_INLINE __attribute__((always_inline)) +#define YAML_CPP_NOINLINE __attribute__((noinline)) +#endif diff --git a/include/yaml-cpp/node/detail/node.h b/include/yaml-cpp/node/detail/node.h index 7c46cbb48..54a571583 100644 --- a/include/yaml-cpp/node/detail/node.h +++ b/include/yaml-cpp/node/detail/node.h @@ -18,8 +18,7 @@ class node { node() : m_pRef(nullptr) {} void set_data(node_data *data) { m_pRef = data; } - __attribute__((noinline)) - ~node() {} + YAML_CPP_NOINLINE ~node() {} node(const node&) = delete; // required for bucket reserve diff --git a/include/yaml-cpp/node/impl.h b/include/yaml-cpp/node/impl.h index 71addafef..cd1765ec3 100644 --- a/include/yaml-cpp/node/impl.h +++ b/include/yaml-cpp/node/impl.h @@ -5,6 +5,7 @@ #include "yaml-cpp/node/detail/memory.h" #include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/string_view.h" +#include "yaml-cpp/dll.h" #include "yaml-cpp/exceptions.h" #include #include @@ -65,7 +66,7 @@ inline Node::Node(detail::node& node, detail::shared_memory pMemory) inline Node::~Node() {} inline void Node::ThrowOnInvalid() const { - if (__builtin_expect(!m_pMemory, 0)) { ThrowInvalidNode(); }; + if (unlikely(!m_pMemory)) { ThrowInvalidNode(); }; } inline void Node::EnsureNodeExists() const { diff --git a/include/yaml-cpp/node/ptr.h b/include/yaml-cpp/node/ptr.h index da5ac91d2..e2fd443f2 100644 --- a/include/yaml-cpp/node/ptr.h +++ b/include/yaml-cpp/node/ptr.h @@ -10,8 +10,7 @@ struct ref_holder { using holder = ref_holder; - __attribute__((always_inline)) - ~ref_holder() { release(); } + YAML_CPP_INLINE ~ref_holder() { release(); } ref_holder(T* ptr) { if (ptr) { diff --git a/src/emitterutils.cpp b/src/emitterutils.cpp index 0ac567581..f9a99a223 100644 --- a/src/emitterutils.cpp +++ b/src/emitterutils.cpp @@ -420,9 +420,10 @@ bool WriteAnchor(ostream_wrapper& out, const std::string& str) { bool WriteTag(ostream_wrapper& out, const std::string& str, bool verbatim) { out << (verbatim ? "!<" : "!"); StringCharSource buffer(str.c_str(), str.size()); - auto reValid = verbatim ? - [](const StringCharSource& s) { return Exp::URI::Match(s); } : - [](const StringCharSource& s) { return Exp::Tag::Match(s); }; + typedef int(*MatchFunctionType)(const StringCharSource& s); + MatchFunctionType uriMatch = [](const StringCharSource& s) { return Exp::URI::Match(s); }; + MatchFunctionType tagMatch = [](const StringCharSource& s) { return Exp::Tag::Match(s); }; + MatchFunctionType reValid = verbatim ? uriMatch : tagMatch; while (buffer) { diff --git a/src/exp.h b/src/exp.h index b706227dc..90757c4af 100644 --- a/src/exp.h +++ b/src/exp.h @@ -7,13 +7,10 @@ #include "stream.h" #include "stringsource.h" #include "streamcharsource.h" +#include "yaml-cpp/dll.h" -#define REGEXP_INLINE inline __attribute__((always_inline)) -#define TEST_INLINE inline __attribute__((always_inline)) -//#define TEST_INLINE __attribute__((noinline)) - -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) +#define REGEXP_INLINE YAML_CPP_INLINE +#define TEST_INLINE YAML_CPP_INLINE namespace YAML { @@ -65,13 +62,19 @@ struct Char { static const std::size_t max_match = 1; }; +template +struct size {}; + + +static const size_t A_NOT_EQUAL_B_NOT_EQUAL = 0; +static const size_t A_NOT_EQUAL_B_EQUAL = 1; +static const size_t A_EQUAL_B_NOT_EQUAL = 2; +static const size_t A_EQUAL_B_EQUAL = 3; + template struct OR { - template ::value != - static_max::value, int>::type = 0> - REGEXP_INLINE static int match(Source source, const size_t pos) { + template + REGEXP_INLINE static int match(Source source, const size_t pos, size) { int match = A::match(source, pos); if (match >= 0) { return match; @@ -79,11 +82,8 @@ struct OR { return OR::match(source, pos); } - template ::value == - static_max::value, int>::type = 0> - REGEXP_INLINE static int match(Source source, const size_t pos) { + template + REGEXP_INLINE static int match(Source source, const size_t pos, size) { if (A::match(source, pos) >= 0) { return A::lookahead; } @@ -93,11 +93,8 @@ struct OR { return -1; } - template ::value == - static_max::value, int>::type = 0> - REGEXP_INLINE static int match(Source source, const size_t pos) { + template + REGEXP_INLINE static int match(Source source, const size_t pos, size) { int match = A::match(source, pos); if (match >= 0) { return match; @@ -108,17 +105,23 @@ struct OR { return -1; } - template ::value != - static_max::value, int>::type = 0> - REGEXP_INLINE static int match(Source source, const size_t pos) { + template + REGEXP_INLINE static int match(Source source, const size_t pos, size) { if (A::match(source, pos) >= 0) { return A::lookahead; } return OR::match(source, pos); } + template + REGEXP_INLINE static int match(Source source, const size_t pos) { + return match(source, pos, size{}); + } + + static const size_t min_value = static_min::value; + static const size_t max_value = static_max::value; + static const size_t index = (size_t)(A::min_match == A::max_match) * 2 + size_t(min_value == max_value); + static const std::size_t lookahead = static_max::value; static const std::size_t min_match = static_min::value; static const std::size_t max_match = static_max::value; @@ -138,11 +141,8 @@ struct OR { template struct SEQ { - template ::value != - static_sum::value, int>::type = 0> - REGEXP_INLINE static int match(Source source, const size_t pos) { + template + REGEXP_INLINE static int match(Source source, const size_t pos, size) { int a = A::match(source, pos); if (a < 0) { return -1; } int b = SEQ::match(source, pos + a); @@ -150,11 +150,8 @@ struct SEQ { return a + b; } - template ::value == - static_sum::value, int>::type = 0> - REGEXP_INLINE static int match(Source source, const size_t pos) { + template + REGEXP_INLINE static int match(Source source, const size_t pos, size) { if (A::match(source, pos) < 0) { return -1; } @@ -164,11 +161,8 @@ struct SEQ { return lookahead; } - template ::value == - static_sum::value, int>::type = 0> - REGEXP_INLINE static int match(Source source, const size_t pos) { + template + REGEXP_INLINE static int match(Source source, const size_t pos, size) { int a = A::match(source, pos); if (a < 0) { return -1; } if (SEQ::match(source, pos + a) < 0) { @@ -177,11 +171,8 @@ struct SEQ { return a + static_sum::value; } - template ::value != - static_sum::value, int>::type = 0> - REGEXP_INLINE static int match(Source source, const size_t pos) { + template + REGEXP_INLINE static int match(Source source, const size_t pos, size) { if (A::match(source, pos) < 0) { return -1; } @@ -189,6 +180,16 @@ struct SEQ { if (b < 0) { return -1; } return A::lookahead + b; } + + template + REGEXP_INLINE static int match(Source source, const size_t pos) { + return match(source, pos, size{}); + } + + static const size_t min_value = static_sum::value; + static const size_t max_value = static_sum::value; + static const size_t index = (size_t)(A::min_match == A::max_match) * 2 + size_t(min_value == max_value); + static const std::size_t lookahead = static_sum::value; static const std::size_t min_match = static_sum::value; static const std::size_t max_match = static_sum::value; diff --git a/src/plalloc.h b/src/plalloc.h index cc48231f7..75ae711b0 100644 --- a/src/plalloc.h +++ b/src/plalloc.h @@ -37,13 +37,20 @@ struct plalloc { typedef T value_type; - plalloc() = default; + plalloc(): memory(new std::vector>()), + available(new std::vector()) { + }; template - plalloc(const plalloc &) {} - plalloc(const plalloc &) {} - plalloc & operator=(const plalloc &) { return *this; } + plalloc(const plalloc &) : memory(new std::vector>()), + available(new std::vector()) { + } + plalloc(const plalloc &) : memory(new std::vector>()), + available(new std::vector()) { + } + plalloc & operator=(const plalloc &) = delete; plalloc(plalloc &&) = default; plalloc & operator=(plalloc &&) = default; + ~plalloc() = default; typedef std::true_type propagate_on_container_copy_assignment; typedef std::true_type propagate_on_container_move_assignment; @@ -59,31 +66,28 @@ struct plalloc { T * allocate(size_t num_to_allocate) { if (num_to_allocate != 1) { return static_cast(::operator new(sizeof(T) * num_to_allocate)); - - } else if (available.empty()) { + } else if (available->empty()) { // first allocate N, then double whenever // we run out of memory - size_t to_allocate = N << memory.size(); + size_t to_allocate = N << memory->size(); //printf("alloc %lu\n", to_allocate); - available.reserve(to_allocate); - std::unique_ptr allocated(new value_holder[to_allocate]); - value_holder * first_new = allocated.get(); - memory.emplace_back(std::move(allocated)); - size_t to_return = to_allocate - 1; - for (size_t i = 0; i < to_return; ++i) { - available.push_back(std::addressof(first_new[i].value)); + available->reserve(to_allocate); + std::unique_ptr allocated((char*)::operator new(sizeof(T) * to_allocate)); + T* first_new = (T *)allocated.get(); + memory->emplace_back(std::move(allocated)); + for (size_t i = 1; i < to_allocate; ++i) { + available->push_back(first_new + i); } - return std::addressof(first_new[to_return].value); - + return first_new; } else { - T * result = available.back(); - available.pop_back(); + T * result = (T*)available->back(); + available->pop_back(); return result; } } void deallocate(T * ptr, size_t num_to_free) { if (num_to_free == 1) { - available.push_back(ptr); + available->push_back(ptr); } else { ::operator delete(ptr); } @@ -110,13 +114,7 @@ struct plalloc { object->~U(); } -private: - union value_holder { - value_holder() {} - ~value_holder() {} - T value; - }; - - std::vector> memory; - std::vector available; +public: + std::vector> *memory; + std::vector *available; }; diff --git a/src/scanscalar.cpp b/src/scanscalar.cpp index d3adfe080..2fd79582b 100644 --- a/src/scanscalar.cpp +++ b/src/scanscalar.cpp @@ -163,7 +163,8 @@ std::string Scanner::ScanScalar(ScanScalarParams& params) { } // ******************************** // Phase #2: eat line ending - assert(INPUT.EatLineBreak()); + bool eated = INPUT.EatLineBreak(); + assert(eated); // ******************************** // Phase #3: scan initial spaces diff --git a/src/simplekey.cpp b/src/simplekey.cpp index 1f4da3c19..8f02f198a 100644 --- a/src/simplekey.cpp +++ b/src/simplekey.cpp @@ -1,6 +1,8 @@ #include "scanner.h" #include "token.h" +#include "yaml-cpp/dll.h" + namespace YAML { struct Mark; @@ -33,7 +35,7 @@ void Scanner::SimpleKey::Invalidate() { // CanInsertPotentialSimpleKey bool Scanner::CanInsertPotentialSimpleKey() const { - if (__builtin_expect(m_simpleKeyAllowed, 1)) { + if (likely(m_simpleKeyAllowed)) { return !ExistsActiveSimpleKey(); } return false; @@ -44,7 +46,7 @@ bool Scanner::CanInsertPotentialSimpleKey() const { // (there's allowed at most one per flow level, i.e., at the start of the flow // start token) bool Scanner::ExistsActiveSimpleKey() const { - if (__builtin_expect(!m_simpleKeys.empty(), 1)) { + if (likely(!m_simpleKeys.empty())) { return m_simpleKeys.top().flowLevel == GetFlowLevel(); } return false; diff --git a/src/stream.cpp b/src/stream.cpp index df00e6bc8..331786ac7 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -14,8 +14,6 @@ #define S_ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A))) #define S_ARRAY_END(A) ((A) + S_ARRAY_SIZE(A)) -#define likely(x) __builtin_expect(!!(x), 1) - #define CP_REPLACEMENT_CHARACTER (0xFFFD) namespace YAML { diff --git a/src/stream.h b/src/stream.h index 1e36fc5f5..0decadd22 100644 --- a/src/stream.h +++ b/src/stream.h @@ -1,6 +1,7 @@ #pragma once #include "yaml-cpp/noncopyable.h" +#include "yaml-cpp/dll.h" #include "yaml-cpp/mark.h" #include "streamcharsource.h" @@ -89,7 +90,7 @@ class Stream : private noncopyable { int offset = m_mark.pos - m_lookahead.streamPos; auto dst = reinterpret_cast(out.data()); - if (__builtin_expect(m_lookahead.available > 4 + offset, 1)) { + if (likely(m_lookahead.available > 4 + offset)) { auto src = reinterpret_cast(m_lookahead.buffer.data()); dst[0] = src[0] >> (offset * 8); } else {