| // 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 an id. An object |
| // may be pointed to by multiple ids. Objects contained in the ring will |
| // be preserved across scavenges but not old space collections. |
| // When the ring buffer wraps around older objects will be replaced and their |
| // ids will be invalidated. |
| 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 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. |
| kNumIdPolicy, |
| }; |
| |
| static const int32_t kMaxId = 0x3FFFFFFF; |
| static const int32_t kInvalidId = -1; |
| static const int32_t kDefaultCapacity = 8192; |
| |
| ObjectIdRing(); |
| ~ObjectIdRing(); |
| |
| // 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); |
| |
| 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); |
| bool IsValidId(int32_t id); |
| |
| DISALLOW_COPY_AND_ASSIGN(ObjectIdRing); |
| }; |
| |
| } // namespace dart |
| |
| #endif // RUNTIME_VM_OBJECT_ID_RING_H_ |