mirror of
https://github.com/dart-lang/sdk
synced 2024-09-22 09:32:59 +00:00
058510ebd0
Prints <collected> or <expired>. Added tooltips to explain these to users. R=johnmccutchan@google.com Review URL: https://codereview.chromium.org//177473004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@33386 260f80e4-7a28-3924-810f-c04153c831b5
169 lines
4.1 KiB
C++
169 lines
4.1 KiB
C++
// 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.
|
|
|
|
#include "platform/assert.h"
|
|
#include "vm/dart_api_state.h"
|
|
#include "vm/object_id_ring.h"
|
|
|
|
namespace dart {
|
|
|
|
void ObjectIdRing::Init(Isolate* isolate, int32_t capacity) {
|
|
ObjectIdRing* ring = new ObjectIdRing(isolate, capacity);
|
|
isolate->set_object_id_ring(ring);
|
|
}
|
|
|
|
|
|
ObjectIdRing::~ObjectIdRing() {
|
|
ASSERT(table_ != NULL);
|
|
free(table_);
|
|
table_ = NULL;
|
|
if (isolate_ != NULL) {
|
|
isolate_->set_object_id_ring(NULL);
|
|
isolate_ = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
int32_t ObjectIdRing::GetIdForObject(RawObject* object) {
|
|
return AllocateNewId(object);
|
|
}
|
|
|
|
|
|
RawObject* ObjectIdRing::GetObjectForId(int32_t id) {
|
|
int32_t index = IndexOfId(id);
|
|
if (index == kInvalidId) {
|
|
// Return sentinel to allow caller to distinguish expired ids.
|
|
return Object::sentinel().raw();
|
|
}
|
|
ASSERT(index >= 0);
|
|
ASSERT(index < capacity_);
|
|
return table_[index];
|
|
}
|
|
|
|
|
|
void ObjectIdRing::VisitPointers(ObjectPointerVisitor* visitor) {
|
|
ASSERT(table_ != NULL);
|
|
visitor->VisitPointers(table_, capacity_);
|
|
}
|
|
|
|
|
|
ObjectIdRing::ObjectIdRing(Isolate* isolate, int32_t capacity) {
|
|
ASSERT(capacity > 0);
|
|
isolate_ = isolate;
|
|
serial_num_ = 0;
|
|
wrapped_ = false;
|
|
table_ = NULL;
|
|
SetCapacityAndMaxSerial(capacity, kMaxId);
|
|
}
|
|
|
|
|
|
void ObjectIdRing::SetCapacityAndMaxSerial(int32_t capacity,
|
|
int32_t max_serial) {
|
|
ASSERT(max_serial <= kMaxId);
|
|
capacity_ = capacity;
|
|
if (table_ != NULL) {
|
|
free(table_);
|
|
}
|
|
table_ = reinterpret_cast<RawObject**>(calloc(capacity_, kWordSize));
|
|
for (int i = 0; i < capacity_; i++) {
|
|
table_[i] = Object::null();
|
|
}
|
|
// The maximum serial number is a multiple of the capacity, so that when
|
|
// the serial number wraps, the index into table_ wraps with it.
|
|
max_serial_ = max_serial - (max_serial % capacity_);
|
|
}
|
|
|
|
|
|
int32_t ObjectIdRing::NextSerial() {
|
|
int32_t r = serial_num_;
|
|
serial_num_++;
|
|
if (serial_num_ >= max_serial_) {
|
|
serial_num_ = 0;
|
|
wrapped_ = true;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
|
|
int32_t ObjectIdRing::AllocateNewId(RawObject* raw_obj) {
|
|
ASSERT(raw_obj->IsHeapObject());
|
|
int32_t id = NextSerial();
|
|
ASSERT(id != kInvalidId);
|
|
int32_t cursor = IndexOfId(id);
|
|
ASSERT(cursor != kInvalidId);
|
|
if (table_[cursor] != Object::null()) {
|
|
// Free old handle.
|
|
table_[cursor] = Object::null();
|
|
}
|
|
ASSERT(table_[cursor] == Object::null());
|
|
table_[cursor] = raw_obj;
|
|
return id;
|
|
}
|
|
|
|
|
|
int32_t ObjectIdRing::IndexOfId(int32_t id) {
|
|
if (!IsValidId(id)) {
|
|
return kInvalidId;
|
|
}
|
|
ASSERT((id >= 0) && (id < max_serial_));
|
|
return id % capacity_;
|
|
}
|
|
|
|
|
|
bool ObjectIdRing::IsValidContiguous(int32_t id) {
|
|
ASSERT(id != kInvalidId);
|
|
ASSERT((id >= 0) && (id < max_serial_));
|
|
if (id >= serial_num_) {
|
|
// Too large.
|
|
return false;
|
|
}
|
|
int32_t bottom = 0;
|
|
if (serial_num_ >= capacity_) {
|
|
bottom = serial_num_ - capacity_;
|
|
}
|
|
return id >= bottom;
|
|
}
|
|
|
|
|
|
bool ObjectIdRing::IsValidId(int32_t id) {
|
|
if (id == kInvalidId) {
|
|
return false;
|
|
}
|
|
if (id < 0) {
|
|
return false;
|
|
}
|
|
if (id >= max_serial_) {
|
|
return false;
|
|
}
|
|
ASSERT((id >= 0) && (id < max_serial_));
|
|
if (wrapped_) {
|
|
// Serial number has wrapped around to 0.
|
|
if (serial_num_ >= capacity_) {
|
|
// Serial number is larger than capacity, the serial
|
|
// numbers are contiguous again.
|
|
wrapped_ = false;
|
|
return IsValidContiguous(id);
|
|
} else {
|
|
// When the serial number first wraps, the valid serial number range
|
|
// spans two intervals:
|
|
// #1 [0, serial_num_)
|
|
// #2 [max_serial_ - (capacity_ - serial_num), max_serial_)
|
|
//
|
|
// Check for both.
|
|
if (id < serial_num_) {
|
|
// Interval #1
|
|
return true;
|
|
}
|
|
// Interval #2
|
|
const int32_t max_serial_num = max_serial_;
|
|
const int32_t bottom = max_serial_num - (capacity_ - serial_num_);
|
|
return id >= bottom && bottom < max_serial_num;
|
|
}
|
|
}
|
|
ASSERT(wrapped_ == false);
|
|
return IsValidContiguous(id);
|
|
}
|
|
|
|
} // namespace dart
|