Changeset 105646 in webkit
- Timestamp:
- Jan 23, 2012 3:30:57 PM (12 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r105639 r105646 1 2012-01-23 Gavin Barraclough <barraclough@apple.com> 2 3 https://bugs.webkit.org/show_bug.cgi?id=76855 4 Implement a JIT-code aware sampling profiler for JSC 5 6 Reviewed by Geoff Garen. 7 8 Step 2: generalize RedBlackTree. The profiler is going to want tio use 9 a RedBlackTree, allow this class to work with subclasses of 10 RedBlackTree::Node, Node should not need to know the names of the m_key 11 and m_value fields (the subclass can provide a key() accessor), and 12 RedBlackTree does not need to know anything about ValueType. 13 14 * JavaScriptCore.exp: 15 * wtf/MetaAllocator.cpp: 16 (WTF::MetaAllocator::findAndRemoveFreeSpace): 17 (WTF::MetaAllocator::debugFreeSpaceSize): 18 (WTF::MetaAllocator::addFreeSpace): 19 * wtf/MetaAllocator.h: 20 (WTF::MetaAllocator::FreeSpaceNode::FreeSpaceNode): 21 (WTF::MetaAllocator::FreeSpaceNode::key): 22 * wtf/MetaAllocatorHandle.h: 23 (WTF::MetaAllocatorHandle::key): 24 * wtf/RedBlackTree.h: 25 (WTF::RedBlackTree::Node::successor): 26 (WTF::RedBlackTree::Node::predecessor): 27 (WTF::RedBlackTree::Node::parent): 28 (WTF::RedBlackTree::Node::setParent): 29 (WTF::RedBlackTree::Node::left): 30 (WTF::RedBlackTree::Node::setLeft): 31 (WTF::RedBlackTree::Node::right): 32 (WTF::RedBlackTree::Node::setRight): 33 (WTF::RedBlackTree::insert): 34 (WTF::RedBlackTree::remove): 35 (WTF::RedBlackTree::findExact): 36 (WTF::RedBlackTree::findLeastGreaterThanOrEqual): 37 (WTF::RedBlackTree::findGreatestLessThanOrEqual): 38 (WTF::RedBlackTree::first): 39 (WTF::RedBlackTree::last): 40 (WTF::RedBlackTree::size): 41 (WTF::RedBlackTree::treeMinimum): 42 (WTF::RedBlackTree::treeMaximum): 43 (WTF::RedBlackTree::treeInsert): 44 (WTF::RedBlackTree::leftRotate): 45 (WTF::RedBlackTree::rightRotate): 46 (WTF::RedBlackTree::removeFixup): 47 1 48 2012-01-23 Andy Estes <aestes@apple.com> 2 49 -
trunk/Source/JavaScriptCore/JavaScriptCore.exp
r105639 r105646 413 413 __ZN3WTF12randomNumberEv 414 414 __ZN3WTF13MetaAllocator17addFreshFreeSpaceEPvm 415 __ZN3WTF13MetaAllocator17freeFreeSpaceNodeEPNS_12RedBlackTreeImPvE4NodeE416 415 __ZN3WTF13MetaAllocator18debugFreeSpaceSizeEv 417 416 __ZN3WTF13MetaAllocator8allocateEm -
trunk/Source/JavaScriptCore/wtf/MetaAllocator.cpp
r103243 r105646 179 179 return 0; 180 180 181 ASSERT(node->m_ key>= sizeInBytes);181 ASSERT(node->m_sizeInBytes >= sizeInBytes); 182 182 183 183 m_freeSpaceSizeMap.remove(node); … … 185 185 void* result; 186 186 187 if (node->m_ key== sizeInBytes) {187 if (node->m_sizeInBytes == sizeInBytes) { 188 188 // Easy case: perfect fit, so just remove the node entirely. 189 result = node->m_ value;190 191 m_freeSpaceStartAddressMap.remove(node->m_ value);192 m_freeSpaceEndAddressMap.remove(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(node->m_ value) + node->m_key));189 result = node->m_start; 190 191 m_freeSpaceStartAddressMap.remove(node->m_start); 192 m_freeSpaceEndAddressMap.remove(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(node->m_start) + node->m_sizeInBytes)); 193 193 freeFreeSpaceNode(node); 194 194 } else { … … 200 200 // fewer committed pages and fewer failures in general. 201 201 202 uintptr_t firstPage = reinterpret_cast<uintptr_t>(node->m_ value) >> m_logPageSize;203 uintptr_t lastPage = (reinterpret_cast<uintptr_t>(node->m_ value) + node->m_key- 1) >> m_logPageSize;204 205 uintptr_t lastPageForLeftAllocation = (reinterpret_cast<uintptr_t>(node->m_ value) + sizeInBytes - 1) >> m_logPageSize;206 uintptr_t firstPageForRightAllocation = (reinterpret_cast<uintptr_t>(node->m_ value) + node->m_key- sizeInBytes) >> m_logPageSize;202 uintptr_t firstPage = reinterpret_cast<uintptr_t>(node->m_start) >> m_logPageSize; 203 uintptr_t lastPage = (reinterpret_cast<uintptr_t>(node->m_start) + node->m_sizeInBytes - 1) >> m_logPageSize; 204 205 uintptr_t lastPageForLeftAllocation = (reinterpret_cast<uintptr_t>(node->m_start) + sizeInBytes - 1) >> m_logPageSize; 206 uintptr_t firstPageForRightAllocation = (reinterpret_cast<uintptr_t>(node->m_start) + node->m_sizeInBytes - sizeInBytes) >> m_logPageSize; 207 207 208 208 if (lastPageForLeftAllocation - firstPage + 1 <= lastPage - firstPageForRightAllocation + 1) { 209 209 // Allocate in the left side of the returned chunk, and slide the node to the right. 210 result = node->m_ value;211 212 m_freeSpaceStartAddressMap.remove(node->m_ value);213 214 node->m_ key-= sizeInBytes;215 node->m_ value = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(node->m_value) + sizeInBytes);210 result = node->m_start; 211 212 m_freeSpaceStartAddressMap.remove(node->m_start); 213 214 node->m_sizeInBytes -= sizeInBytes; 215 node->m_start = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(node->m_start) + sizeInBytes); 216 216 217 217 m_freeSpaceSizeMap.insert(node); 218 m_freeSpaceStartAddressMap.add(node->m_ value, node);218 m_freeSpaceStartAddressMap.add(node->m_start, node); 219 219 } else { 220 220 // Allocate in the right size of the returned chunk, and slide the node to the left; 221 221 222 result = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(node->m_ value) + node->m_key- sizeInBytes);223 224 m_freeSpaceEndAddressMap.remove(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(node->m_ value) + node->m_key));225 226 node->m_ key-= sizeInBytes;222 result = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(node->m_start) + node->m_sizeInBytes - sizeInBytes); 223 224 m_freeSpaceEndAddressMap.remove(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(node->m_start) + node->m_sizeInBytes)); 225 226 node->m_sizeInBytes -= sizeInBytes; 227 227 228 228 m_freeSpaceSizeMap.insert(node); … … 256 256 size_t result = 0; 257 257 for (FreeSpaceNode* node = m_freeSpaceSizeMap.first(); node; node = node->successor()) 258 result += node->m_ key;258 result += node->m_sizeInBytes; 259 259 return result; 260 260 #else … … 275 275 // remove its end from the end address map. 276 276 277 ASSERT(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(leftNeighbor->second->m_ value) + leftNeighbor->second->m_key) == leftNeighbor->first);277 ASSERT(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(leftNeighbor->second->m_start) + leftNeighbor->second->m_sizeInBytes) == leftNeighbor->first); 278 278 279 279 FreeSpaceNode* leftNode = leftNeighbor->second; 280 280 281 void* leftStart = leftNode->m_ value;282 size_t leftSize = leftNode->m_ key;281 void* leftStart = leftNode->m_start; 282 size_t leftSize = leftNode->m_sizeInBytes; 283 283 void* leftEnd = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(leftStart) + leftSize); 284 284 … … 293 293 // right, whilst removing the right neighbor from the maps. 294 294 295 ASSERT(rightNeighbor->second->m_ value== rightNeighbor->first);295 ASSERT(rightNeighbor->second->m_start == rightNeighbor->first); 296 296 297 297 FreeSpaceNode* rightNode = rightNeighbor->second; 298 298 void* rightStart = rightNeighbor->first; 299 size_t rightSize = rightNode->m_ key;299 size_t rightSize = rightNode->m_sizeInBytes; 300 300 void* rightEnd = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(rightStart) + rightSize); 301 301 … … 309 309 freeFreeSpaceNode(rightNode); 310 310 311 leftNode->m_ key+= sizeInBytes + rightSize;311 leftNode->m_sizeInBytes += sizeInBytes + rightSize; 312 312 313 313 m_freeSpaceSizeMap.insert(leftNode); 314 314 m_freeSpaceEndAddressMap.add(rightEnd, leftNode); 315 315 } else { 316 leftNode->m_ key+= sizeInBytes;316 leftNode->m_sizeInBytes += sizeInBytes; 317 317 318 318 m_freeSpaceSizeMap.insert(leftNode); … … 325 325 FreeSpaceNode* rightNode = rightNeighbor->second; 326 326 void* rightStart = rightNeighbor->first; 327 size_t rightSize = rightNode->m_ key;327 size_t rightSize = rightNode->m_sizeInBytes; 328 328 void* rightEnd = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(rightStart) + rightSize); 329 329 … … 334 334 m_freeSpaceStartAddressMap.remove(rightStart); 335 335 336 rightNode->m_ key+= sizeInBytes;337 rightNode->m_ value= start;336 rightNode->m_sizeInBytes += sizeInBytes; 337 rightNode->m_start = start; 338 338 339 339 m_freeSpaceSizeMap.insert(rightNode); … … 344 344 FreeSpaceNode* node = allocFreeSpaceNode(); 345 345 346 node->m_ key= sizeInBytes;347 node->m_ value= start;346 node->m_sizeInBytes = sizeInBytes; 347 node->m_start = start; 348 348 349 349 m_freeSpaceSizeMap.insert(node); -
trunk/Source/JavaScriptCore/wtf/MetaAllocator.h
r104900 r105646 46 46 class MetaAllocator { 47 47 WTF_MAKE_NONCOPYABLE(MetaAllocator); 48 48 49 public: 49 50 50 WTF_EXPORT_PRIVATE MetaAllocator(size_t allocationGranule); 51 51 … … 102 102 friend class MetaAllocatorHandle; 103 103 104 typedef RedBlackTree<size_t, void*> Tree; 105 typedef Tree::Node FreeSpaceNode; 104 class FreeSpaceNode : public RedBlackTree<FreeSpaceNode, size_t>::Node { 105 public: 106 FreeSpaceNode(void* start, size_t sizeInBytes) 107 : m_start(start) 108 , m_sizeInBytes(sizeInBytes) 109 { 110 } 111 112 size_t key() 113 { 114 return m_sizeInBytes; 115 } 116 117 void* m_start; 118 size_t m_sizeInBytes; 119 }; 120 typedef RedBlackTree<FreeSpaceNode, size_t> Tree; 106 121 107 122 // Remove free space from the allocator. This is effectively … … 122 137 void incrementPageOccupancy(void* address, size_t sizeInBytes); 123 138 void decrementPageOccupancy(void* address, size_t sizeInBytes); 124 139 125 140 // Utilities. 126 141 -
trunk/Source/JavaScriptCore/wtf/RedBlackTree.h
r95901 r105646 42 42 // - The key type must implement operator< and ==. 43 43 44 template< typename KeyType, typename ValueType>44 template<class NodeType, typename KeyType> 45 45 class RedBlackTree { 46 46 WTF_MAKE_NONCOPYABLE(RedBlackTree); … … 56 56 57 57 public: 58 Node(KeyType key, ValueType value) 59 : m_key(key) 60 , m_value(value) 61 { 62 } 63 64 const Node* successor() const 58 const NodeType* successor() const 65 59 { 66 60 const Node* x = this; 67 61 if (x->right()) 68 62 return treeMinimum(x->right()); 69 const Node * y = x->parent();63 const NodeType* y = x->parent(); 70 64 while (y && x == y->right()) { 71 65 x = y; … … 75 69 } 76 70 77 const Node * predecessor() const71 const NodeType* predecessor() const 78 72 { 79 73 const Node* x = this; 80 74 if (x->left()) 81 75 return treeMaximum(x->left()); 82 const Node * y = x->parent();76 const NodeType* y = x->parent(); 83 77 while (y && x == y->left()) { 84 78 x = y; … … 88 82 } 89 83 90 Node* successor() 91 { 92 return const_cast<Node*>(const_cast<const Node*>(this)->successor()); 93 } 94 95 Node* predecessor() 96 { 97 return const_cast<Node*>(const_cast<const Node*>(this)->predecessor()); 98 } 99 100 KeyType m_key; 101 ValueType m_value; 84 NodeType* successor() 85 { 86 return const_cast<NodeType*>(const_cast<const Node*>(this)->successor()); 87 } 88 89 NodeType* predecessor() 90 { 91 return const_cast<NodeType*>(const_cast<const Node*>(this)->predecessor()); 92 } 102 93 103 94 private: … … 111 102 // NOTE: these methods should pack the parent and red into a single 112 103 // word. But doing so appears to reveal a bug in the compiler. 113 Node * parent() const114 { 115 return reinterpret_cast<Node *>(m_parentAndRed & ~static_cast<uintptr_t>(1));116 } 117 118 void setParent(Node * newParent)104 NodeType* parent() const 105 { 106 return reinterpret_cast<NodeType*>(m_parentAndRed & ~static_cast<uintptr_t>(1)); 107 } 108 109 void setParent(NodeType* newParent) 119 110 { 120 111 m_parentAndRed = reinterpret_cast<uintptr_t>(newParent) | (m_parentAndRed & 1); 121 112 } 122 113 123 Node * left() const114 NodeType* left() const 124 115 { 125 116 return m_left; 126 117 } 127 118 128 void setLeft(Node * node)119 void setLeft(NodeType* node) 129 120 { 130 121 m_left = node; 131 122 } 132 123 133 Node * right() const124 NodeType* right() const 134 125 { 135 126 return m_right; 136 127 } 137 128 138 void setRight(Node * node)129 void setRight(NodeType* node) 139 130 { 140 131 m_right = node; … … 156 147 } 157 148 158 Node * m_left;159 Node * m_right;149 NodeType* m_left; 150 NodeType* m_right; 160 151 uintptr_t m_parentAndRed; 161 152 }; 162 153 163 154 RedBlackTree() 164 155 : m_root(0) … … 166 157 } 167 158 168 void insert(Node * x)159 void insert(NodeType* x) 169 160 { 170 161 x->reset(); … … 174 165 while (x != m_root && x->parent()->color() == Red) { 175 166 if (x->parent() == x->parent()->parent()->left()) { 176 Node * y = x->parent()->parent()->right();167 NodeType* y = x->parent()->parent()->right(); 177 168 if (y && y->color() == Red) { 178 169 // Case 1 … … 194 185 } else { 195 186 // Same as "then" clause with "right" and "left" exchanged. 196 Node * y = x->parent()->parent()->left();187 NodeType* y = x->parent()->parent()->left(); 197 188 if (y && y->color() == Red) { 198 189 // Case 1 … … 218 209 } 219 210 220 Node * remove(Node* z)211 NodeType* remove(NodeType* z) 221 212 { 222 213 ASSERT(z); … … 224 215 225 216 // Y is the node to be unlinked from the tree. 226 Node * y;217 NodeType* y; 227 218 if (!z->left() || !z->right()) 228 219 y = z; … … 231 222 232 223 // Y is guaranteed to be non-null at this point. 233 Node * x;224 NodeType* x; 234 225 if (y->left()) 235 226 x = y->left(); … … 239 230 // X is the child of y which might potentially replace y in 240 231 // the tree. X might be null at this point. 241 Node * xParent;232 NodeType* xParent; 242 233 if (x) { 243 234 x->setParent(y->parent()); … … 282 273 } 283 274 284 Node * remove(const KeyType& key)285 { 286 Node * result = findExact(key);275 NodeType* remove(const KeyType& key) 276 { 277 NodeType* result = findExact(key); 287 278 if (!result) 288 279 return 0; … … 290 281 } 291 282 292 Node * findExact(const KeyType& key) const293 { 294 for (Node * current = m_root; current;) {295 if (current-> m_key== key)283 NodeType* findExact(const KeyType& key) const 284 { 285 for (NodeType* current = m_root; current;) { 286 if (current->key() == key) 296 287 return current; 297 if (key < current-> m_key)288 if (key < current->key()) 298 289 current = current->left(); 299 290 else … … 303 294 } 304 295 305 Node * findLeastGreaterThanOrEqual(const KeyType& key) const306 { 307 Node * best = 0;308 for (Node * current = m_root; current;) {309 if (current-> m_key== key)296 NodeType* findLeastGreaterThanOrEqual(const KeyType& key) const 297 { 298 NodeType* best = 0; 299 for (NodeType* current = m_root; current;) { 300 if (current->key() == key) 310 301 return current; 311 if (current-> m_key< key)302 if (current->key() < key) 312 303 current = current->right(); 313 304 else { … … 319 310 } 320 311 321 Node * findGreatestLessThanOrEqual(const KeyType& key) const322 { 323 Node * best = 0;324 for (Node * current = m_root; current;) {325 if (current-> m_key== key)312 NodeType* findGreatestLessThanOrEqual(const KeyType& key) const 313 { 314 NodeType* best = 0; 315 for (NodeType* current = m_root; current;) { 316 if (current->key() == key) 326 317 return current; 327 if (current-> m_key> key)318 if (current->key() > key) 328 319 current = current->left(); 329 320 else { … … 335 326 } 336 327 337 Node * first() const328 NodeType* first() const 338 329 { 339 330 if (!m_root) … … 342 333 } 343 334 344 Node * last() const335 NodeType* last() const 345 336 { 346 337 if (!m_root) … … 353 344 { 354 345 size_t result = 0; 355 for (Node * current = first(); current; current = current->successor())346 for (NodeType* current = first(); current; current = current->successor()) 356 347 result++; 357 348 return result; … … 367 358 // Finds the minimum element in the sub-tree rooted at the given 368 359 // node. 369 static Node * treeMinimum(Node* x)360 static NodeType* treeMinimum(NodeType* x) 370 361 { 371 362 while (x->left()) … … 374 365 } 375 366 376 static Node * treeMaximum(Node* x)367 static NodeType* treeMaximum(NodeType* x) 377 368 { 378 369 while (x->right()) … … 381 372 } 382 373 383 static const Node * treeMinimum(const Node* x)374 static const NodeType* treeMinimum(const NodeType* x) 384 375 { 385 376 while (x->left()) … … 388 379 } 389 380 390 static const Node * treeMaximum(const Node* x)381 static const NodeType* treeMaximum(const NodeType* x) 391 382 { 392 383 while (x->right()) … … 395 386 } 396 387 397 void treeInsert(Node * z)388 void treeInsert(NodeType* z) 398 389 { 399 390 ASSERT(!z->left()); … … 402 393 ASSERT(z->color() == Red); 403 394 404 Node * y = 0;405 Node * x = m_root;395 NodeType* y = 0; 396 NodeType* x = m_root; 406 397 while (x) { 407 398 y = x; 408 if (z-> m_key < x->m_key)399 if (z->key() < x->key()) 409 400 x = x->left(); 410 401 else … … 415 406 m_root = z; 416 407 else { 417 if (z-> m_key < y->m_key)408 if (z->key() < y->key()) 418 409 y->setLeft(z); 419 410 else … … 428 419 // Left-rotates the subtree rooted at x. 429 420 // Returns the new root of the subtree (x's right child). 430 Node * leftRotate(Node* x)421 NodeType* leftRotate(NodeType* x) 431 422 { 432 423 // Set y. 433 Node * y = x->right();424 NodeType* y = x->right(); 434 425 435 426 // Turn y's left subtree into x's right subtree. … … 458 449 // Right-rotates the subtree rooted at y. 459 450 // Returns the new root of the subtree (y's left child). 460 Node * rightRotate(Node* y)451 NodeType* rightRotate(NodeType* y) 461 452 { 462 453 // Set x. 463 Node * x = y->left();454 NodeType* x = y->left(); 464 455 465 456 // Turn x's right subtree into y's left subtree. … … 489 480 // a node. Note that x may be null, which is why xParent must be 490 481 // supplied. 491 void removeFixup(Node * x, Node* xParent)482 void removeFixup(NodeType* x, NodeType* xParent) 492 483 { 493 484 while (x != m_root && (!x || x->color() == Black)) { … … 497 488 // the code; it comes about from the properties of the 498 489 // red-black tree. 499 Node * w = xParent->right();490 NodeType* w = xParent->right(); 500 491 ASSERT(w); // x's sibling should not be null. 501 492 if (w->color() == Red) { … … 537 528 // the code; it comes about from the properties of the 538 529 // red-black tree. 539 Node * w = xParent->left();530 NodeType* w = xParent->left(); 540 531 ASSERT(w); // x's sibling should not be null. 541 532 if (w->color() == Red) { … … 575 566 } 576 567 577 Node * m_root;568 NodeType* m_root; 578 569 }; 579 570
Note: See TracChangeset
for help on using the changeset viewer.