// Abstraction implemented by all large object spaces. class LargeObjectSpace : public DiscontinuousSpace, public AllocSpace { public:
SpaceType GetType() const override { return kSpaceTypeLargeObjectSpace;
} void SwapBitmaps(); void CopyLiveToMarked(); virtualvoid Walk(DlMallocSpace::WalkCallback, void* arg) = 0; virtual ~LargeObjectSpace() {}
uint64_t GetBytesAllocated() override {
MutexLock mu(Thread::Current(), lock_); return num_bytes_allocated_;
}
uint64_t GetObjectsAllocated() override {
MutexLock mu(Thread::Current(), lock_); return num_objects_allocated_;
}
uint64_t GetTotalBytesAllocated() const {
MutexLock mu(Thread::Current(), lock_); return total_bytes_allocated_;
}
uint64_t GetTotalObjectsAllocated() const {
MutexLock mu(Thread::Current(), lock_); return total_objects_allocated_;
}
size_t FreeList(Thread* self, size_t num_ptrs, mirror::Object** ptrs) override
REQUIRES_SHARED(Locks::mutator_lock_); // LargeObjectSpaces don't have thread local state.
size_t RevokeThreadLocalBuffers(art::Thread*) override { return0U;
}
size_t RevokeAllThreadLocalBuffers() override { return0U;
} bool IsAllocSpace() const override { returntrue;
}
AllocSpace* AsAllocSpace() override { returnthis;
}
collector::ObjectBytePair Sweep(bool swap_bitmaps); bool CanMoveObjects() const override { returnfalse;
} // Current address at which the space begins, which may vary as the space is filled.
uint8_t* Begin() const { return begin_;
} // Current address at which the space ends, which may vary as the space is filled.
uint8_t* End() const { return end_;
} // Current size of space
size_t Size() const { return End() - Begin();
} // Return true if we contain the specified address. bool Contains(const mirror::Object* obj) const override { const uint8_t* byte_obj = reinterpret_cast<const uint8_t*>(obj); return Begin() <= byte_obj && byte_obj < End();
} bool LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) override
REQUIRES_SHARED(Locks::mutator_lock_);
// Return true if the large object is a zygote large object. Potentially slow. virtualbool IsZygoteLargeObject(Thread* self, mirror::Object* obj) const = 0; // Called when we create the zygote space, mark all existing large objects as zygote large // objects. Set mark-bit if called from PreZygoteFork() for ConcurrentCopying // GC to avoid dirtying the first page. virtualvoid SetAllLargeObjectsAsZygoteObjects(Thread* self, bool set_mark_bit) = 0;
virtualvoid ForEachMemMap(std::function<void(const MemMap&)> func) const = 0; // GetRangeAtomic returns Begin() and End() atomically, that is, it never returns Begin() and // End() from different allocations. virtual std::pair<uint8_t*, uint8_t*> GetBeginEndAtomic() const = 0; // Clamp the space size to the given capacity. virtualvoid ClampGrowthLimit(size_t capacity) = 0;
// The way large object spaces are implemented, the object alignment has to be // the same as the *runtime* OS page size. However, in the future this may // change so it is important to use LargeObjectSpace::ObjectAlignment() rather // than gPageSize when appropriate. #ifdefined(ART_PAGE_SIZE_AGNOSTIC) static ALWAYS_INLINE size_t ObjectAlignment() { return gPageSize; } #else static constexpr size_t ObjectAlignment() { return kMinPageSize; } #endif
// Used to ensure mutual exclusion when the allocation spaces data structures, // including the allocation counters below, are being modified. mutable Mutex lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
// Number of bytes which have been allocated into the space and not yet freed. The count is also // included in the identically named field in Heap. Counts actual allocated (after rounding), // not requested, sizes. TODO: It would be cheaper to just maintain total allocated and total // free counts.
uint64_t num_bytes_allocated_ GUARDED_BY(lock_);
uint64_t num_objects_allocated_ GUARDED_BY(lock_);
// Totals for large objects ever allocated, including those that have since been deallocated. // Never decremented.
uint64_t total_bytes_allocated_ GUARDED_BY(lock_);
uint64_t total_objects_allocated_ GUARDED_BY(lock_);
// Begin and end, may change as more large objects are allocated.
uint8_t* begin_;
uint8_t* end_;
class SortByPrevFree { public: booloperator()(const AllocationInfo* a, const AllocationInfo* b) const;
}; using FreeBlocks = std::set<AllocationInfo*,
SortByPrevFree,
TrackingAllocator<AllocationInfo*, kAllocatorTagLOSFreeList>>;
// There is not footer for any allocations at the end of the space, so we keep track of how much // free space there is at the end manually.
MemMap mem_map_; // Side table for allocation info, one per page.
MemMap allocation_info_map_;
AllocationInfo* allocation_info_;
// Free bytes at the end of the space.
size_t free_end_ GUARDED_BY(lock_);
FreeBlocks free_blocks_ GUARDED_BY(lock_);
};
} // namespace space
} // namespace gc
} // namespace art
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.