OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ | 5 #ifndef BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ |
6 #define BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ | 6 #define BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <atomic> | 10 #include <atomic> |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 // when the last field is actually variable length. | 506 // when the last field is actually variable length. |
507 template <typename T> | 507 template <typename T> |
508 T* New(size_t size) { | 508 T* New(size_t size) { |
509 if (size < sizeof(T)) | 509 if (size < sizeof(T)) |
510 size = sizeof(T); | 510 size = sizeof(T); |
511 Reference ref = Allocate(size, T::kPersistentTypeId); | 511 Reference ref = Allocate(size, T::kPersistentTypeId); |
512 void* mem = | 512 void* mem = |
513 const_cast<void*>(GetBlockData(ref, T::kPersistentTypeId, size)); | 513 const_cast<void*>(GetBlockData(ref, T::kPersistentTypeId, size)); |
514 if (!mem) | 514 if (!mem) |
515 return nullptr; | 515 return nullptr; |
516 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(mem) & (ALIGNOF(T) - 1)); | 516 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(mem) & (alignof(T) - 1)); |
517 return new (mem) T(); | 517 return new (mem) T(); |
518 } | 518 } |
519 template <typename T> | 519 template <typename T> |
520 T* New() { | 520 T* New() { |
521 return New<T>(sizeof(T)); | 521 return New<T>(sizeof(T)); |
522 } | 522 } |
523 | 523 |
524 // Similar to New, above, but construct the object out of an existing memory | 524 // Similar to New, above, but construct the object out of an existing memory |
525 // block and of an expected type. If |clear| is true, memory will be zeroed | 525 // block and of an expected type. If |clear| is true, memory will be zeroed |
526 // before construction. Though this is not standard object behavior, it | 526 // before construction. Though this is not standard object behavior, it |
527 // is present to match with new allocations that always come from zeroed | 527 // is present to match with new allocations that always come from zeroed |
528 // memory. Anything previously present simply ceases to exist; no destructor | 528 // memory. Anything previously present simply ceases to exist; no destructor |
529 // is called for it so explicitly Delete() the old object first if need be. | 529 // is called for it so explicitly Delete() the old object first if need be. |
530 // Calling this will not invalidate existing pointers to the object, either | 530 // Calling this will not invalidate existing pointers to the object, either |
531 // in this process or others, so changing the object could have unpredictable | 531 // in this process or others, so changing the object could have unpredictable |
532 // results. USE WITH CARE! | 532 // results. USE WITH CARE! |
533 template <typename T> | 533 template <typename T> |
534 T* New(Reference ref, uint32_t from_type_id, bool clear) { | 534 T* New(Reference ref, uint32_t from_type_id, bool clear) { |
535 DCHECK_LE(sizeof(T), GetAllocSize(ref)) << "alloc not big enough for obj"; | 535 DCHECK_LE(sizeof(T), GetAllocSize(ref)) << "alloc not big enough for obj"; |
536 // Make sure the memory is appropriate. This won't be used until after | 536 // Make sure the memory is appropriate. This won't be used until after |
537 // the type is changed but checking first avoids the possibility of having | 537 // the type is changed but checking first avoids the possibility of having |
538 // to change the type back. | 538 // to change the type back. |
539 void* mem = const_cast<void*>(GetBlockData(ref, 0, sizeof(T))); | 539 void* mem = const_cast<void*>(GetBlockData(ref, 0, sizeof(T))); |
540 if (!mem) | 540 if (!mem) |
541 return nullptr; | 541 return nullptr; |
542 // Ensure the allocator's internal alignment is sufficient for this object. | 542 // Ensure the allocator's internal alignment is sufficient for this object. |
543 // This protects against coding errors in the allocator. | 543 // This protects against coding errors in the allocator. |
544 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(mem) & (ALIGNOF(T) - 1)); | 544 DCHECK_EQ(0U, reinterpret_cast<uintptr_t>(mem) & (alignof(T) - 1)); |
545 // Change the type, clearing the memory if so desired. The new type is | 545 // Change the type, clearing the memory if so desired. The new type is |
546 // "transitioning" so that there is no race condition with the construction | 546 // "transitioning" so that there is no race condition with the construction |
547 // of the object should another thread be simultaneously iterating over | 547 // of the object should another thread be simultaneously iterating over |
548 // data. This will "acquire" the memory so no changes get reordered before | 548 // data. This will "acquire" the memory so no changes get reordered before |
549 // it. | 549 // it. |
550 if (!ChangeType(ref, kTypeIdTransitioning, from_type_id, clear)) | 550 if (!ChangeType(ref, kTypeIdTransitioning, from_type_id, clear)) |
551 return nullptr; | 551 return nullptr; |
552 // Construct an object of the desired type on this memory, just as if | 552 // Construct an object of the desired type on this memory, just as if |
553 // New() had been called to create it. | 553 // New() had been called to create it. |
554 T* obj = new (mem) T(); | 554 T* obj = new (mem) T(); |
(...skipping 306 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 // share the same pointer then an allocation on one will amount to an | 861 // share the same pointer then an allocation on one will amount to an |
862 // allocation for all. | 862 // allocation for all. |
863 volatile std::atomic<Reference>* const reference_; | 863 volatile std::atomic<Reference>* const reference_; |
864 | 864 |
865 // No DISALLOW_COPY_AND_ASSIGN as it's okay to copy/move these objects. | 865 // No DISALLOW_COPY_AND_ASSIGN as it's okay to copy/move these objects. |
866 }; | 866 }; |
867 | 867 |
868 } // namespace base | 868 } // namespace base |
869 | 869 |
870 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ | 870 #endif // BASE_METRICS_PERSISTENT_MEMORY_ALLOCATOR_H_ |
OLD | NEW |