Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ build_script:
- cmake ..
- cmake --build .
test_script:
- build/test/run-tests
- cd %APPVEYOR_BUILD_FOLDER%/build
- ctest --output-on-failure
16 changes: 16 additions & 0 deletions include/yaml-cpp/dll.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 1 addition & 2 deletions include/yaml-cpp/node/detail/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion include/yaml-cpp/node/impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <string>
#include <cstring>
Expand Down Expand Up @@ -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 {
Expand Down
3 changes: 1 addition & 2 deletions include/yaml-cpp/node/ptr.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ struct ref_holder {

using holder = ref_holder<T, owned_region>;

__attribute__((always_inline))
~ref_holder() { release(); }
YAML_CPP_INLINE ~ref_holder() { release(); }

ref_holder(T* ptr) {
if (ptr) {
Expand Down
7 changes: 4 additions & 3 deletions src/emitterutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {

Expand Down
93 changes: 47 additions & 46 deletions src/exp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -65,25 +62,28 @@ struct Char {
static const std::size_t max_match = 1;
};

template<std::size_t>
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 <typename A, typename... B>
struct OR {
template <std::size_t N, typename MA = A,
typename std::enable_if<MA::min_match != MA::max_match &&
static_min<B::min_match...>::value !=
static_max<B::max_match...>::value, int>::type = 0>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos, size<A_NOT_EQUAL_B_NOT_EQUAL>) {
int match = A::match(source, pos);
if (match >= 0) {
return match;
}
return OR<B...>::match(source, pos);
}

template <std::size_t N, typename MA = A,
typename std::enable_if<MA::min_match == MA::max_match &&
static_min<B::min_match...>::value ==
static_max<B::max_match...>::value, int>::type = 0>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos, size<A_EQUAL_B_EQUAL>) {
if (A::match(source, pos) >= 0) {
return A::lookahead;
}
Expand All @@ -93,11 +93,8 @@ struct OR {
return -1;
}

template <std::size_t N, typename MA = A,
typename std::enable_if<MA::min_match != MA::max_match &&
static_min<B::min_match...>::value ==
static_max<B::max_match...>::value, int>::type = 0>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos, size<A_NOT_EQUAL_B_EQUAL>) {
int match = A::match(source, pos);
if (match >= 0) {
return match;
Expand All @@ -108,17 +105,23 @@ struct OR {
return -1;
}

template <std::size_t N, typename MA = A,
typename std::enable_if<MA::min_match == MA::max_match &&
static_min<B::min_match...>::value !=
static_max<B::max_match...>::value, int>::type = 0>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos, size<A_EQUAL_B_NOT_EQUAL>) {
if (A::match(source, pos) >= 0) {
return A::lookahead;
}
return OR<B...>::match(source, pos);
}

template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
return match<N>(source, pos, size<index>{});
}

static const size_t min_value = static_min<B::min_match...>::value;
static const size_t max_value = static_max<B::max_match...>::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<A::lookahead, B::lookahead...>::value;
static const std::size_t min_match = static_min<A::min_match, B::min_match...>::value;
static const std::size_t max_match = static_max<A::max_match, B::max_match...>::value;
Expand All @@ -138,23 +141,17 @@ struct OR<A> {
template <typename A, typename... B>
struct SEQ {

template <std::size_t N, typename MA = A,
typename std::enable_if<MA::min_match != MA::max_match &&
static_sum<B::min_match...>::value !=
static_sum<B::max_match...>::value, int>::type = 0>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos, size<A_NOT_EQUAL_B_NOT_EQUAL>) {
int a = A::match(source, pos);
if (a < 0) { return -1; }
int b = SEQ<B...>::match(source, pos + a);
if (b < 0) { return -1; }
return a + b;
}

template <std::size_t N, typename MA = A,
typename std::enable_if<MA::min_match == MA::max_match &&
static_sum<B::min_match...>::value ==
static_sum<B::max_match...>::value, int>::type = 0>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos, size<A_EQUAL_B_EQUAL>) {
if (A::match(source, pos) < 0) {
return -1;
}
Expand All @@ -164,11 +161,8 @@ struct SEQ {
return lookahead;
}

template <std::size_t N, typename MA = A,
typename std::enable_if<MA::min_match != MA::max_match &&
static_sum<B::min_match...>::value ==
static_sum<B::max_match...>::value, int>::type = 0>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos, size<A_NOT_EQUAL_B_EQUAL>) {
int a = A::match(source, pos);
if (a < 0) { return -1; }
if (SEQ<B...>::match(source, pos + a) < 0) {
Expand All @@ -177,18 +171,25 @@ struct SEQ {
return a + static_sum<B::lookahead...>::value;
}

template <std::size_t N, typename MA = A,
typename std::enable_if<MA::min_match == MA::max_match &&
static_sum<B::min_match...>::value !=
static_sum<B::max_match...>::value, int>::type = 0>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos, size<A_EQUAL_B_NOT_EQUAL>) {
if (A::match(source, pos) < 0) {
return -1;
}
int b = SEQ<B...>::match(source, pos + A::lookahead);
if (b < 0) { return -1; }
return A::lookahead + b;
}

template <std::size_t N>
REGEXP_INLINE static int match(Source<N> source, const size_t pos) {
return match<N>(source, pos, size<index>{});
}

static const size_t min_value = static_sum<B::min_match...>::value;
static const size_t max_value = static_sum<B::max_match...>::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<A::lookahead, B::lookahead...>::value;
static const std::size_t min_match = static_sum<A::min_match, B::min_match...>::value;
static const std::size_t max_match = static_sum<A::max_match, B::max_match...>::value;
Expand Down
54 changes: 26 additions & 28 deletions src/plalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,20 @@ struct plalloc {

typedef T value_type;

plalloc() = default;
plalloc(): memory(new std::vector<std::unique_ptr<char>>()),
available(new std::vector<void *>()) {
};
template<typename U>
plalloc(const plalloc<U, N> &) {}
plalloc(const plalloc &) {}
plalloc & operator=(const plalloc &) { return *this; }
plalloc(const plalloc<U, N> &) : memory(new std::vector<std::unique_ptr<char>>()),
available(new std::vector<void *>()) {
}
plalloc(const plalloc &) : memory(new std::vector<std::unique_ptr<char>>()),
available(new std::vector<void *>()) {
}
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;
Expand All @@ -59,31 +66,28 @@ struct plalloc {
T * allocate(size_t num_to_allocate) {
if (num_to_allocate != 1) {
return static_cast<T *>(::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<value_holder[]> 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<char> 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);
}
Expand All @@ -110,13 +114,7 @@ struct plalloc {
object->~U();
}

private:
union value_holder {
value_holder() {}
~value_holder() {}
T value;
};

std::vector<std::unique_ptr<value_holder[]>> memory;
std::vector<T *> available;
public:
std::vector<std::unique_ptr<char>> *memory;
std::vector<void *> *available;
};
3 changes: 2 additions & 1 deletion src/scanscalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions src/simplekey.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "scanner.h"
#include "token.h"

#include "yaml-cpp/dll.h"

namespace YAML {
struct Mark;

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
2 changes: 0 additions & 2 deletions src/stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 2 additions & 1 deletion src/stream.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "yaml-cpp/noncopyable.h"
#include "yaml-cpp/dll.h"
#include "yaml-cpp/mark.h"
#include "streamcharsource.h"

Expand Down Expand Up @@ -89,7 +90,7 @@ class Stream : private noncopyable {
int offset = m_mark.pos - m_lookahead.streamPos;
auto dst = reinterpret_cast<uint32_t*>(out.data());

if (__builtin_expect(m_lookahead.available > 4 + offset, 1)) {
if (likely(m_lookahead.available > 4 + offset)) {
auto src = reinterpret_cast<uint64_t*>(m_lookahead.buffer.data());
dst[0] = src[0] >> (offset * 8);
} else {
Expand Down