Skip to content

Commit bd3919a

Browse files
committed
[libc++] Add ABI flag to make __tree nodes more compact
1 parent f1fc048 commit bd3919a

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

libcxx/include/__configuration/abi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@
116116
// This setting disables the addition of such artificial padding, leading to a more optimal
117117
// representation for several types.
118118
# define _LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING
119+
# define _LIBCPP_ABI_TREE_POINTER_INT_PAIR
119120
#elif _LIBCPP_ABI_VERSION == 1
120121
# if !(defined(_LIBCPP_OBJECT_FORMAT_COFF) || defined(_LIBCPP_OBJECT_FORMAT_XCOFF))
121122
// Enable compiling copies of now inline methods into the dylib to support
@@ -135,6 +136,8 @@
135136
# endif
136137
#endif
137138

139+
#define _LIBCPP_ABI_TREE_POINTER_INT_PAIR
140+
138141
// We had some bugs where we use [[no_unique_address]] together with construct_at,
139142
// which causes UB as the call on construct_at could write to overlapping subobjects
140143
//

libcxx/include/__tree

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include <__utility/forward.h>
4141
#include <__utility/move.h>
4242
#include <__utility/pair.h>
43+
#include <__utility/pointer_int_pair.h>
4344
#include <__utility/swap.h>
4445
#include <limits>
4546

@@ -61,7 +62,7 @@ class __tree_const_iterator;
6162

6263
template <class _Pointer>
6364
class __tree_end_node;
64-
template <class _VoidPtr>
65+
template <class _VoidPtr, class = void>
6566
class __tree_node_base;
6667
template <class _Tp, class _VoidPtr>
6768
class __tree_node;
@@ -626,7 +627,7 @@ public:
626627
_LIBCPP_HIDE_FROM_ABI __tree_end_node() _NOEXCEPT : __left_() {}
627628
};
628629

629-
template <class _VoidPtr>
630+
template <class _VoidPtr, class>
630631
class _LIBCPP_STANDALONE_DEBUG __tree_node_base : public __tree_node_base_types<_VoidPtr>::__end_node_type {
631632
typedef __tree_node_base_types<_VoidPtr> _NodeBaseTypes;
632633

@@ -654,6 +655,48 @@ public:
654655
__tree_node_base& operator=(__tree_node_base const&) = delete;
655656
};
656657

658+
#ifdef _LIBCPP_ABI_TREE_POINTER_INT_PAIR
659+
template <class _VoidPtr>
660+
class __tree_node_base<
661+
_VoidPtr,
662+
__enable_if_t<is_pointer<typename __tree_node_base_types<_VoidPtr>::__node_base_pointer>::value> >
663+
: public __tree_node_base_types<_VoidPtr>::__end_node_type {
664+
using _NodeBaseTypes = __tree_node_base_types<_VoidPtr>;
665+
666+
public:
667+
using pointer = typename _NodeBaseTypes::__node_base_pointer;
668+
using __parent_pointer = typename _NodeBaseTypes::__parent_pointer;
669+
670+
pointer __right_;
671+
672+
private:
673+
using __pair_t = __pointer_int_pair<__parent_pointer, bool, __integer_width(1)>;
674+
675+
__pair_t __parent_and_color_;
676+
677+
public:
678+
_LIBCPP_HIDE_FROM_ABI pointer __parent_unsafe() const {
679+
return static_cast<pointer>(__parent_and_color_.__get_ptr());
680+
}
681+
682+
_LIBCPP_HIDE_FROM_ABI void __set_parent(pointer __ptr) { __set_parent(static_cast<__parent_pointer>(__ptr)); }
683+
684+
_LIBCPP_HIDE_FROM_ABI void __set_parent(__parent_pointer __ptr) {
685+
__parent_and_color_ = __pair_t(__ptr, __parent_and_color_.__get_value());
686+
}
687+
688+
_LIBCPP_HIDE_FROM_ABI __parent_pointer __get_parent() const { return __parent_and_color_.__get_ptr(); }
689+
_LIBCPP_HIDE_FROM_ABI __tree_color __get_color() const {
690+
return static_cast<__tree_color>(__parent_and_color_.__get_value());
691+
}
692+
_LIBCPP_HIDE_FROM_ABI void __set_color(__tree_color __color) {
693+
__parent_and_color_ = __pair_t(__parent_and_color_.__get_ptr(), __color == __tree_color::__black);
694+
}
695+
};
696+
#endif // _LIBCPP_ABI_TREE_POINTER_INT_PAIR
697+
698+
static_assert(sizeof(__tree_node_base<void*>) == 24);
699+
657700
template <class _Tp, class _VoidPtr>
658701
class _LIBCPP_STANDALONE_DEBUG __tree_node : public __tree_node_base<_VoidPtr> {
659702
public:

0 commit comments

Comments
 (0)