From: Lucian Grijincu Date: Thu, 29 Sep 2016 05:33:39 +0000 (-0700) Subject: folly: Range: outline exception throwing X-Git-Tag: v2016.10.03.00~8 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d6c0ba0195950a4adda3c2abb9439dc2e86ca282;p=folly.git folly: Range: outline exception throwing Summary: Here's some godbolt: https://godbolt.org/g/9K36Km advanceNoInline(S): movq %rdi, %rax sarq $32, %rax cmpl %eax, %edi jg .L20 leal 1(%rdi), %eax ret .L20: subq $8, %rsp call S::outOfRange() [clone .isra.0] vs previous implementation advance(S): movq %rdi, %rdx sarq $32, %rdx cmpl %edx, %edi jg .L14 leal 1(%rdi), %eax ret .L14: pushq %rbp pushq %rbx movl $16, %edi subq $8, %rsp call __cxa_allocate_exception movl $.LC0, %esi movq %rax, %rdi movq %rax, %rbx call std::out_of_range::out_of_range(char const*) movl std::out_of_range::~out_of_range(), %edx movl typeinfo for std::out_of_range, %esi movq %rbx, %rdi call __cxa_throw movq %rax, %rbp movq %rbx, %rdi call __cxa_free_exception movq %rbp, %rdi call _Unwind_Resume Reviewed By: ot Differential Revision: D3940968 fbshipit-source-id: b47a41e7cdd863fcef099ff3c21860b2979ee6e8 --- diff --git a/folly/Range.h b/folly/Range.h index 59e14bd5..9cacdd58 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -145,6 +145,11 @@ struct IsCharPointer { typedef int type; }; +// Prevent it from being inlined to reduce instruction bloat. +FOLLY_NOINLINE inline void throwOutOfRange() { + throw std::out_of_range("index out of range"); +} + } // namespace detail /** @@ -217,7 +222,7 @@ public: template ::const_type = 0> Range(const std::string& str, std::string::size_type startFrom) { if (UNLIKELY(startFrom > str.size())) { - throw std::out_of_range("index out of range"); + detail::throwOutOfRange(); } b_ = str.data() + startFrom; e_ = str.data() + str.size(); @@ -228,7 +233,7 @@ public: std::string::size_type startFrom, std::string::size_type size) { if (UNLIKELY(startFrom > str.size())) { - throw std::out_of_range("index out of range"); + detail::throwOutOfRange(); } b_ = str.data() + startFrom; if (str.size() - startFrom < size) { @@ -251,7 +256,7 @@ public: template ::const_type = 0> Range(const fbstring& str, fbstring::size_type startFrom) { if (UNLIKELY(startFrom > str.size())) { - throw std::out_of_range("index out of range"); + detail::throwOutOfRange(); } b_ = str.data() + startFrom; e_ = str.data() + str.size(); @@ -261,7 +266,7 @@ public: Range(const fbstring& str, fbstring::size_type startFrom, fbstring::size_type size) { if (UNLIKELY(startFrom > str.size())) { - throw std::out_of_range("index out of range"); + detail::throwOutOfRange(); } b_ = str.data() + startFrom; if (str.size() - startFrom < size) { @@ -426,12 +431,12 @@ public: } value_type& at(size_t i) { - if (i >= size()) throw std::out_of_range("index out of range"); + if (i >= size()) detail::throwOutOfRange(); return b_[i]; } const value_type& at(size_t i) const { - if (i >= size()) throw std::out_of_range("index out of range"); + if (i >= size()) detail::throwOutOfRange(); return b_[i]; } @@ -453,21 +458,21 @@ public: void advance(size_type n) { if (UNLIKELY(n > size())) { - throw std::out_of_range("index out of range"); + detail::throwOutOfRange(); } b_ += n; } void subtract(size_type n) { if (UNLIKELY(n > size())) { - throw std::out_of_range("index out of range"); + detail::throwOutOfRange(); } e_ -= n; } Range subpiece(size_type first, size_type length = npos) const { if (UNLIKELY(first > size())) { - throw std::out_of_range("index out of range"); + detail::throwOutOfRange(); } return Range(b_ + first, std::min(length, size() - first)); @@ -628,7 +633,7 @@ public: } else if (e == e_) { e_ = b; } else { - throw std::out_of_range("index out of range"); + detail::throwOutOfRange(); } }