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

Side by Side Diff: Source/wtf/Vector.h

Issue 23455034: Possible fix for a Mac performance regression. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 3 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
« no previous file with comments | « Source/wtf/Deque.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * This library is free software; you can redistribute it and/or 4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public 5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either 6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version. 7 * version 2 of the License, or (at your option) any later version.
8 * 8 *
9 * This library is distributed in the hope that it will be useful, 9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 void reallocateBuffer(size_t newCapacity) 269 void reallocateBuffer(size_t newCapacity)
270 { 270 {
271 ASSERT(shouldReallocateBuffer(newCapacity)); 271 ASSERT(shouldReallocateBuffer(newCapacity));
272 // Using "unsigned" is not a limitation because Chromium's max mallo c() is 2GB even on 64-bit. 272 // Using "unsigned" is not a limitation because Chromium's max mallo c() is 2GB even on 64-bit.
273 RELEASE_ASSERT(newCapacity <= std::numeric_limits<unsigned>::max() / sizeof(T)); 273 RELEASE_ASSERT(newCapacity <= std::numeric_limits<unsigned>::max() / sizeof(T));
274 size_t sizeToAllocate = fastMallocGoodSize(newCapacity * sizeof(T)); 274 size_t sizeToAllocate = fastMallocGoodSize(newCapacity * sizeof(T));
275 m_capacity = sizeToAllocate / sizeof(T); 275 m_capacity = sizeToAllocate / sizeof(T);
276 m_buffer = static_cast<T*>(fastRealloc(m_buffer, sizeToAllocate)); 276 m_buffer = static_cast<T*>(fastRealloc(m_buffer, sizeToAllocate));
277 } 277 }
278 278
279 T* buffer() { return m_buffer; } 279 ALWAYS_INLINE T* buffer() { return m_buffer; }
280 const T* buffer() const { return m_buffer; } 280 ALWAYS_INLINE const T* buffer() const { return m_buffer; }
281 size_t capacity() const { return m_capacity; } 281 ALWAYS_INLINE size_t capacity() const { return m_capacity; }
282 282
283 protected: 283 protected:
284 VectorBufferBase() 284 VectorBufferBase()
285 : m_buffer(0) 285 : m_buffer(0)
286 , m_capacity(0) 286 , m_capacity(0)
287 , m_size(0)
287 { 288 {
288 } 289 }
289 290
290 VectorBufferBase(T* buffer, size_t capacity) 291 VectorBufferBase(T* buffer, size_t capacity)
291 : m_buffer(buffer) 292 : m_buffer(buffer)
292 , m_capacity(capacity) 293 , m_capacity(capacity)
294 , m_size(0)
293 { 295 {
294 } 296 }
295 297
296 ~VectorBufferBase() 298 ~VectorBufferBase()
297 { 299 {
298 m_buffer = 0;
299 m_size = 0;
300 } 300 }
301 301
302 T* m_buffer; 302 T* m_buffer;
303 unsigned m_capacity; 303 unsigned m_capacity;
304 unsigned m_size; 304 unsigned m_size;
305 }; 305 };
306 306
307 template<typename T, size_t inlineCapacity> 307 template<typename T, size_t inlineCapacity>
308 class VectorBuffer; 308 class VectorBuffer;
309 309
310 template<typename T> 310 template<typename T>
311 class VectorBuffer<T, 0> : private VectorBufferBase<T> { 311 class VectorBuffer<T, 0> : private VectorBufferBase<T> {
312 private: 312 private:
313 typedef VectorBufferBase<T> Base; 313 typedef VectorBufferBase<T> Base;
314 public: 314 public:
315 VectorBuffer() 315 VectorBuffer()
316 { 316 {
317 } 317 }
318 318
319 VectorBuffer(size_t capacity) 319 VectorBuffer(size_t capacity)
320 { 320 {
321 // Calling malloc(0) might take a lock and may actually do an 321 // Calling malloc(0) might take a lock and may actually do an
322 // allocation on some systems. 322 // allocation on some systems.
323 if (capacity) 323 if (capacity)
324 allocateBuffer(capacity); 324 allocateBuffer(capacity);
325 } 325 }
326 326
327 ~VectorBuffer()
328 {
329 }
330
327 void deallocateBuffer(T* bufferToDeallocate) 331 void deallocateBuffer(T* bufferToDeallocate)
328 { 332 {
329 fastFree(bufferToDeallocate); 333 fastFree(bufferToDeallocate);
330 } 334 }
331 335
332 void clearBufferPointer() 336 void clearBufferPointer()
333 { 337 {
334 m_buffer = 0; 338 m_buffer = 0;
335 m_capacity = 0; 339 m_capacity = 0;
336 } 340 }
337 341
338 ~VectorBuffer() 342 void destruct()
339 { 343 {
340 deallocateBuffer(buffer()); 344 deallocateBuffer(m_buffer);
345 m_buffer = 0;
341 } 346 }
342 347
343 void swap(VectorBuffer<T, 0>& other) 348 void swap(VectorBuffer<T, 0>& other)
344 { 349 {
345 std::swap(m_buffer, other.m_buffer); 350 std::swap(m_buffer, other.m_buffer);
346 std::swap(m_capacity, other.m_capacity); 351 std::swap(m_capacity, other.m_capacity);
347 } 352 }
348 353
349 void restoreInlineBufferIfNeeded() { } 354 void restoreInlineBufferIfNeeded() { }
350 355
(...skipping 23 matching lines...) Expand all
374 { 379 {
375 } 380 }
376 381
377 VectorBuffer(size_t capacity) 382 VectorBuffer(size_t capacity)
378 : Base(inlineBuffer(), inlineCapacity) 383 : Base(inlineBuffer(), inlineCapacity)
379 { 384 {
380 if (capacity > inlineCapacity) 385 if (capacity > inlineCapacity)
381 Base::allocateBuffer(capacity); 386 Base::allocateBuffer(capacity);
382 } 387 }
383 388
389 ~VectorBuffer()
390 {
391 }
392
384 void deallocateBuffer(T* bufferToDeallocate) 393 void deallocateBuffer(T* bufferToDeallocate)
385 { 394 {
386 if (UNLIKELY(bufferToDeallocate != inlineBuffer())) 395 if (UNLIKELY(bufferToDeallocate != inlineBuffer()))
387 fastFree(bufferToDeallocate); 396 fastFree(bufferToDeallocate);
388 } 397 }
389 398
399 void destruct()
400 {
401 deallocateBuffer(m_buffer);
402 m_buffer = 0;
403 }
404
390 void clearBufferPointer() 405 void clearBufferPointer()
391 { 406 {
392 m_buffer = 0; 407 m_buffer = 0;
393 m_capacity = 0; 408 m_capacity = 0;
394 } 409 }
395 410
396 ~VectorBuffer()
397 {
398 deallocateBuffer(buffer());
399 }
400
401 void allocateBuffer(size_t newCapacity) 411 void allocateBuffer(size_t newCapacity)
402 { 412 {
403 // FIXME: This should ASSERT(!m_buffer) to catch misuse/leaks. 413 // FIXME: This should ASSERT(!m_buffer) to catch misuse/leaks.
404 if (newCapacity > inlineCapacity) 414 if (newCapacity > inlineCapacity)
405 Base::allocateBuffer(newCapacity); 415 Base::allocateBuffer(newCapacity);
406 else { 416 else {
407 m_buffer = inlineBuffer(); 417 m_buffer = inlineBuffer();
408 m_capacity = inlineCapacity; 418 m_capacity = inlineCapacity;
409 } 419 }
410 } 420 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 using Base::capacity; 464 using Base::capacity;
455 465
456 protected: 466 protected:
457 using Base::m_size; 467 using Base::m_size;
458 468
459 private: 469 private:
460 using Base::m_buffer; 470 using Base::m_buffer;
461 using Base::m_capacity; 471 using Base::m_capacity;
462 472
463 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); 473 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T);
464 T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffe r); } 474 ALWAYS_INLINE T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inli neBuffer.buffer); }
465 const T* inlineBuffer() const { return reinterpret_cast_ptr<const T*>(m_ inlineBuffer.buffer); } 475 ALWAYS_INLINE const T* inlineBuffer() const { return reinterpret_cast_pt r<const T*>(m_inlineBuffer.buffer); }
466 476
467 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; 477 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer;
468 }; 478 };
469 479
470 template<typename T, size_t inlineCapacity = 0> 480 template<typename T, size_t inlineCapacity = 0>
471 class Vector : private VectorBuffer<T, inlineCapacity> { 481 class Vector : private VectorBuffer<T, inlineCapacity> {
472 WTF_MAKE_FAST_ALLOCATED; 482 WTF_MAKE_FAST_ALLOCATED;
473 private: 483 private:
474 typedef VectorBuffer<T, inlineCapacity> Base; 484 typedef VectorBuffer<T, inlineCapacity> Base;
475 typedef VectorTypeOperations<T> TypeOperations; 485 typedef VectorTypeOperations<T> TypeOperations;
476 486
477 public: 487 public:
478 typedef T ValueType; 488 typedef T ValueType;
479 489
480 typedef T* iterator; 490 typedef T* iterator;
481 typedef const T* const_iterator; 491 typedef const T* const_iterator;
482 typedef std::reverse_iterator<iterator> reverse_iterator; 492 typedef std::reverse_iterator<iterator> reverse_iterator;
483 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 493 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
484 494
485 Vector() 495 Vector()
486 { 496 {
487 m_size = 0; 497 // Initialization occurs on the base classes.
488 } 498 }
489 499
490 explicit Vector(size_t size) 500 explicit Vector(size_t size)
491 : Base(size) 501 : Base(size)
492 { 502 {
493 m_size = size; 503 m_size = size;
494 TypeOperations::initialize(begin(), end()); 504 TypeOperations::initialize(begin(), end());
495 } 505 }
496 506
497 ~Vector() 507 ~Vector()
498 { 508 {
499 shrink(0); 509 if (!inlineCapacity) {
510 if (LIKELY(!Base::buffer()))
511 return;
512 shrink(0);
513 } else {
514 if (UNLIKELY(m_size))
515 shrink(0);
516 }
517 Base::destruct();
500 } 518 }
501 519
502 Vector(const Vector&); 520 Vector(const Vector&);
503 template<size_t otherCapacity> 521 template<size_t otherCapacity>
504 Vector(const Vector<T, otherCapacity>&); 522 Vector(const Vector<T, otherCapacity>&);
505 523
506 Vector& operator=(const Vector&); 524 Vector& operator=(const Vector&);
507 template<size_t otherCapacity> 525 template<size_t otherCapacity>
508 Vector& operator=(const Vector<T, otherCapacity>&); 526 Vector& operator=(const Vector<T, otherCapacity>&);
509 527
510 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) 528 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES)
511 Vector(Vector&&); 529 Vector(Vector&&);
512 Vector& operator=(Vector&&); 530 Vector& operator=(Vector&&);
513 #endif 531 #endif
514 532
515 size_t size() const { return m_size; } 533 ALWAYS_INLINE size_t size() const { return m_size; }
516 size_t capacity() const { return Base::capacity(); } 534 ALWAYS_INLINE size_t capacity() const { return Base::capacity(); }
517 bool isEmpty() const { return !size(); } 535 ALWAYS_INLINE bool isEmpty() const { return !size(); }
518 536
519 T& at(size_t i) 537 T& at(size_t i)
520 { 538 {
521 RELEASE_ASSERT(i < size()); 539 RELEASE_ASSERT(i < size());
522 return Base::buffer()[i]; 540 return Base::buffer()[i];
523 } 541 }
524 const T& at(size_t i) const 542 const T& at(size_t i) const
525 { 543 {
526 RELEASE_ASSERT(i < size()); 544 RELEASE_ASSERT(i < size());
527 return Base::buffer()[i]; 545 return Base::buffer()[i];
(...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after
1063 inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, i nlineCapacity>& b) 1081 inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, i nlineCapacity>& b)
1064 { 1082 {
1065 return !(a == b); 1083 return !(a == b);
1066 } 1084 }
1067 1085
1068 } // namespace WTF 1086 } // namespace WTF
1069 1087
1070 using WTF::Vector; 1088 using WTF::Vector;
1071 1089
1072 #endif // WTF_Vector_h 1090 #endif // WTF_Vector_h
OLDNEW
« no previous file with comments | « Source/wtf/Deque.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698