Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(439)

Side by Side Diff: Source/core/rendering/RenderArena.cpp

Issue 16896019: Replace RenderArena with PartitionAlloc. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2003 Apple Computer, Inc.
3 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
4 *
5 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US A
20 *
21 * Alternatively, the contents of this file may be used under the terms
22 * of either the Mozilla Public License Version 1.1, found at
23 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
24 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
25 * (the "GPL"), in which case the provisions of the MPL or the GPL are
26 * applicable instead of those above. If you wish to allow use of your
27 * version of this file only under the terms of one of those two
28 * licenses (the MPL or the GPL) and not to allow others to use your
29 * version of this file under the LGPL, indicate your decision by
30 * deletingthe provisions above and replace them with the notice and
31 * other provisions required by the MPL or the GPL, as the case may be.
32 * If you do not delete the provisions above, a recipient may use your
33 * version of this file under any of the LGPL, the MPL or the GPL.
34 */
35
36 #include "config.h"
37 #include "core/rendering/RenderArena.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <limits>
42 #include <wtf/Assertions.h>
43 #include <wtf/CryptographicallyRandomNumber.h>
44
45 #define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
46
47 #ifdef NDEBUG
48 static void* MaskPtr(void* p, uintptr_t mask)
49 {
50 return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) ^ mask);
51 }
52 #endif
53
54 namespace WebCore {
55
56 #ifndef NDEBUG
57
58 const int signature = 0xDBA00AEA;
59 const int signatureDead = 0xDBA00AED;
60
61 typedef struct {
62 RenderArena* arena;
63 size_t size;
64 int signature;
65 } RenderArenaDebugHeader;
66
67 static const size_t debugHeaderSize = ARENA_ALIGN(sizeof(RenderArenaDebugHeader) );
68
69 #endif
70
71 RenderArena::RenderArena(unsigned arenaSize)
72 : m_totalSize(0)
73 , m_totalAllocated(0)
74 {
75 ASSERT(arenaSize > sizeof(Arena) + ARENA_ALIGN_MASK);
76 // The underlying Arena class allocates some metadata on top of our
77 // requested size. Factor this in so that we can get perfect power-of-two
78 // allocation sizes passed to the underlying malloc() call.
79 arenaSize -= (sizeof(Arena) + ARENA_ALIGN_MASK);
80 // Initialize the arena pool
81 INIT_ARENA_POOL(&m_pool, "RenderArena", arenaSize);
82
83 // Zero out the recyclers array
84 memset(m_recyclers, 0, sizeof(m_recyclers));
85
86 // Mask freelist pointers to detect corruption and stop freelist spraying.
87 // We use an arbitray function and rely on ASLR to randomize it.
88 // The first value in RenderObject (or any class) is a vtable pointer, which
89 // always overlaps with the next pointer. This change guarantees that the
90 // masked vtable/next pointer will never point to valid memory. So, we
91 // should immediately crash on the first invalid vtable access for a stale
92 // RenderObject pointer.
93 // See http://download.crowdstrike.com/papers/hes-exploiting-a-coalmine.pdf.
94 WTF::cryptographicallyRandomValues(&m_mask, sizeof(m_mask));
95 m_mask |= (static_cast<uintptr_t>(3) << (std::numeric_limits<uintptr_t>::dig its - 2)) | 1;
96 }
97
98 RenderArena::~RenderArena()
99 {
100 FinishArenaPool(&m_pool);
101 }
102
103 void* RenderArena::allocate(size_t size)
104 {
105 ASSERT(size <= gMaxRecycledSize - 32);
106 m_totalSize += size;
107
108 #ifdef ADDRESS_SANITIZER
109 return ::malloc(size);
110 #elif !defined(NDEBUG)
111 // Use standard malloc so that memory debugging tools work.
112 ASSERT(this);
113 void* block = ::malloc(debugHeaderSize + size);
114 RenderArenaDebugHeader* header = static_cast<RenderArenaDebugHeader*>(block) ;
115 header->arena = this;
116 header->size = size;
117 header->signature = signature;
118 return static_cast<char*>(block) + debugHeaderSize;
119 #else
120 // Ensure we have correct alignment for pointers. Important for Tru64
121 size = ROUNDUP(size, sizeof(void*));
122
123 const size_t index = size >> kRecyclerShift;
124
125 void* result = m_recyclers[index];
126 if (result) {
127 // Need to move to the next object
128 void* next = MaskPtr(*((void**)result), m_mask);
129 m_recyclers[index] = next;
130 }
131
132 if (!result) {
133 // Allocate a new chunk from the arena
134 unsigned bytesAllocated = 0;
135 ARENA_ALLOCATE(result, &m_pool, size, &bytesAllocated);
136 m_totalAllocated += bytesAllocated;
137 }
138
139 return result;
140 #endif
141 }
142
143 void RenderArena::free(size_t size, void* ptr)
144 {
145 ASSERT(size <= gMaxRecycledSize - 32);
146 m_totalSize -= size;
147
148 #ifdef ADDRESS_SANITIZER
149 ::free(ptr);
150 #elif !defined(NDEBUG)
151 // Use standard free so that memory debugging tools work.
152 void* block = static_cast<char*>(ptr) - debugHeaderSize;
153 RenderArenaDebugHeader* header = static_cast<RenderArenaDebugHeader*>(block) ;
154 ASSERT(header->signature == signature);
155 ASSERT_UNUSED(size, header->size == size);
156 ASSERT(header->arena == this);
157 header->signature = signatureDead;
158 ::free(block);
159 #else
160 // Ensure we have correct alignment for pointers. Important for Tru64
161 size = ROUNDUP(size, sizeof(void*));
162
163 const size_t index = size >> kRecyclerShift;
164 void* currentTop = m_recyclers[index];
165 m_recyclers[index] = ptr;
166 *((void**)ptr) = MaskPtr(currentTop, m_mask);
167 #endif
168 }
169
170 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698