| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #include "stdafx.h"
- class RecyclerTestObject : public FinalizableObject
- {
- protected:
- RecyclerTestObject()
- {
- generation = currentGeneration;
- }
- public:
- // FinalizableObject implementation
- virtual void Finalize(bool isShutdown) override { VerifyCondition(false); };
- virtual void Dispose(bool isShutdown) override { VerifyCondition(false); };
- virtual void Mark(Recycler * recycler) override { VerifyCondition(false); };
- public:
- static void BeginWalk()
- {
- currentGeneration++;
- walkObjectCount = 0;
- walkScannedByteCount = 0;
- walkBarrierByteCount = 0;
- walkTrackedByteCount = 0;
- walkLeafByteCount = 0;
- maxWalkDepth = 0;
- currentWalkDepth = 0;
- wprintf(_u("-------------------------------------------\n"));
- wprintf(_u("Full heap walk starting\n"));
- }
-
- static void WalkReference(RecyclerTestObject * object)
- {
- if (object != nullptr)
- {
- // See if we've already seen the location in this traversal.
- if (object->generation != currentGeneration)
- {
- // Haven't see it yet. Must be from the previous generation; increment generation and validate that.
- // Update to current generation to indicate we've seen it
- object->generation++;
- VerifyCondition(object->generation == currentGeneration);
- walkObjectCount++;
-
- currentWalkDepth++;
- maxWalkDepth = max(currentWalkDepth, maxWalkDepth);
- // Call virtual for object-specific behavior
- object->DoWalkObject();
- currentWalkDepth--;
- }
- }
- }
- static void EndWalk()
- {
- VerifyCondition(currentWalkDepth == 0);
- wprintf(_u("Full heap walk finished\n"));
- wprintf(_u("Object Count: %12llu\n"), (unsigned long long) walkObjectCount);
- wprintf(_u("Scanned Bytes: %12llu\n"), (unsigned long long) walkScannedByteCount);
- wprintf(_u("Barrier Bytes: %12llu\n"), (unsigned long long) walkBarrierByteCount);
- wprintf(_u("Tracked Bytes: %12llu\n"), (unsigned long long) walkTrackedByteCount);
- wprintf(_u("Leaf Bytes: %12llu\n"), (unsigned long long) walkLeafByteCount);
- wprintf(_u("Total Bytes: %12llu\n"), (unsigned long long) (walkScannedByteCount + walkBarrierByteCount + walkTrackedByteCount + walkLeafByteCount));
- wprintf(_u("Max Depth: %12llu\n"), (unsigned long long) maxWalkDepth);
- }
- // Virtual methods
- virtual bool TryGetRandomLocation(Location * location)
- {
- // Return false to indicate no internal locations
- // Subclasses can override this to handle their internal locations as appropriate
- return false;
- }
- virtual void DoWalkObject() = 0;
- protected:
- // Global variables
-
- // This global variable contains the "generation" of GC objects
- // It is used to validate the correctness of GC objects
- // It is assigned initially during object creation, and
- // updated when we walk the entire object graph in TraverseAllObjects
- static size_t currentGeneration;
- // These globals contain statistical data generated by WalkAllReferences
- static size_t walkObjectCount;
- static size_t walkScannedByteCount;
- static size_t walkLeafByteCount;
- static size_t walkBarrierByteCount;
- static size_t walkTrackedByteCount;
- static size_t currentWalkDepth;
- static size_t maxWalkDepth;
- private:
- // Instance variables
-
- // See comments above re currentGeneration
- size_t generation;
- };
- template <unsigned int minCount, unsigned int maxCount>
- class LeafObject : public RecyclerTestObject
- {
- private:
- LeafObject(unsigned int count) :
- count(count)
- {
- for (unsigned int i = 0; i < count; i++)
- {
- data[i] = i;
- }
- }
-
- public:
- static RecyclerTestObject * New()
- {
- unsigned int count = minCount + GetRandomInteger(maxCount - minCount + 1);
-
- return RecyclerNewPlusLeaf(recyclerInstance, sizeof(size_t) * count, LeafObject, count);
- }
- protected:
- virtual void DoWalkObject() override
- {
- walkLeafByteCount += sizeof(LeafObject) + count * sizeof(size_t);
- }
- private:
- unsigned int count;
- size_t data[0];
- };
- template <unsigned int minCount, unsigned int maxCount>
- class ScannedObject : public RecyclerTestObject
- {
- private:
- ScannedObject(unsigned int count) :
- count(count)
- {
- for (unsigned int i = 0; i < count; i++)
- {
- references[i] = nullptr;
- }
- }
-
- public:
- static RecyclerTestObject * New()
- {
- unsigned int count = minCount + GetRandomInteger(maxCount - minCount + 1);
-
- return RecyclerNewPlus(recyclerInstance, sizeof(RecyclerTestObject *) * count, ScannedObject, count);
- }
- virtual bool TryGetRandomLocation(Location * location) override
- {
- // Get a random slot and construct a Location for it
- *location = Location::Scanned(&references[GetRandomInteger(count)]);
- return true;
- }
- protected:
- virtual void DoWalkObject() override
- {
- walkScannedByteCount += sizeof(ScannedObject) + count * sizeof(RecyclerTestObject *);
- for (unsigned int i = 0; i < count; i++)
- {
- RecyclerTestObject::WalkReference(references[i]);
- }
- }
-
- private:
- unsigned int count;
- RecyclerTestObject * references[0];
- };
- template <unsigned int minCount, unsigned int maxCount>
- class BarrierObject : public RecyclerTestObject
- {
- private:
- BarrierObject(unsigned int count) :
- count(count)
- {
- for (unsigned int i = 0; i < count; i++)
- {
- references[i] = nullptr;
- }
- }
-
- public:
- static RecyclerTestObject * New()
- {
- unsigned int count = minCount + GetRandomInteger(maxCount - minCount + 1);
-
- return RecyclerNewWithBarrierPlus(recyclerInstance, sizeof(RecyclerTestObject *) * count, BarrierObject, count);
- }
- virtual bool TryGetRandomLocation(Location * location) override
- {
- // Get a random slot and construct a Location for it
- *location = Location::Barrier(&references[GetRandomInteger(count)]);
- return true;
- }
- protected:
- virtual void DoWalkObject() override
- {
- walkBarrierByteCount += sizeof(BarrierObject) + count * sizeof(RecyclerTestObject *);
- for (unsigned int i = 0; i < count; i++)
- {
- RecyclerTestObject::WalkReference(references[i]);
- }
- }
-
- private:
- unsigned int count;
- RecyclerTestObject * references[0];
- };
- template <unsigned int minCount, unsigned int maxCount>
- class TrackedObject : public RecyclerTestObject
- {
- private:
- TrackedObject(unsigned int count) :
- count(count)
- {
- for (unsigned int i = 0; i < count; i++)
- {
- references[i] = nullptr;
- }
- }
-
- public:
- static RecyclerTestObject * New()
- {
- unsigned int count = minCount + GetRandomInteger(maxCount - minCount + 1);
-
- return RecyclerNewTrackedLeafPlusZ(recyclerInstance, sizeof(RecyclerTestObject *) * count, TrackedObject, count);
- }
- virtual bool TryGetRandomLocation(Location * location) override
- {
- // Get a random slot and construct a Location for it
- *location = Location::Tagged(&references[GetRandomInteger(count)]);
- return true;
- }
- // Tracked object implementation
- virtual void Mark(Recycler * recycler) override
- {
- for (unsigned int i = 0; i < count; i++)
- {
- RecyclerTestObject * object = Location::Untag(references[i]);
- if (object != nullptr)
- {
- recycler->TryMarkNonInterior(object);
- }
- }
- };
- // Tracked objects are always finalize as well. Just do nothing.
- virtual void Finalize(bool isShutdown) override { }
- virtual void Dispose(bool isShutdown) override { };
-
-
- protected:
- virtual void DoWalkObject() override
- {
- walkTrackedByteCount += sizeof(TrackedObject) + count * sizeof(RecyclerTestObject *);
- for (unsigned int i = 0; i < count; i++)
- {
- RecyclerTestObject::WalkReference(Location::Untag(references[i]));
- }
- }
-
- private:
- unsigned int count;
- RecyclerTestObject * references[0];
- };
|