Add some unique_ptr-related support to smart:: containers
- smart::make_unique, returns a unique pointer to smart allocated
data.
- Support forwarding in our allocator's construct, so
smart::vector<foo::unique_ptr<>> works.
- Move smart containers to their own header.
Esse commit está contido em:
@@ -18,6 +18,9 @@
|
||||
#define incl_HPHP_MEMORY_MANAGER_H_
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include "folly/Memory.h"
|
||||
|
||||
#include "hphp/util/thread_local.h"
|
||||
#include "hphp/runtime/base/memory/memory_usage_stats.h"
|
||||
|
||||
@@ -395,137 +398,6 @@ void* smart_calloc(size_t count, size_t bytes);
|
||||
void* smart_realloc(void* ptr, size_t nbytes);
|
||||
void smart_free(void* ptr);
|
||||
|
||||
namespace smart {
|
||||
namespace do_not_use_directly {
|
||||
/*
|
||||
* We are deriving from the std::collection classes to get
|
||||
* smart::collection classes that use smart allocation.
|
||||
* To avoid the various issues involved with deriving
|
||||
* from value types, we want to make sure that there are
|
||||
* no references to std::collection<...,SmartStlAlloc<>>
|
||||
* other than the ones below. That way we know that
|
||||
* a pointer to a smart::collection can never decay
|
||||
* to a pointer to a std::collection.
|
||||
*
|
||||
* The namespace do_not_use_directly should remind us
|
||||
* of that.
|
||||
*
|
||||
*/
|
||||
template <class T>
|
||||
class SmartStlAlloc {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
template <class U>
|
||||
struct rebind {
|
||||
typedef SmartStlAlloc<U> other;
|
||||
};
|
||||
|
||||
pointer address (reference value) const {
|
||||
return &value;
|
||||
}
|
||||
const_pointer address (const_reference value) const {
|
||||
return &value;
|
||||
}
|
||||
|
||||
SmartStlAlloc() throw() {}
|
||||
SmartStlAlloc(const SmartStlAlloc&) {}
|
||||
template <class U>
|
||||
SmartStlAlloc (const SmartStlAlloc<U>&) {}
|
||||
~SmartStlAlloc() {}
|
||||
|
||||
size_type max_size () const {
|
||||
return std::numeric_limits<std::size_t>::max() / sizeof(T);
|
||||
}
|
||||
|
||||
pointer allocate (size_type num, const void* = 0) {
|
||||
pointer ret = (pointer)smart_malloc(num * sizeof(T));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void construct (pointer p, const T& value) {
|
||||
new ((void*)p) T(value);
|
||||
}
|
||||
|
||||
void construct (pointer p) {
|
||||
new ((void*)p) T();
|
||||
}
|
||||
|
||||
void destroy (pointer p) {
|
||||
p->~T();
|
||||
}
|
||||
|
||||
void deallocate (pointer p, size_type num) {
|
||||
smart_free(p);
|
||||
}
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
bool operator== (const SmartStlAlloc<T1>&,
|
||||
const SmartStlAlloc<T2>&) {
|
||||
return true;
|
||||
}
|
||||
template <class T1, class T2>
|
||||
bool operator!= (const SmartStlAlloc<T1>&,
|
||||
const SmartStlAlloc<T2>&) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Derivation from value types is generally bad.
|
||||
* Here, we derive from classes that do not exist anywhere
|
||||
* else in the code base (see comments above).
|
||||
*
|
||||
* We also add no functionality to the derived class. Your
|
||||
* code will not get past code review if you try to do so.
|
||||
*/
|
||||
template <class Key, class T, class Compare = std::less<Key> >
|
||||
class map : public std::map<
|
||||
Key, T, Compare,
|
||||
do_not_use_directly::SmartStlAlloc<std::pair<const Key, T> > > {};
|
||||
|
||||
template <class T>
|
||||
class deque : public std::deque<T, do_not_use_directly::SmartStlAlloc<T> > {};
|
||||
|
||||
template <class T>
|
||||
class vector : public std::vector<T, do_not_use_directly::SmartStlAlloc<T> > {
|
||||
typedef std::vector<T, do_not_use_directly::SmartStlAlloc<T> > Base_;
|
||||
public:
|
||||
template <typename... A>
|
||||
explicit vector(A &&... args) : Base_(std::forward<A>(args)...) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class list : public std::list<T, do_not_use_directly::SmartStlAlloc<T> > {};
|
||||
|
||||
template <class T>
|
||||
class queue : public std::queue<T, deque<T> > {};
|
||||
|
||||
template <class _T, class _U,
|
||||
class _V = hphp_hash<_T>,class _W = std::equal_to<_T> >
|
||||
struct hash_map : std::tr1::unordered_map<
|
||||
_T, _U, _V, _W, do_not_use_directly::SmartStlAlloc<std::pair<_T, _U> > > {
|
||||
hash_map() : std::tr1::unordered_map<
|
||||
_T, _U, _V, _W, do_not_use_directly::SmartStlAlloc<std::pair<_T, _U> >
|
||||
>(0) {}
|
||||
};
|
||||
|
||||
template <class _T,
|
||||
class _V = hphp_hash<_T>,class _W = std::equal_to<_T> >
|
||||
struct hash_set : std::tr1::unordered_set<
|
||||
_T, _V, _W, do_not_use_directly::SmartStlAlloc<_T> > {
|
||||
hash_set() : std::tr1::unordered_set<
|
||||
_T, _V, _W, do_not_use_directly::SmartStlAlloc<_T> >(0) {}
|
||||
};
|
||||
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| HipHop for PHP |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.01 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.php.net/license/3_01.txt |
|
||||
| If you did not receive a copy of the PHP license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
#ifndef incl_HPHP_RUNTIME_BASE_MEMORY_SMART_CONTAINERS_H_
|
||||
#define incl_HPHP_RUNTIME_BASE_MEMORY_SMART_CONTAINERS_H_
|
||||
|
||||
#include "hphp/runtime/base/memory/memory_manager.h"
|
||||
|
||||
namespace HPHP { namespace smart {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*
|
||||
* Defines a family of types similar to std:: collections and
|
||||
* pointers, except using the request-local allocator, which we
|
||||
* consider smart.
|
||||
*
|
||||
* Replace std:: with smart:: if you know the data is request-local.
|
||||
*
|
||||
* You can also use smart::Allocator as a model of folly's
|
||||
* SimpleAllocator where appropriate.
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// STL-style allocator for the smart allocator. (Unfortunately we
|
||||
// can't use allocator_traits yet.)
|
||||
|
||||
template <class T>
|
||||
struct Allocator {
|
||||
typedef T value_type;
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
template <class U>
|
||||
struct rebind {
|
||||
typedef Allocator<U> other;
|
||||
};
|
||||
|
||||
pointer address(reference value) const {
|
||||
return &value;
|
||||
}
|
||||
const_pointer address(const_reference value) const {
|
||||
return &value;
|
||||
}
|
||||
|
||||
Allocator() noexcept {}
|
||||
Allocator(const Allocator&) noexcept {}
|
||||
template<class U> Allocator(const Allocator<U>&) noexcept {}
|
||||
~Allocator() noexcept {}
|
||||
|
||||
size_type max_size() const {
|
||||
return std::numeric_limits<std::size_t>::max() / sizeof(T);
|
||||
}
|
||||
|
||||
pointer allocate(size_type num, const void* = 0) {
|
||||
pointer ret = (pointer)smart_malloc(num * sizeof(T));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<class... Args>
|
||||
void construct(pointer p, Args&&... args) {
|
||||
new ((void*)p) T(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void destroy(pointer p) {
|
||||
p->~T();
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type num) {
|
||||
smart_free(p);
|
||||
}
|
||||
|
||||
template<class U> bool operator==(const Allocator<U>&) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template<class U> bool operator!=(const Allocator<U>&) const {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Shorthand to create a std::unique_ptr to a smart-allocated object.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* auto ptr = smart::make_unique<Foo>(arg1, arg2);
|
||||
*
|
||||
* If you need to make a typedef to one, since we don't have type
|
||||
* aliases yet in our version of gcc you have to do:
|
||||
*
|
||||
* typedef smart::unique_ptr<T>::type type;
|
||||
*/
|
||||
|
||||
template<class T> struct unique_ptr
|
||||
: folly::AllocatorUniquePtr<T,Allocator<T>>
|
||||
{};
|
||||
|
||||
template<class T, class... Args>
|
||||
typename unique_ptr<T>::type make_unique(Args&&... args) {
|
||||
return folly::allocate_unique<T>(
|
||||
Allocator<T>(),
|
||||
std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
|
||||
static_assert(
|
||||
sizeof(unique_ptr<int>::type) == sizeof(std::unique_ptr<int>),
|
||||
"smart::unique_ptr pointer should not be larger than std::unique_ptr"
|
||||
);
|
||||
|
||||
/*
|
||||
* We are deriving from the std::collection classes to get
|
||||
* smart::collection classes that use smart allocation. To avoid the
|
||||
* various issues involved with deriving from value types, we want to
|
||||
* make sure that there are no references to the base classes here
|
||||
* other than the ones below. That way we know that a pointer to a
|
||||
* smart::collection can never decay to a pointer to a
|
||||
* std::collection.
|
||||
*
|
||||
* Derivation from value types is generally bad. We also add no
|
||||
* functionality to the derived class. Your code will not get past
|
||||
* code review if you try to do so.
|
||||
*
|
||||
* When we upgrade compilers we can change these to C++11 type
|
||||
* aliases.
|
||||
*/
|
||||
|
||||
template <class Key, class T, class Compare = std::less<Key>>
|
||||
class map : public std::map<
|
||||
Key, T, Compare,
|
||||
Allocator<std::pair<const Key,T>>
|
||||
> {};
|
||||
|
||||
template <class T>
|
||||
class deque : public std::deque<T,Allocator<T>> {};
|
||||
|
||||
template <class T>
|
||||
class vector : public std::vector<T,Allocator<T>> {
|
||||
typedef std::vector<T,Allocator<T>> Base;
|
||||
public:
|
||||
template <class... A>
|
||||
explicit vector(A &&... args) : Base(std::forward<A>(args)...) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class list : public std::list<T,Allocator<T>> {};
|
||||
|
||||
template <class T>
|
||||
class queue : public std::queue<T, deque<T> > {};
|
||||
|
||||
template <class T,
|
||||
class U,
|
||||
class V = hphp_hash<T>,
|
||||
class W = std::equal_to<T>>
|
||||
struct hash_map : std::tr1::unordered_map<
|
||||
T, U, V, W,
|
||||
Allocator<std::pair<T,U>>
|
||||
> {
|
||||
hash_map()
|
||||
: std::tr1::unordered_map<
|
||||
T, U, V, W,
|
||||
Allocator<std::pair<T,U>>
|
||||
>(0)
|
||||
{}
|
||||
};
|
||||
|
||||
template <class T,
|
||||
class V = hphp_hash<T>,
|
||||
class W = std::equal_to<T>>
|
||||
struct hash_set : std::tr1::unordered_set<T,V,W,Allocator<T> > {
|
||||
hash_set()
|
||||
: std::tr1::unordered_set<T,V,W,Allocator<T>>(0)
|
||||
{}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "hphp/runtime/base/types.h"
|
||||
#include "hphp/runtime/base/util/string_buffer.h"
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/vm/class.h"
|
||||
#include "hphp/runtime/vm/unit.h"
|
||||
|
||||
@@ -107,6 +108,7 @@ public:
|
||||
void setResourceInfo(CStrRef rsrcName, int rsrcId);
|
||||
void getResourceInfo(String &rsrcName, int &rsrcId);
|
||||
Type getType() const { return m_type; }
|
||||
|
||||
private:
|
||||
typedef smart::hash_map<void*, int, pointer_hash<void> > SmartPtrCtrMap;
|
||||
Type m_type;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define incl_HPHP_VARIABLE_UNSERIALIZER_H_
|
||||
|
||||
#include "hphp/runtime/base/types.h"
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
|
||||
namespace HPHP {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
#include "hphp/runtime/ext/asio/asio_context.h"
|
||||
|
||||
#include "hphp/runtime/ext/ext_asio.h"
|
||||
#include "hphp/runtime/ext/asio/asio_context.h"
|
||||
#include "hphp/runtime/ext/asio/asio_session.h"
|
||||
#include "hphp/system/lib/systemlib.h"
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include "hphp/runtime/base/base_includes.h"
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
|
||||
namespace HPHP {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/ext/ext_asio.h"
|
||||
#include "hphp/runtime/ext/asio/asio_context.h"
|
||||
#include "hphp/system/lib/systemlib.h"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#ifndef incl_HPHP_VM_BLOCK_H_
|
||||
#define incl_HPHP_VM_BLOCK_H_
|
||||
|
||||
#include "hphp/runtime/base/memory/memory_manager.h"
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/vm/jit/ir.h"
|
||||
#include "hphp/runtime/vm/jit/edge.h"
|
||||
#include "hphp/runtime/vm/jit/irinstruction.h"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
|
||||
#include "hphp/runtime/base/memory/memory_manager.h"
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/vm/jit/block.h"
|
||||
#include "hphp/runtime/vm/jit/trace.h"
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#ifndef incl_HPHP_JIT_LAYOUT_H_
|
||||
#define incl_HPHP_JIT_LAYOUT_H_
|
||||
|
||||
#include "hphp/runtime/base/memory/memory_manager.h"
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/vm/jit/ir.h"
|
||||
#include "hphp/runtime/vm/jit/block.h"
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
#include "hphp/runtime/vm/jit/linearscan.h"
|
||||
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/vm/jit/irfactory.h"
|
||||
#include "hphp/runtime/vm/jit/nativecalls.h"
|
||||
#include "hphp/runtime/vm/jit/print.h"
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
| license@php.net so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "hphp/runtime/vm/jit/print.h"
|
||||
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/vm/jit/ir.h"
|
||||
#include "hphp/runtime/vm/jit/linearscan.h"
|
||||
#include "hphp/runtime/vm/jit/codegen.h"
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/base/type_conversions.h"
|
||||
#include "hphp/runtime/vm/jit/tracebuilder.h"
|
||||
#include "hphp/runtime/vm/runtime.h"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#ifndef incl_HPHP_HHVM_HHIR_SIMPLIFIER_H_
|
||||
#define incl_HPHP_HHVM_HHIR_SIMPLIFIER_H_
|
||||
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/vm/jit/cse.h"
|
||||
#include "hphp/runtime/vm/jit/ir.h"
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "hphp/runtime/base/memory/memory_manager.h"
|
||||
#include "hphp/runtime/base/memory/smart_containers.h"
|
||||
#include "hphp/runtime/vm/jit/irfactory.h"
|
||||
|
||||
namespace HPHP { namespace JIT {
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário