summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBilly Donahue <billy.donahue@mongodb.com>2023-05-09 16:33:30 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-05-09 21:51:49 +0000
commitf439c82251932419f9eae69fd48358132cce58e7 (patch)
tree9acdd4029bee4c7baca43a90c3d8ba292e417e0b
parentb6eab7e7d83b10cef5c57f781c1751b465aade9f (diff)
downloadmongo-f439c82251932419f9eae69fd48358132cce58e7.tar.gz
SERVER-39506 destroying delete for RCString
-rw-r--r--src/mongo/db/SConscript1
-rw-r--r--src/mongo/db/exec/document_value/SConscript1
-rw-r--r--src/mongo/db/exec/document_value/value_internal.h69
-rw-r--r--src/mongo/util/SConscript10
-rw-r--r--src/mongo/util/intrusive_counter.cpp60
-rw-r--r--src/mongo/util/intrusive_counter.h46
6 files changed, 72 insertions, 115 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index d0debcf9e1f..2d5d9447d8e 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -1657,7 +1657,6 @@ env.Library(
'$BUILD_DIR/mongo/crypto/fle_crypto',
'$BUILD_DIR/mongo/scripting/scripting',
'$BUILD_DIR/mongo/scripting/scripting_common',
- '$BUILD_DIR/mongo/util/intrusive_counter',
'$BUILD_DIR/mongo/util/pcre_util',
'$BUILD_DIR/mongo/util/pcre_wrapper',
'$BUILD_DIR/mongo/util/summation',
diff --git a/src/mongo/db/exec/document_value/SConscript b/src/mongo/db/exec/document_value/SConscript
index 9d0947da749..5899cb089fc 100644
--- a/src/mongo/db/exec/document_value/SConscript
+++ b/src/mongo/db/exec/document_value/SConscript
@@ -15,7 +15,6 @@ env.Library(
'$BUILD_DIR/mongo/base',
'$BUILD_DIR/mongo/db/pipeline/field_path',
'$BUILD_DIR/mongo/db/query/datetime/date_time_support',
- '$BUILD_DIR/mongo/util/intrusive_counter',
],
)
diff --git a/src/mongo/db/exec/document_value/value_internal.h b/src/mongo/db/exec/document_value/value_internal.h
index b19af0e728f..8f36c8f800e 100644
--- a/src/mongo/db/exec/document_value/value_internal.h
+++ b/src/mongo/db/exec/document_value/value_internal.h
@@ -30,14 +30,20 @@
#pragma once
#include <algorithm>
+#include <cstdlib>
+#include <new>
+
#include <boost/intrusive_ptr.hpp>
#include "mongo/base/static_assert.h"
+#include "mongo/base/string_data.h"
#include "mongo/bson/bsonmisc.h"
#include "mongo/bson/bsonobj.h"
#include "mongo/bson/bsontypes.h"
#include "mongo/bson/oid.h"
#include "mongo/bson/timestamp.h"
+#include "mongo/bson/util/builder.h"
+#include "mongo/util/assert_util.h"
#include "mongo/util/debug_util.h"
#include "mongo/util/intrusive_counter.h"
@@ -47,6 +53,67 @@ class Document;
class DocumentStorage;
class Value;
+
+/** An immutable reference-counted string of inline data. */
+class RCString final : public RefCountable {
+public:
+ static boost::intrusive_ptr<const RCString> create(StringData s) {
+ using namespace fmt::literals;
+ static constexpr size_t sizeLimit = BSONObjMaxUserSize;
+ uassert(16493,
+ "RCString too large. Requires size={} < limit={}"_format(s.size(), sizeLimit),
+ s.size() < sizeLimit);
+ return boost::intrusive_ptr{new (s) RCString{s}};
+ }
+
+ explicit operator StringData() const noexcept {
+ return StringData{_data(), _size};
+ }
+
+ void* operator new(size_t, StringData s) {
+ return ::operator new(_allocSize(s.size()));
+ }
+
+ /** Used if constructor fails after placement `new (StringData)`. */
+ void operator delete(void* ptr, StringData s) {
+ ::operator delete(ptr, _allocSize(s.size()));
+ }
+
+#if __cpp_lib_destroying_delete >= 201806L
+ void operator delete(RCString* ptr, std::destroying_delete_t) {
+ size_t sz = _allocSize(ptr->_size);
+ ptr->~RCString();
+ ::operator delete(ptr, sz);
+ }
+#else // !__cpp_lib_destroying_delete
+ /** Invoked by virtual destructor. */
+ void operator delete(void* ptr) {
+ ::operator delete(ptr);
+ }
+#endif // __cpp_lib_destroying_delete
+
+private:
+ static size_t _allocSize(size_t stringSize) {
+ return sizeof(RCString) + stringSize + 1; // Incl. '\0'-terminator
+ }
+
+ /** Use static `create()` instead. */
+ explicit RCString(StringData s) : _size{s.size()} {
+ if (_size)
+ memcpy(_data(), s.rawData(), _size);
+ _data()[_size] = '\0';
+ }
+
+ const char* _data() const noexcept {
+ return reinterpret_cast<const char*>(this + 1);
+ }
+ char* _data() noexcept {
+ return const_cast<char*>(std::as_const(*this)._data());
+ }
+
+ size_t _size; /** Excluding '\0' terminator. */
+};
+
// TODO: a MutableVector, similar to MutableDocument
/// A heap-allocated reference-counted std::vector
class RCVector : public RefCountable {
@@ -268,7 +335,7 @@ public:
} else {
dassert(typeid(*genericRCPtr) == typeid(const RCString));
const RCString* stringPtr = static_cast<const RCString*>(genericRCPtr);
- return StringData(stringPtr->c_str(), stringPtr->size());
+ return StringData{*stringPtr};
}
}
diff --git a/src/mongo/util/SConscript b/src/mongo/util/SConscript
index 4f92d284478..aff0ed44fef 100644
--- a/src/mongo/util/SConscript
+++ b/src/mongo/util/SConscript
@@ -115,16 +115,6 @@ env.Library(
)
env.Library(
- target='intrusive_counter',
- source=[
- 'intrusive_counter.cpp',
- ],
- LIBDEPS=[
- '$BUILD_DIR/mongo/base',
- ],
-)
-
-env.Library(
target='log_and_backoff',
source=[
'log_and_backoff.cpp',
diff --git a/src/mongo/util/intrusive_counter.cpp b/src/mongo/util/intrusive_counter.cpp
deleted file mode 100644
index e33cbc87da5..00000000000
--- a/src/mongo/util/intrusive_counter.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * Copyright (C) 2018-present MongoDB, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the Server Side Public License, version 1,
- * as published by MongoDB, Inc.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * Server Side Public License for more details.
- *
- * You should have received a copy of the Server Side Public License
- * along with this program. If not, see
- * <http://www.mongodb.com/licensing/server-side-public-license>.
- *
- * As a special exception, the copyright holders give permission to link the
- * code of portions of this program with the OpenSSL library under certain
- * conditions as described in each individual source file and distribute
- * linked combinations including the program with the OpenSSL library. You
- * must comply with the Server Side Public License in all respects for
- * all of the code used other than as permitted herein. If you modify file(s)
- * with this exception, you may extend this exception to your version of the
- * file(s), but you are not obligated to do so. If you do not wish to do so,
- * delete this exception statement from your version. If you delete this
- * exception statement from all source files in the program, then also delete
- * it in the license file.
- */
-
-#include "mongo/platform/basic.h"
-
-#include "mongo/util/intrusive_counter.h"
-
-#include "mongo/util/str.h"
-
-namespace mongo {
-using boost::intrusive_ptr;
-
-intrusive_ptr<const RCString> RCString::create(StringData s) {
- uassert(16493,
- str::stream() << "Tried to create string longer than "
- << (BSONObjMaxUserSize / 1024 / 1024) << "MB",
- s.size() < static_cast<size_t>(BSONObjMaxUserSize));
-
- const size_t sizeWithNUL = s.size() + 1;
- const size_t bytesNeeded = sizeof(RCString) + sizeWithNUL;
-
-#pragma warning(push)
-#pragma warning(disable : 4291)
- intrusive_ptr<RCString> ptr = new (bytesNeeded) RCString(); // uses custom operator new
-#pragma warning(pop)
-
- ptr->_size = s.size();
- char* stringStart = reinterpret_cast<char*>(ptr.get()) + sizeof(RCString);
- s.copyTo(stringStart, true);
-
- return ptr;
-}
-
-} // namespace mongo
diff --git a/src/mongo/util/intrusive_counter.h b/src/mongo/util/intrusive_counter.h
index 38d024ddea6..9041f50d937 100644
--- a/src/mongo/util/intrusive_counter.h
+++ b/src/mongo/util/intrusive_counter.h
@@ -29,12 +29,11 @@
#pragma once
+#include <atomic> // NOLINT
#include <boost/intrusive_ptr.hpp>
#include <cstdlib>
-#include "mongo/base/string_data.h"
-#include "mongo/platform/atomic_word.h"
-#include "mongo/util/allocator.h"
+#include "mongo/util/assert_util_core.h"
namespace mongo {
@@ -67,13 +66,13 @@ public:
// See this for a description of why relaxed is OK here. It is also used in libc++.
// http://www.boost.org/doc/libs/1_66_0/doc/html/atomic/usage_examples.html#boost_atomic.usage_examples.example_reference_counters.discussion
ptr->_count.fetch_add(1, std::memory_order_relaxed);
- };
+ }
friend void intrusive_ptr_release(const RefCountable* ptr) {
if (ptr->_count.fetch_sub(1, std::memory_order_acq_rel) == 1) {
delete ptr;
}
- };
+ }
protected:
/**
@@ -101,41 +100,4 @@ boost::intrusive_ptr<T> make_intrusive(Args&&... args) {
ptr->threadUnsafeIncRefCountTo(1);
return boost::intrusive_ptr<T>(ptr, /*add ref*/ false);
}
-
-/// This is an immutable reference-counted string
-class RCString : public RefCountable {
-public:
- const char* c_str() const {
- return reinterpret_cast<const char*>(this) + sizeof(RCString);
- }
- int size() const {
- return _size;
- }
- StringData stringData() const {
- return StringData(c_str(), _size);
- }
-
- static boost::intrusive_ptr<const RCString> create(StringData s);
-
-// MSVC: C4291: 'declaration' : no matching operator delete found; memory will not be freed if
-// initialization throws an exception
-// We simply rely on the default global placement delete since a local placement delete would be
-// ambiguous for some compilers
-#pragma warning(push)
-#pragma warning(disable : 4291)
- void operator delete(void* ptr) {
- free(ptr);
- }
-#pragma warning(pop)
-
-private:
- // these can only be created by calling create()
- RCString(){};
- void* operator new(size_t objSize, size_t realSize) {
- return mongoMalloc(realSize);
- }
-
- int _size; // does NOT include trailing NUL byte.
- // char[_size+1] array allocated past end of class
-};
} // namespace mongo