folly: use std::__throw_out_of_range
authorLucian Grijincu <lucian@fb.com>
Fri, 30 Sep 2016 19:12:32 +0000 (12:12 -0700)
committerFacebook Github Bot <facebook-github-bot-bot@fb.com>
Fri, 30 Sep 2016 19:23:29 +0000 (12:23 -0700)
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
folly/FBVector.h
folly/dynamic.cpp
folly/io/Cursor-inl.h
folly/io/Cursor.h
folly/small_vector.h
folly/sorted_vector_types.h

index 3059fb5..8a4240b 100644 (file)
@@ -24,6 +24,7 @@
 #include <boost/intrusive/list.hpp>
 #include <boost/intrusive/unordered_set.hpp>
 #include <boost/iterator/iterator_adaptor.hpp>
+#include <folly/portability/BitsFunctexcept.h>
 
 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;
   }
index 174343a..6c6de44 100644 (file)
@@ -39,6 +39,7 @@
 #include <folly/Likely.h>
 #include <folly/Malloc.h>
 #include <folly/Traits.h>
+#include <folly/portability/BitsFunctexcept.h>
 
 #include <boost/operators.hpp>
 
@@ -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];
   }
index 7015d8b..5e656c5 100644 (file)
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-#include <folly/dynamic.h>
 #include <folly/Hash.h>
+#include <folly/dynamic.h>
+#include <folly/portability/BitsFunctexcept.h>
 
 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<ObjectImpl>()) {
index ec5038e..6c16a38 100644 (file)
@@ -60,7 +60,7 @@ std::string CursorBase<Derived, BufType>::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);
 
index f33a0ce..b32670a 100644 (file)
 #include <memory>
 
 #include <folly/Bits.h>
-#include <folly/io/IOBuf.h>
-#include <folly/io/IOBufQueue.h>
 #include <folly/Likely.h>
 #include <folly/Memory.h>
 #include <folly/Portability.h>
 #include <folly/Range.h>
+#include <folly/io/IOBuf.h>
+#include <folly/io/IOBufQueue.h>
+#include <folly/portability/BitsFunctexcept.h>
 
 /**
  * Cursor class for fast iteration over IOBuf chains.
@@ -326,13 +327,13 @@ class CursorBase {
 
   void clone(std::unique_ptr<folly::IOBuf>& 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<const char*>(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<Derived*>(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<Appender> {
     // 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_);
index aea4746..b3db04e 100644 (file)
@@ -47,6 +47,7 @@
 #include <folly/Malloc.h>
 #include <folly/Portability.h>
 #include <folly/SmallLocks.h>
+#include <folly/portability/BitsFunctexcept.h>
 #include <folly/portability/Constexpr.h>
 #include <folly/portability/Malloc.h>
 #include <folly/portability/TypeTraits.h>
@@ -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];
   }
index cc5c9c3..d603886 100644 (file)
@@ -68,6 +68,7 @@
 #include <vector>
 
 #include <boost/operators.hpp>
+#include <folly/portability/BitsFunctexcept.h>
 
 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 {