From eb6bd53fde2fd971d891c06fa81f8d0e385a79a1 Mon Sep 17 00:00:00 2001 From: Lucian Grijincu Date: Fri, 30 Sep 2016 12:12:32 -0700 Subject: [PATCH] folly: use std::__throw_out_of_range Summary: A ton of these functions are tiny and should be inlined. `throw std::out_of_range("bla")` generates quite a lot of code. See godbolt from {D3940968}: 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 This pattern is in the standard library as well: ``` reference at(size_type __n) { if (__n >= _Nm) std::__throw_out_of_range(__N("array::at")); return _M_instance[__n]; } ``` https://github.com/gcc-mirror/gcc/blob/edd716b6b1caa1a5cb320a8cd7f626f30198e098/libstdc%2B%2B-v3/include/tr1/array#L138 Reviewed By: yfeldblum Differential Revision: D3947075 fbshipit-source-id: 6e174c725791762a533a534c8482ea9576460b86 --- folly/EvictingCacheMap.h | 5 +++-- folly/FBVector.h | 3 ++- folly/dynamic.cpp | 5 +++-- folly/io/Cursor-inl.h | 2 +- folly/io/Cursor.h | 29 +++++++++++++++-------------- folly/small_vector.h | 5 +++-- folly/sorted_vector_types.h | 5 +++-- 7 files changed, 30 insertions(+), 24 deletions(-) diff --git a/folly/EvictingCacheMap.h b/folly/EvictingCacheMap.h index 3059fb5e..8a4240bd 100644 --- a/folly/EvictingCacheMap.h +++ b/folly/EvictingCacheMap.h @@ -24,6 +24,7 @@ #include #include #include +#include namespace folly { @@ -205,7 +206,7 @@ class EvictingCacheMap : private boost::noncopyable { TValue& get(const TKey& key) { auto it = find(key); if (it == end()) { - throw std::out_of_range("Key does not exist"); + std::__throw_out_of_range("Key does not exist"); } return it->second; } @@ -237,7 +238,7 @@ class EvictingCacheMap : private boost::noncopyable { const TValue& getWithoutPromotion(const TKey& key) const { auto it = findWithoutPromotion(key); if (it == end()) { - throw std::out_of_range("Key does not exist"); + std::__throw_out_of_range("Key does not exist"); } return it->second; } diff --git a/folly/FBVector.h b/folly/FBVector.h index 174343a2..6c6de44e 100644 --- a/folly/FBVector.h +++ b/folly/FBVector.h @@ -39,6 +39,7 @@ #include #include #include +#include #include @@ -1042,7 +1043,7 @@ public: } const_reference at(size_type n) const { if (UNLIKELY(n >= size())) { - throw std::out_of_range("fbvector: index is greater than size."); + std::__throw_out_of_range("fbvector: index is greater than size."); } return (*this)[n]; } diff --git a/folly/dynamic.cpp b/folly/dynamic.cpp index 7015d8b8..5e656c5e 100644 --- a/folly/dynamic.cpp +++ b/folly/dynamic.cpp @@ -14,8 +14,9 @@ * limitations under the License. */ -#include #include +#include +#include namespace folly { @@ -223,7 +224,7 @@ dynamic const& dynamic::at(dynamic const& idx) const& { throw TypeError("int64", idx.type()); } if (idx < 0 || idx >= parray->size()) { - throw std::out_of_range("out of range in dynamic array"); + std::__throw_out_of_range("out of range in dynamic array"); } return (*parray)[idx.asInt()]; } else if (auto* pobject = get_nothrow()) { diff --git a/folly/io/Cursor-inl.h b/folly/io/Cursor-inl.h index ec5038e5..6c16a380 100644 --- a/folly/io/Cursor-inl.h +++ b/folly/io/Cursor-inl.h @@ -60,7 +60,7 @@ std::string CursorBase::readTerminatedString( auto result = readWhile(keepReading); // skip over the terminator character if (isAtEnd()) { - throw std::out_of_range("terminator not found"); + std::__throw_out_of_range("terminator not found"); } skip(1); diff --git a/folly/io/Cursor.h b/folly/io/Cursor.h index f33a0cea..b32670a2 100644 --- a/folly/io/Cursor.h +++ b/folly/io/Cursor.h @@ -24,12 +24,13 @@ #include #include -#include -#include #include #include #include #include +#include +#include +#include /** * Cursor class for fast iteration over IOBuf chains. @@ -326,13 +327,13 @@ class CursorBase { void clone(std::unique_ptr& buf, size_t len) { if (UNLIKELY(cloneAtMost(buf, len) != len)) { - throw std::out_of_range("underflow"); + std::__throw_out_of_range("underflow"); } } void clone(folly::IOBuf& buf, size_t len) { if (UNLIKELY(cloneAtMost(buf, len) != len)) { - throw std::out_of_range("underflow"); + std::__throw_out_of_range("underflow"); } } @@ -400,13 +401,13 @@ class CursorBase { } if (otherBuf == other.buffer_) { - throw std::out_of_range("wrap-around"); + std::__throw_out_of_range("wrap-around"); } len += offset_; } else { if (offset_ < other.offset_) { - throw std::out_of_range("underflow"); + std::__throw_out_of_range("underflow"); } len += offset_ - other.offset_; @@ -426,7 +427,7 @@ class CursorBase { len += curBuf->length(); curBuf = curBuf->next(); if (curBuf == buf || curBuf == buffer_) { - throw std::out_of_range("wrap-around"); + std::__throw_out_of_range("wrap-around"); } } @@ -468,7 +469,7 @@ class CursorBase { for (size_t available; (available = length()) < len; ) { str->append(reinterpret_cast(data()), available); if (UNLIKELY(!tryAdvanceBuffer())) { - throw std::out_of_range("string underflow"); + std::__throw_out_of_range("string underflow"); } len -= available; } @@ -497,7 +498,7 @@ class CursorBase { void pullSlow(void* buf, size_t len) { if (UNLIKELY(pullAtMostSlow(buf, len) != len)) { - throw std::out_of_range("underflow"); + std::__throw_out_of_range("underflow"); } } @@ -517,7 +518,7 @@ class CursorBase { void skipSlow(size_t len) { if (UNLIKELY(skipAtMostSlow(len) != len)) { - throw std::out_of_range("underflow"); + std::__throw_out_of_range("underflow"); } } @@ -567,13 +568,13 @@ class Writable { void push(const uint8_t* buf, size_t len) { Derived* d = static_cast(this); if (d->pushAtMost(buf, len) != len) { - throw std::out_of_range("overflow"); + std::__throw_out_of_range("overflow"); } } void push(ByteRange buf) { if (this->pushAtMost(buf) != buf.size()) { - throw std::out_of_range("overflow"); + std::__throw_out_of_range("overflow"); } } @@ -589,7 +590,7 @@ class Writable { */ void push(Cursor cursor, size_t len) { if (this->pushAtMost(cursor, len) != len) { - throw std::out_of_range("overflow"); + std::__throw_out_of_range("overflow"); } } @@ -783,7 +784,7 @@ class Appender : public detail::Writable { // Waste the rest of the current buffer and allocate a new one. // Don't make it too small, either. if (growth_ == 0) { - throw std::out_of_range("can't grow buffer chain"); + std::__throw_out_of_range("can't grow buffer chain"); } n = std::max(n, growth_); diff --git a/folly/small_vector.h b/folly/small_vector.h index aea4746b..b3db04ea 100644 --- a/folly/small_vector.h +++ b/folly/small_vector.h @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -781,14 +782,14 @@ class small_vector reference at(size_type i) { if (i >= size()) { - throw std::out_of_range("index out of range"); + std::__throw_out_of_range("index out of range"); } return (*this)[i]; } const_reference at(size_type i) const { if (i >= size()) { - throw std::out_of_range("index out of range"); + std::__throw_out_of_range("index out of range"); } return (*this)[i]; } diff --git a/folly/sorted_vector_types.h b/folly/sorted_vector_types.h index cc5c9c3c..d6038869 100644 --- a/folly/sorted_vector_types.h +++ b/folly/sorted_vector_types.h @@ -68,6 +68,7 @@ #include #include +#include namespace folly { @@ -558,7 +559,7 @@ public: if (it != end()) { return it->second; } - throw std::out_of_range("sorted_vector_map::at"); + std::__throw_out_of_range("sorted_vector_map::at"); } const mapped_type& at(const key_type& key) const { @@ -566,7 +567,7 @@ public: if (it != end()) { return it->second; } - throw std::out_of_range("sorted_vector_map::at"); + std::__throw_out_of_range("sorted_vector_map::at"); } size_type count(const key_type& key) const { -- 2.34.1