sassc 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +5 -0
- data/ext/libsass/VERSION +1 -1
- data/ext/libsass/include/sass/context.h +3 -0
- data/ext/libsass/src/MurmurHash2.hpp +91 -0
- data/ext/libsass/src/ast.cpp +117 -117
- data/ext/libsass/src/ast.hpp +160 -162
- data/ext/libsass/src/ast_def_macros.hpp +10 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +2 -2
- data/ext/libsass/src/ast_fwd_decl.hpp +61 -52
- data/ext/libsass/src/ast_helpers.hpp +5 -5
- data/ext/libsass/src/ast_sel_cmp.cpp +18 -18
- data/ext/libsass/src/ast_sel_super.cpp +52 -52
- data/ext/libsass/src/ast_sel_unify.cpp +16 -16
- data/ext/libsass/src/ast_sel_weave.cpp +62 -62
- data/ext/libsass/src/ast_selectors.cpp +87 -77
- data/ext/libsass/src/ast_selectors.hpp +72 -62
- data/ext/libsass/src/ast_supports.cpp +35 -35
- data/ext/libsass/src/ast_supports.hpp +29 -29
- data/ext/libsass/src/ast_values.cpp +58 -58
- data/ext/libsass/src/ast_values.hpp +75 -75
- data/ext/libsass/src/backtrace.cpp +9 -9
- data/ext/libsass/src/backtrace.hpp +5 -5
- data/ext/libsass/src/base64vlq.cpp +2 -2
- data/ext/libsass/src/base64vlq.hpp +1 -1
- data/ext/libsass/src/bind.cpp +17 -17
- data/ext/libsass/src/bind.hpp +1 -1
- data/ext/libsass/src/c2ast.cpp +3 -3
- data/ext/libsass/src/c2ast.hpp +1 -1
- data/ext/libsass/src/check_nesting.cpp +36 -36
- data/ext/libsass/src/check_nesting.hpp +2 -2
- data/ext/libsass/src/color_maps.cpp +5 -5
- data/ext/libsass/src/color_maps.hpp +1 -1
- data/ext/libsass/src/context.cpp +63 -60
- data/ext/libsass/src/context.hpp +33 -33
- data/ext/libsass/src/cssize.cpp +30 -29
- data/ext/libsass/src/cssize.hpp +13 -13
- data/ext/libsass/src/dart_helpers.hpp +5 -5
- data/ext/libsass/src/debugger.hpp +127 -128
- data/ext/libsass/src/emitter.cpp +12 -12
- data/ext/libsass/src/emitter.hpp +10 -10
- data/ext/libsass/src/environment.cpp +27 -27
- data/ext/libsass/src/environment.hpp +24 -24
- data/ext/libsass/src/error_handling.cpp +42 -42
- data/ext/libsass/src/error_handling.hpp +38 -50
- data/ext/libsass/src/eval.cpp +138 -132
- data/ext/libsass/src/eval.hpp +17 -17
- data/ext/libsass/src/eval_selectors.cpp +3 -3
- data/ext/libsass/src/expand.cpp +70 -64
- data/ext/libsass/src/expand.hpp +12 -12
- data/ext/libsass/src/extender.cpp +55 -53
- data/ext/libsass/src/extender.hpp +14 -14
- data/ext/libsass/src/file.cpp +66 -58
- data/ext/libsass/src/file.hpp +23 -25
- data/ext/libsass/src/fn_colors.cpp +9 -9
- data/ext/libsass/src/fn_lists.cpp +18 -18
- data/ext/libsass/src/fn_maps.cpp +3 -3
- data/ext/libsass/src/fn_miscs.cpp +15 -15
- data/ext/libsass/src/fn_numbers.cpp +7 -7
- data/ext/libsass/src/fn_selectors.cpp +8 -8
- data/ext/libsass/src/fn_strings.cpp +34 -22
- data/ext/libsass/src/fn_utils.cpp +29 -26
- data/ext/libsass/src/fn_utils.hpp +10 -10
- data/ext/libsass/src/inspect.cpp +35 -34
- data/ext/libsass/src/inspect.hpp +21 -21
- data/ext/libsass/src/lexer.cpp +3 -1
- data/ext/libsass/src/listize.cpp +2 -2
- data/ext/libsass/src/mapping.hpp +1 -0
- data/ext/libsass/src/memory.hpp +12 -0
- data/ext/libsass/src/memory/allocator.cpp +48 -0
- data/ext/libsass/src/memory/allocator.hpp +138 -0
- data/ext/libsass/src/memory/config.hpp +20 -0
- data/ext/libsass/src/memory/memory_pool.hpp +186 -0
- data/ext/libsass/src/memory/{SharedPtr.cpp → shared_ptr.cpp} +2 -2
- data/ext/libsass/src/memory/{SharedPtr.hpp → shared_ptr.hpp} +18 -6
- data/ext/libsass/src/operation.hpp +44 -44
- data/ext/libsass/src/operators.cpp +18 -18
- data/ext/libsass/src/operators.hpp +11 -11
- data/ext/libsass/src/ordered_map.hpp +18 -18
- data/ext/libsass/src/output.cpp +16 -16
- data/ext/libsass/src/output.hpp +5 -5
- data/ext/libsass/src/parser.cpp +327 -345
- data/ext/libsass/src/parser.hpp +77 -87
- data/ext/libsass/src/parser_selectors.cpp +6 -6
- data/ext/libsass/src/permutate.hpp +39 -15
- data/ext/libsass/src/plugins.cpp +7 -7
- data/ext/libsass/src/plugins.hpp +8 -8
- data/ext/libsass/src/position.cpp +7 -26
- data/ext/libsass/src/position.hpp +44 -21
- data/ext/libsass/src/remove_placeholders.cpp +4 -4
- data/ext/libsass/src/remove_placeholders.hpp +3 -3
- data/ext/libsass/src/sass.cpp +16 -15
- data/ext/libsass/src/sass.hpp +9 -5
- data/ext/libsass/src/sass_context.cpp +52 -34
- data/ext/libsass/src/sass_values.cpp +8 -10
- data/ext/libsass/src/settings.hpp +19 -0
- data/ext/libsass/src/source.cpp +69 -0
- data/ext/libsass/src/source.hpp +95 -0
- data/ext/libsass/src/source_data.hpp +32 -0
- data/ext/libsass/src/source_map.cpp +22 -18
- data/ext/libsass/src/source_map.hpp +12 -9
- data/ext/libsass/src/units.cpp +19 -19
- data/ext/libsass/src/units.hpp +8 -8
- data/ext/libsass/src/utf8_string.cpp +9 -10
- data/ext/libsass/src/utf8_string.hpp +7 -6
- data/ext/libsass/src/util.cpp +38 -38
- data/ext/libsass/src/util.hpp +18 -18
- data/ext/libsass/src/util_string.cpp +13 -13
- data/ext/libsass/src/util_string.hpp +9 -8
- data/ext/libsass/src/values.cpp +12 -12
- data/lib/sassc/native.rb +3 -5
- data/lib/sassc/version.rb +1 -1
- data/test/native_test.rb +4 -4
- metadata +14 -5
- data/lib/sassc/native/lib_c.rb +0 -21
data/ext/libsass/src/inspect.hpp
CHANGED
@@ -20,24 +20,24 @@ namespace Sass {
|
|
20
20
|
|
21
21
|
// statements
|
22
22
|
virtual void operator()(Block*);
|
23
|
-
virtual void operator()(
|
23
|
+
virtual void operator()(StyleRule*);
|
24
24
|
virtual void operator()(Bubble*);
|
25
|
-
virtual void operator()(
|
26
|
-
virtual void operator()(
|
27
|
-
virtual void operator()(
|
25
|
+
virtual void operator()(SupportsRule*);
|
26
|
+
virtual void operator()(AtRootRule*);
|
27
|
+
virtual void operator()(AtRule*);
|
28
28
|
virtual void operator()(Keyframe_Rule*);
|
29
29
|
virtual void operator()(Declaration*);
|
30
30
|
virtual void operator()(Assignment*);
|
31
31
|
virtual void operator()(Import*);
|
32
32
|
virtual void operator()(Import_Stub*);
|
33
|
-
virtual void operator()(
|
34
|
-
virtual void operator()(
|
35
|
-
virtual void operator()(
|
33
|
+
virtual void operator()(WarningRule*);
|
34
|
+
virtual void operator()(ErrorRule*);
|
35
|
+
virtual void operator()(DebugRule*);
|
36
36
|
virtual void operator()(Comment*);
|
37
37
|
virtual void operator()(If*);
|
38
|
-
virtual void operator()(
|
39
|
-
virtual void operator()(
|
40
|
-
virtual void operator()(
|
38
|
+
virtual void operator()(ForRule*);
|
39
|
+
virtual void operator()(EachRule*);
|
40
|
+
virtual void operator()(WhileRule*);
|
41
41
|
virtual void operator()(Return*);
|
42
42
|
virtual void operator()(ExtendRule*);
|
43
43
|
virtual void operator()(Definition*);
|
@@ -62,9 +62,9 @@ namespace Sass {
|
|
62
62
|
virtual void operator()(String_Quoted*);
|
63
63
|
virtual void operator()(Custom_Error*);
|
64
64
|
virtual void operator()(Custom_Warning*);
|
65
|
-
virtual void operator()(
|
66
|
-
virtual void operator()(
|
67
|
-
virtual void operator()(
|
65
|
+
virtual void operator()(SupportsOperation*);
|
66
|
+
virtual void operator()(SupportsNegation*);
|
67
|
+
virtual void operator()(SupportsDeclaration*);
|
68
68
|
virtual void operator()(Supports_Interpolation*);
|
69
69
|
virtual void operator()(MediaRule*);
|
70
70
|
virtual void operator()(CssMediaRule*);
|
@@ -81,19 +81,19 @@ namespace Sass {
|
|
81
81
|
virtual void operator()(Arguments*);
|
82
82
|
// selectors
|
83
83
|
virtual void operator()(Selector_Schema*);
|
84
|
-
virtual void operator()(
|
85
|
-
virtual void operator()(
|
86
|
-
virtual void operator()(
|
87
|
-
virtual void operator()(
|
88
|
-
virtual void operator()(
|
89
|
-
virtual void operator()(
|
84
|
+
virtual void operator()(PlaceholderSelector*);
|
85
|
+
virtual void operator()(TypeSelector*);
|
86
|
+
virtual void operator()(ClassSelector*);
|
87
|
+
virtual void operator()(IDSelector*);
|
88
|
+
virtual void operator()(AttributeSelector*);
|
89
|
+
virtual void operator()(PseudoSelector*);
|
90
90
|
virtual void operator()(SelectorComponent*);
|
91
91
|
virtual void operator()(SelectorCombinator*);
|
92
92
|
virtual void operator()(CompoundSelector*);
|
93
93
|
virtual void operator()(ComplexSelector*);
|
94
94
|
virtual void operator()(SelectorList*);
|
95
|
-
virtual
|
96
|
-
virtual
|
95
|
+
virtual sass::string lbracket(List*);
|
96
|
+
virtual sass::string rbracket(List*);
|
97
97
|
|
98
98
|
};
|
99
99
|
|
data/ext/libsass/src/lexer.cpp
CHANGED
@@ -93,7 +93,9 @@ namespace Sass {
|
|
93
93
|
const char* re_linebreak(const char* src)
|
94
94
|
{
|
95
95
|
// end of file or unix linefeed return here
|
96
|
-
if (*src == 0
|
96
|
+
if (*src == 0) return src;
|
97
|
+
// end of file or unix linefeed return here
|
98
|
+
if (*src == '\n' || *src == '\f') return src + 1;
|
97
99
|
// a carriage return may optionally be followed by a linefeed
|
98
100
|
if (*src == '\r') return *(src + 1) == '\n' ? src + 2 : src + 1;
|
99
101
|
// no linefeed
|
data/ext/libsass/src/listize.cpp
CHANGED
@@ -36,7 +36,7 @@ namespace Sass {
|
|
36
36
|
|
37
37
|
Expression* Listize::operator()(CompoundSelector* sel)
|
38
38
|
{
|
39
|
-
|
39
|
+
sass::string str;
|
40
40
|
for (size_t i = 0, L = sel->length(); i < L; ++i) {
|
41
41
|
Expression* e = (*sel)[i]->perform(this);
|
42
42
|
if (e) str += e->to_string();
|
@@ -54,7 +54,7 @@ namespace Sass {
|
|
54
54
|
for (auto component : sel->elements()) {
|
55
55
|
if (CompoundSelectorObj compound = Cast<CompoundSelector>(component)) {
|
56
56
|
if (!compound->empty()) {
|
57
|
-
|
57
|
+
ExpressionObj hh = compound->perform(this);
|
58
58
|
if (hh) l->append(hh);
|
59
59
|
}
|
60
60
|
}
|
data/ext/libsass/src/mapping.hpp
CHANGED
@@ -0,0 +1,48 @@
|
|
1
|
+
#include "../sass.hpp"
|
2
|
+
#include "allocator.hpp"
|
3
|
+
#include "memory_pool.hpp"
|
4
|
+
|
5
|
+
#if defined (_MSC_VER) // Visual studio
|
6
|
+
#define thread_local __declspec( thread )
|
7
|
+
#elif defined (__GCC__) // GCC
|
8
|
+
#define thread_local __thread
|
9
|
+
#endif
|
10
|
+
|
11
|
+
namespace Sass {
|
12
|
+
|
13
|
+
#ifdef SASS_CUSTOM_ALLOCATOR
|
14
|
+
|
15
|
+
// Only use PODs for thread_local
|
16
|
+
// Objects get unpredictable init order
|
17
|
+
static thread_local MemoryPool* pool;
|
18
|
+
static thread_local size_t allocations;
|
19
|
+
|
20
|
+
void* allocateMem(size_t size)
|
21
|
+
{
|
22
|
+
if (pool == nullptr) {
|
23
|
+
pool = new MemoryPool();
|
24
|
+
}
|
25
|
+
allocations++;
|
26
|
+
return pool->allocate(size);
|
27
|
+
}
|
28
|
+
|
29
|
+
void deallocateMem(void* ptr, size_t size)
|
30
|
+
{
|
31
|
+
|
32
|
+
// It seems thread_local variable might be discharged!?
|
33
|
+
// But the destructors of e.g. static strings is still
|
34
|
+
// called, although their memory was discharged too.
|
35
|
+
// Fine with me as long as address sanitizer is happy.
|
36
|
+
if (pool == nullptr || allocations == 0) { return; }
|
37
|
+
|
38
|
+
pool->deallocate(ptr);
|
39
|
+
if (--allocations == 0) {
|
40
|
+
delete pool;
|
41
|
+
pool = nullptr;
|
42
|
+
}
|
43
|
+
|
44
|
+
}
|
45
|
+
|
46
|
+
#endif
|
47
|
+
|
48
|
+
}
|
@@ -0,0 +1,138 @@
|
|
1
|
+
#ifndef SASS_ALLOCATOR_H
|
2
|
+
#define SASS_ALLOCATOR_H
|
3
|
+
|
4
|
+
#include "config.hpp"
|
5
|
+
#include "../settings.hpp"
|
6
|
+
#include "../MurmurHash2.hpp"
|
7
|
+
|
8
|
+
#include <vector>
|
9
|
+
#include <limits>
|
10
|
+
#include <iostream>
|
11
|
+
#include <algorithm>
|
12
|
+
#include <functional>
|
13
|
+
|
14
|
+
namespace Sass {
|
15
|
+
|
16
|
+
#ifndef SASS_CUSTOM_ALLOCATOR
|
17
|
+
|
18
|
+
template <typename T> using Allocator = std::allocator<T>;
|
19
|
+
|
20
|
+
#else
|
21
|
+
|
22
|
+
void* allocateMem(size_t size);
|
23
|
+
|
24
|
+
void deallocateMem(void* ptr, size_t size = 1);
|
25
|
+
|
26
|
+
template<typename T>
|
27
|
+
class Allocator
|
28
|
+
{
|
29
|
+
public:
|
30
|
+
|
31
|
+
// Allocator traits
|
32
|
+
typedef T type;
|
33
|
+
typedef type value_type;
|
34
|
+
typedef value_type* pointer;
|
35
|
+
typedef value_type const* const_pointer;
|
36
|
+
typedef value_type& reference;
|
37
|
+
typedef value_type const& const_reference;
|
38
|
+
typedef std::size_t size_type;
|
39
|
+
typedef std::ptrdiff_t difference_type;
|
40
|
+
|
41
|
+
template<typename U>
|
42
|
+
struct rebind
|
43
|
+
{
|
44
|
+
typedef Allocator<U> other;
|
45
|
+
};
|
46
|
+
|
47
|
+
// Constructor
|
48
|
+
Allocator(void) {}
|
49
|
+
|
50
|
+
// Copy Constructor
|
51
|
+
template<typename U>
|
52
|
+
Allocator(Allocator<U> const&)
|
53
|
+
{}
|
54
|
+
|
55
|
+
// allocate but don't initialize count of elements of type T
|
56
|
+
pointer allocate(size_type count, const_pointer /* hint */ = 0)
|
57
|
+
{
|
58
|
+
return (pointer)(Sass::allocateMem(count * sizeof(T)));
|
59
|
+
}
|
60
|
+
|
61
|
+
// deallocate storage ptr of deleted elements
|
62
|
+
void deallocate(pointer ptr, size_type count)
|
63
|
+
{
|
64
|
+
Sass::deallocateMem(ptr, count);
|
65
|
+
}
|
66
|
+
|
67
|
+
// return maximum number of elements that can be allocated
|
68
|
+
size_type max_size() const throw()
|
69
|
+
{
|
70
|
+
return std::numeric_limits<size_type>::max() / sizeof(T);
|
71
|
+
}
|
72
|
+
|
73
|
+
// Address of object
|
74
|
+
type* address(type& obj) const { return &obj; }
|
75
|
+
type const* address(type const& obj) const { return &obj; }
|
76
|
+
|
77
|
+
// Construct object
|
78
|
+
void construct(type* ptr, type const& ref) const
|
79
|
+
{
|
80
|
+
// In-place copy construct
|
81
|
+
new(ptr) type(ref);
|
82
|
+
}
|
83
|
+
|
84
|
+
// Destroy object
|
85
|
+
void destroy(type* ptr) const
|
86
|
+
{
|
87
|
+
// Call destructor
|
88
|
+
ptr->~type();
|
89
|
+
}
|
90
|
+
|
91
|
+
};
|
92
|
+
|
93
|
+
template<typename T, typename U>
|
94
|
+
bool operator==(Allocator<T> const& left,
|
95
|
+
Allocator<U> const& right)
|
96
|
+
{
|
97
|
+
return true;
|
98
|
+
}
|
99
|
+
|
100
|
+
template<typename T, typename U>
|
101
|
+
bool operator!=(Allocator<T> const& left,
|
102
|
+
Allocator<U> const& right)
|
103
|
+
{
|
104
|
+
return !(left == right);
|
105
|
+
}
|
106
|
+
|
107
|
+
#endif
|
108
|
+
|
109
|
+
namespace sass {
|
110
|
+
template <typename T> using vector = std::vector<T, Sass::Allocator<T>>;
|
111
|
+
using string = std::basic_string<char, std::char_traits<char>, Sass::Allocator<char>>;
|
112
|
+
using sstream = std::basic_stringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
|
113
|
+
using ostream = std::basic_ostringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
|
114
|
+
using istream = std::basic_istringstream<char, std::char_traits<char>, Sass::Allocator<char>>;
|
115
|
+
}
|
116
|
+
|
117
|
+
}
|
118
|
+
|
119
|
+
#ifdef SASS_CUSTOM_ALLOCATOR
|
120
|
+
|
121
|
+
namespace std {
|
122
|
+
// Only GCC seems to need this specialization!?
|
123
|
+
template <> struct hash<Sass::sass::string> {
|
124
|
+
public:
|
125
|
+
inline size_t operator()(
|
126
|
+
const Sass::sass::string& name) const
|
127
|
+
{
|
128
|
+
return MurmurHash2(
|
129
|
+
(void*)name.c_str(),
|
130
|
+
(int)name.size(),
|
131
|
+
0x73617373);
|
132
|
+
}
|
133
|
+
};
|
134
|
+
}
|
135
|
+
|
136
|
+
#endif
|
137
|
+
|
138
|
+
#endif
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#ifndef SASS_MEMORY_CONFIG_H
|
2
|
+
#define SASS_MEMORY_CONFIG_H
|
3
|
+
|
4
|
+
// Define memory alignment requirements
|
5
|
+
#define SASS_MEM_ALIGN sizeof(unsigned int)
|
6
|
+
|
7
|
+
// Minimal alignment for memory fragments. Must be a multiple
|
8
|
+
// of `SASS_MEM_ALIGN` and should not be too big (maybe 1 or 2)
|
9
|
+
#define SassAllocatorHeadSize sizeof(unsigned int)
|
10
|
+
|
11
|
+
// The number of bytes we use for our book-keeping before every
|
12
|
+
// memory fragment. Needed to know to which bucket we belongs on
|
13
|
+
// deallocations, or if it should go directly to the `free` call.
|
14
|
+
#define SassAllocatorBookSize sizeof(unsigned int)
|
15
|
+
|
16
|
+
// Bytes reserve for book-keeping on the arenas
|
17
|
+
// Currently unused and for later optimization
|
18
|
+
#define SassAllocatorArenaHeadSize 0
|
19
|
+
|
20
|
+
#endif
|
@@ -0,0 +1,186 @@
|
|
1
|
+
#ifndef SASS_MEMORY_POOL_H
|
2
|
+
#define SASS_MEMORY_POOL_H
|
3
|
+
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <iostream>
|
6
|
+
#include <algorithm>
|
7
|
+
#include <climits>
|
8
|
+
#include <vector>
|
9
|
+
|
10
|
+
namespace Sass {
|
11
|
+
|
12
|
+
// SIMPLE MEMORY-POOL ALLOCATOR WITH FREE-LIST ON TOP
|
13
|
+
|
14
|
+
// This is a memory pool allocator with a free list on top.
|
15
|
+
// We only allocate memory arenas from the system in specific
|
16
|
+
// sizes (`SassAllocatorArenaSize`). Users claim memory slices
|
17
|
+
// of certain sizes from the pool. If the allocation is too big
|
18
|
+
// to fit into our buckets, we use regular malloc/free instead.
|
19
|
+
|
20
|
+
// When the systems starts, we allocate the first arena and then
|
21
|
+
// start to give out addresses to memory slices. During that
|
22
|
+
// we steadily increase `offset` until the current arena is full.
|
23
|
+
// Once that happens we allocate a new arena and continue.
|
24
|
+
// https://en.wikipedia.org/wiki/Memory_pool
|
25
|
+
|
26
|
+
// Fragments that get deallocated are not really freed, we put
|
27
|
+
// them on our free-list. For every bucket we have a pointer to
|
28
|
+
// the first item for reuse. That item itself holds a pointer to
|
29
|
+
// the previously free item (regular free-list implementation).
|
30
|
+
// https://en.wikipedia.org/wiki/Free_list
|
31
|
+
|
32
|
+
// On allocation calls we first check if there is any suitable
|
33
|
+
// item on the free-list. If there is we pop it from the stack
|
34
|
+
// and return it to the caller. Otherwise we have to take out
|
35
|
+
// a new slice from the current `arena` and increase `offset`.
|
36
|
+
|
37
|
+
// Note that this is not thread safe. This is on purpose as we
|
38
|
+
// want to use the memory pool in a thread local usage. In order
|
39
|
+
// to get this thread safe you need to only allocate one pool
|
40
|
+
// per thread. This can be achieved by using thread local PODs.
|
41
|
+
// Simply create a pool on the first allocation and dispose
|
42
|
+
// it once all allocations have been returned. E.g. by using:
|
43
|
+
// static thread_local size_t allocations;
|
44
|
+
// static thread_local MemoryPool* pool;
|
45
|
+
|
46
|
+
class MemoryPool {
|
47
|
+
|
48
|
+
// Current arena we fill up
|
49
|
+
char* arena;
|
50
|
+
|
51
|
+
// Position into the arena
|
52
|
+
size_t offset = std::string::npos;
|
53
|
+
|
54
|
+
// A list of full arenas
|
55
|
+
std::vector<void*> arenas;
|
56
|
+
|
57
|
+
// One pointer for every bucket (zero init)
|
58
|
+
#ifdef _MSC_VER
|
59
|
+
#pragma warning (suppress:4351)
|
60
|
+
#endif
|
61
|
+
void* freeList[SassAllocatorBuckets]{};
|
62
|
+
|
63
|
+
// Increase the address until it sits on a
|
64
|
+
// memory aligned address (maybe use `aligned`).
|
65
|
+
inline static size_t alignMemAddr(size_t addr) {
|
66
|
+
return (addr + SASS_MEM_ALIGN - 1) & ~(SASS_MEM_ALIGN - 1);
|
67
|
+
}
|
68
|
+
|
69
|
+
public:
|
70
|
+
|
71
|
+
// Default ctor
|
72
|
+
MemoryPool() :
|
73
|
+
// Wait for first allocation
|
74
|
+
arena(nullptr),
|
75
|
+
// Set to maximum value in order to
|
76
|
+
// make an allocation on the first run
|
77
|
+
offset(std::string::npos)
|
78
|
+
{
|
79
|
+
}
|
80
|
+
|
81
|
+
// Destructor
|
82
|
+
~MemoryPool() {
|
83
|
+
// Delete full arenas
|
84
|
+
for (auto area : arenas) {
|
85
|
+
free(area);
|
86
|
+
}
|
87
|
+
// Delete current arena
|
88
|
+
free(arena);
|
89
|
+
|
90
|
+
}
|
91
|
+
|
92
|
+
// Allocate a slice of the memory pool
|
93
|
+
void* allocate(size_t size)
|
94
|
+
{
|
95
|
+
|
96
|
+
// Increase size so its memory is aligned
|
97
|
+
size = alignMemAddr(
|
98
|
+
// Make sure we have enough space for us to
|
99
|
+
// create the pointer to the free list later
|
100
|
+
std::max(sizeof(void*), size)
|
101
|
+
// and the size needed for our book-keeping
|
102
|
+
+ SassAllocatorBookSize);
|
103
|
+
|
104
|
+
// Size must be multiple of alignment
|
105
|
+
// So we can derive bucket index from it
|
106
|
+
size_t bucket = size / SASS_MEM_ALIGN;
|
107
|
+
|
108
|
+
// Everything bigger is allocated via malloc
|
109
|
+
// Malloc is optimized for exactly this case
|
110
|
+
if (bucket >= SassAllocatorBuckets) {
|
111
|
+
char* buffer = (char*)malloc(size);
|
112
|
+
if (buffer == nullptr) {
|
113
|
+
throw std::bad_alloc();
|
114
|
+
}
|
115
|
+
// Mark it for deallocation via free
|
116
|
+
((unsigned int*)buffer)[0] = UINT_MAX;
|
117
|
+
// Return pointer after our book-keeping space
|
118
|
+
return (void*)(buffer + SassAllocatorBookSize);
|
119
|
+
}
|
120
|
+
// Use custom allocator
|
121
|
+
else {
|
122
|
+
// Get item from free list
|
123
|
+
void*& free = freeList[bucket];
|
124
|
+
// Do we have a free item?
|
125
|
+
if (free != nullptr) {
|
126
|
+
// Copy pointer to return
|
127
|
+
void* ptr = free;
|
128
|
+
// Update free list pointer
|
129
|
+
free = ((void**)ptr)[0];
|
130
|
+
// Return popped item
|
131
|
+
return ptr;
|
132
|
+
}
|
133
|
+
}
|
134
|
+
|
135
|
+
// Make sure we have enough space in the arena
|
136
|
+
if (!arena || offset > SassAllocatorArenaSize - size) {
|
137
|
+
if (arena) arenas.emplace_back(arena);
|
138
|
+
arena = (char*)malloc(SassAllocatorArenaSize);
|
139
|
+
if (arena == nullptr) throw std::bad_alloc();
|
140
|
+
offset = SassAllocatorArenaHeadSize;
|
141
|
+
}
|
142
|
+
|
143
|
+
// Get pointer into the arena
|
144
|
+
char* buffer = arena + offset;
|
145
|
+
// Consume object size
|
146
|
+
offset += size;
|
147
|
+
|
148
|
+
// Set the bucket index for this slice
|
149
|
+
((unsigned int*)buffer)[0] = (unsigned int)bucket;
|
150
|
+
|
151
|
+
// Return pointer after our book-keeping space
|
152
|
+
return (void*)(buffer + SassAllocatorBookSize);
|
153
|
+
|
154
|
+
}
|
155
|
+
// EO allocate
|
156
|
+
|
157
|
+
void deallocate(void* ptr)
|
158
|
+
{
|
159
|
+
|
160
|
+
// Rewind buffer from pointer
|
161
|
+
char* buffer = (char*)ptr -
|
162
|
+
SassAllocatorBookSize;
|
163
|
+
|
164
|
+
// Get the bucket index stored in the header
|
165
|
+
unsigned int bucket = ((unsigned int*)buffer)[0];
|
166
|
+
|
167
|
+
// Check allocation method
|
168
|
+
if (bucket != UINT_MAX) {
|
169
|
+
// Let memory point to previous item in free list
|
170
|
+
((void**)ptr)[0] = freeList[bucket];
|
171
|
+
// Free list now points to our memory
|
172
|
+
freeList[bucket] = (void*)ptr;
|
173
|
+
}
|
174
|
+
else {
|
175
|
+
// Release memory
|
176
|
+
free(buffer);
|
177
|
+
}
|
178
|
+
|
179
|
+
}
|
180
|
+
// EO deallocate
|
181
|
+
|
182
|
+
};
|
183
|
+
|
184
|
+
}
|
185
|
+
|
186
|
+
#endif
|