b2TrackedBlock.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (c) 2014 Google, Inc.
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include <Box2D/Common/b2TrackedBlock.h>
  19. #include <stddef.h>
  20. #include <stdint.h>
  21. #include <new>
  22. // Initialize this block with a reference to "this".
  23. b2TrackedBlock::b2TrackedBlock()
  24. {
  25. b2TrackedBlock** pointerToThis =
  26. (b2TrackedBlock**)((uint8*)GetMemory() - sizeof(b2TrackedBlock**));
  27. *pointerToThis = this;
  28. }
  29. /// Get the allocated memory associated with this block.
  30. void* b2TrackedBlock::GetMemory() const
  31. {
  32. // The size of data in this without padding.
  33. static const uint32 kSizeOfThisWithNoPadding =
  34. sizeof(*this) - sizeof(m_padding) + sizeof(b2TrackedBlock**);
  35. // Make sure b2_mallocAlignment is base2.
  36. b2Assert(((b2_mallocAlignment - 1) & b2_mallocAlignment) == 0);
  37. // Round the pointer following data in this to b2_mallocAlignment.
  38. uint8* const aligned = (uint8*)(
  39. ((uintptr_t)this + kSizeOfThisWithNoPadding + b2_mallocAlignment - 1) &
  40. ~((uintptr_t)b2_mallocAlignment - 1));
  41. // Verify offset doesn't overlap data in this.
  42. b2Assert((uintptr_t)aligned - (uintptr_t)this >= kSizeOfThisWithNoPadding);
  43. return aligned;
  44. }
  45. /// Allocate a b2TrackedBlock returning a pointer to memory of size
  46. /// bytes that can be used by the caller.
  47. void* b2TrackedBlock::Allocate(uint32 size)
  48. {
  49. void* memory = (b2TrackedBlock*)b2Alloc(sizeof(b2TrackedBlock) +
  50. size);
  51. if (!memory)
  52. {
  53. return NULL;
  54. }
  55. return (new(memory) b2TrackedBlock)->GetMemory();
  56. }
  57. /// Get a b2TrackedBlock from a pointer to memory returned by
  58. /// b2TrackedBlock::Allocate().
  59. b2TrackedBlock* b2TrackedBlock::GetFromMemory(void *memory)
  60. {
  61. uint8* const aligned = (uint8*)memory;
  62. b2Assert(memory);
  63. b2TrackedBlock **blockPtr = (b2TrackedBlock**)(aligned -
  64. sizeof(b2TrackedBlock**));
  65. b2Assert(*blockPtr);
  66. return *blockPtr;
  67. }
  68. /// Free a block of memory returned by b2TrackedBlock::Allocate()
  69. void b2TrackedBlock::Free(void *memory)
  70. {
  71. Free(GetFromMemory(memory));
  72. }
  73. /// Free a b2TrackedBlock.
  74. void b2TrackedBlock::Free(b2TrackedBlock *block)
  75. {
  76. b2Assert(block);
  77. block->~b2TrackedBlock();
  78. b2Free(block);
  79. }
  80. /// Allocate a block of size bytes using b2TrackedBlock::Allocate().
  81. void* b2TrackedBlockAllocator::Allocate(uint32 size)
  82. {
  83. void *memory = b2TrackedBlock::Allocate(size);
  84. m_blocks.InsertBefore(b2TrackedBlock::GetFromMemory(memory));
  85. return memory;
  86. }
  87. /// Free a block returned by Allocate().
  88. void b2TrackedBlockAllocator::Free(void *memory)
  89. {
  90. b2TrackedBlock::Free(memory);
  91. }
  92. /// Free all allocated blocks.
  93. void b2TrackedBlockAllocator::FreeAll()
  94. {
  95. while (!m_blocks.IsEmpty())
  96. {
  97. b2TrackedBlock::Free(m_blocks.GetNext());
  98. }
  99. }