diff options
Diffstat (limited to 'src/mongo/bson')
-rw-r--r-- | src/mongo/bson/bsonobjbuilder.cpp | 20 | ||||
-rw-r--r-- | src/mongo/bson/util/builder.h | 31 | ||||
-rw-r--r-- | src/mongo/bson/util/builder_test.cpp | 4 |
3 files changed, 28 insertions, 27 deletions
diff --git a/src/mongo/bson/bsonobjbuilder.cpp b/src/mongo/bson/bsonobjbuilder.cpp index 1eab3f0b93c..39538ecf6c5 100644 --- a/src/mongo/bson/bsonobjbuilder.cpp +++ b/src/mongo/bson/bsonobjbuilder.cpp @@ -235,25 +235,9 @@ BSONObjBuilder::~BSONObjBuilder() { } } -template <typename Alloc> -void BasicBufBuilder<Alloc>::grow_reallocate(int minSize) { - if (minSize > BufferMaxSize) { - std::stringstream ss; - ss << "BufBuilder attempted to grow() to " << minSize << " bytes, past the 64MB limit."; - msgasserted(13548, ss.str().c_str()); - } - - int a = 64; - while (a < minSize) - a = a * 2; - - _buf.realloc(a); - size = a; -} - template class BasicBufBuilder<SharedBufferAllocator>; -template class BasicBufBuilder<StackAllocator>; +template class BasicBufBuilder<StackAllocator<StackSizeDefault>>; template class StringBuilderImpl<SharedBufferAllocator>; -template class StringBuilderImpl<StackAllocator>; +template class StringBuilderImpl<StackAllocator<StackSizeDefault>>; } // namespace mongo diff --git a/src/mongo/bson/util/builder.h b/src/mongo/bson/util/builder.h index a6c821c5b0f..64b578faafd 100644 --- a/src/mongo/bson/util/builder.h +++ b/src/mongo/bson/util/builder.h @@ -111,6 +111,8 @@ private: SharedBuffer _buf; }; +enum { StackSizeDefault = 512 }; +template <size_t SZ> class StackAllocator { StackAllocator(const StackAllocator&) = delete; StackAllocator& operator=(const StackAllocator&) = delete; @@ -121,7 +123,6 @@ public: free(); } - enum { SZ = 512 }; void malloc(size_t sz) { if (sz > SZ) _ptr = mongoMalloc(sz); @@ -340,7 +341,21 @@ private: DataView(grow(sizeof(t))).write(tagLittleEndian(t)); } /* "slow" portion of 'grow()' */ - void grow_reallocate(int minSize); + void grow_reallocate(int minSize) { + if (minSize > BufferMaxSize) { + std::stringstream ss; + ss << "BufBuilder attempted to grow() to " << minSize << " bytes, past the 64MB limit."; + msgasserted(13548, ss.str().c_str()); + } + + int a = 64; + while (a < minSize) + a = a * 2; + + _buf.realloc(a); + size = a; + } + BufferAllocator _buf; int l; @@ -360,11 +375,13 @@ MONGO_STATIC_ASSERT(std::is_move_constructible_v<BufBuilder>); nothing bad would happen. In fact in some circumstances this might make sense, say, embedded in some other object. */ -class StackBufBuilder : public BasicBufBuilder<StackAllocator> { +template <size_t SZ> +class StackBufBuilderBase : public BasicBufBuilder<StackAllocator<SZ>> { public: - StackBufBuilder() : BasicBufBuilder<StackAllocator>(StackAllocator::SZ) {} + StackBufBuilderBase() : BasicBufBuilder<StackAllocator<SZ>>(SZ) {} void release() = delete; // not allowed. not implemented. }; +using StackBufBuilder = StackBufBuilderBase<StackSizeDefault>; MONGO_STATIC_ASSERT(!std::is_move_constructible<StackBufBuilder>::value); /** std::stringstream deals with locale so this is a lot faster than std::stringstream for UTF8 */ @@ -524,11 +541,11 @@ private: }; using StringBuilder = StringBuilderImpl<SharedBufferAllocator>; -using StackStringBuilder = StringBuilderImpl<StackAllocator>; +using StackStringBuilder = StringBuilderImpl<StackAllocator<StackSizeDefault>>; extern template class BasicBufBuilder<SharedBufferAllocator>; -extern template class BasicBufBuilder<StackAllocator>; +extern template class BasicBufBuilder<StackAllocator<StackSizeDefault>>; extern template class StringBuilderImpl<SharedBufferAllocator>; -extern template class StringBuilderImpl<StackAllocator>; +extern template class StringBuilderImpl<StackAllocator<StackSizeDefault>>; } // namespace mongo diff --git a/src/mongo/bson/util/builder_test.cpp b/src/mongo/bson/util/builder_test.cpp index a1c1f127eb0..a4ed4c87115 100644 --- a/src/mongo/bson/util/builder_test.cpp +++ b/src/mongo/bson/util/builder_test.cpp @@ -79,8 +79,8 @@ TEST(Builder, BooleanOstreamOperator) { } TEST(Builder, StackAllocatorShouldNotLeak) { - StackAllocator stackAlloc; - stackAlloc.malloc(StackAllocator::SZ + 1); // Force heap allocation. + StackAllocator<StackSizeDefault> stackAlloc; + stackAlloc.malloc(StackSizeDefault + 1); // Force heap allocation. // Let the builder go out of scope. If this leaks, it will trip the ASAN leak detector. } |