// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #ifndef RUNTIME_VM_OBJECT_ID_RING_H_ #define RUNTIME_VM_OBJECT_ID_RING_H_ #include "platform/globals.h" #include "vm/tagged_pointer.h" namespace dart { // Forward declarations. class ObjectPointerVisitor; class JSONStream; // A ring buffer of object pointers that have been given temporary Service IDs. // An object may be pointed to by multiple IDs. The objects associated with the // pointers in the ring will be preserved across garbage collections. When the // ring buffer wraps around, older objects will be replaced and their IDs will // become expired. class ObjectIdRing { public: enum LookupResult { kValid = 0, kInvalid, // Malformed ring id (used in service.cc). kCollected, // Entry was reclaimed due to a full GC (entries are weak). kExpired, // Entry was evicted during an insertion into a full ring. }; enum BackingBufferKind { kRing, }; enum IdPolicy { kAllocateId, // Always allocate a new object id. kReuseId, // If the object is already in the ring, reuse id. // Otherwise allocate a new object id. }; static constexpr int32_t kMaxId = 0x3FFFFFFF; static constexpr int32_t kInvalidId = -1; explicit ObjectIdRing(int32_t capacity); ~ObjectIdRing(); // Invalidate all the Service IDs currently living in this ring. void Invalidate(); // Adds the argument to the ring and returns its id. Note we do not allow // adding Object::null(). int32_t GetIdForObject(ObjectPtr raw_obj, IdPolicy policy = kAllocateId); // Returns Object::null() when the result is not kValid. ObjectPtr GetObjectForId(int32_t id, LookupResult* kind); void VisitPointers(ObjectPointerVisitor* visitor) const; void PrintJSON(JSONStream* js); private: friend class ObjectIdRingTestHelper; void SetCapacityAndMaxSerial(int32_t capacity, int32_t max_serial); int32_t FindExistingIdForObject(ObjectPtr raw_obj); ObjectPtr* table_; int32_t max_serial_; int32_t capacity_; int32_t serial_num_; bool wrapped_; ObjectPtr* table() { return table_; } int32_t table_size() { return capacity_; } int32_t NextSerial(); int32_t AllocateNewId(ObjectPtr object); int32_t IndexOfId(int32_t id); int32_t IdOfIndex(int32_t index); bool IsValidContiguous(int32_t id) const; bool IsValidId(int32_t id); DISALLOW_COPY_AND_ASSIGN(ObjectIdRing); }; } // namespace dart #endif // RUNTIME_VM_OBJECT_ID_RING_H_