Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Unified Diff: src/global-handles.cc

Issue 260017: Implemented really weak handles. (Closed)
Patch Set: Fix typo. Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/global-handles.cc
diff --git a/src/global-handles.cc b/src/global-handles.cc
index e51c4aadf13d68bd581064f33628caf8bbf588d6..5ab9acb3c6db551fd081e361222e042a95b3de33 100644
--- a/src/global-handles.cc
+++ b/src/global-handles.cc
@@ -39,6 +39,7 @@ class GlobalHandles::Node : public Malloced {
void Initialize(Object* object) {
// Set the initial value of the handle.
object_ = object;
+ really_weak_ = false;
state_ = NORMAL;
parameter_or_next_free_.parameter = NULL;
callback_ = NULL;
@@ -63,9 +64,6 @@ class GlobalHandles::Node : public Malloced {
void Destroy() {
if (state_ == WEAK || IsNearDeath()) {
GlobalHandles::number_of_weak_handles_--;
- if (object_->IsJSGlobalObject()) {
- GlobalHandles::number_of_global_object_weak_handles_--;
- }
}
state_ = DESTROYED;
}
@@ -95,15 +93,14 @@ class GlobalHandles::Node : public Malloced {
Handle<Object> handle() { return Handle<Object>(&object_); }
// Make this handle weak.
- void MakeWeak(void* parameter, WeakReferenceCallback callback) {
+ void MakeWeak(void* parameter, WeakReferenceCallback callback,
Christian Plesner Hansen 2009/10/06 13:47:21 The 'callback' parameter should be moved to the ne
+ bool really_weak) {
LOG(HandleEvent("GlobalHandle::MakeWeak", handle().location()));
ASSERT(state_ != DESTROYED);
if (state_ != WEAK && !IsNearDeath()) {
GlobalHandles::number_of_weak_handles_++;
- if (object_->IsJSGlobalObject()) {
- GlobalHandles::number_of_global_object_weak_handles_++;
- }
}
+ really_weak_ = really_weak;
state_ = WEAK;
set_parameter(parameter);
callback_ = callback;
@@ -113,11 +110,12 @@ class GlobalHandles::Node : public Malloced {
LOG(HandleEvent("GlobalHandle::ClearWeakness", handle().location()));
ASSERT(state_ != DESTROYED);
if (state_ == WEAK || IsNearDeath()) {
+ // Can't clear weakness of near death really weak handle because
+ // the object may have been collected already.
+ ASSERT(!IsNearDeath() || !really_weak_);
Christian Plesner Hansen 2009/10/06 13:47:21 Are we sure this can't happen? Wouldn't it be saf
GlobalHandles::number_of_weak_handles_--;
- if (object_->IsJSGlobalObject()) {
- GlobalHandles::number_of_global_object_weak_handles_--;
- }
}
+ really_weak_ = false;
state_ = NORMAL;
set_parameter(NULL);
}
@@ -131,6 +129,10 @@ class GlobalHandles::Node : public Malloced {
return state_ == WEAK;
}
+ bool IsReallyWeak() {
+ return really_weak_;
+ }
+
// Returns the id for this weak handle.
void set_parameter(void* parameter) {
ASSERT(state_ != DESTROYED);
@@ -171,6 +173,8 @@ class GlobalHandles::Node : public Malloced {
// Place the handle address first to avoid offset computation.
Object* object_; // Storage for object pointer.
+ bool really_weak_ : 1;
+
// Transition diagram:
// NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, DESTROYED }
enum State {
@@ -180,7 +184,7 @@ class GlobalHandles::Node : public Malloced {
NEAR_DEATH, // Callback has informed the handle is near death.
DESTROYED
};
- State state_;
+ State state_ : 3;
private:
// Handle specific callback.
@@ -232,7 +236,14 @@ void GlobalHandles::Destroy(Object** location) {
void GlobalHandles::MakeWeak(Object** location, void* parameter,
WeakReferenceCallback callback) {
ASSERT(callback != NULL);
- Node::FromLocation(location)->MakeWeak(parameter, callback);
+ Node::FromLocation(location)->MakeWeak(parameter, callback, false);
+}
+
+
+void GlobalHandles::MakeReallyWeak(Object** location, void* parameter,
+ WeakReferenceCallback callback) {
+ ASSERT(callback != NULL);
+ Node::FromLocation(location)->MakeWeak(parameter, callback, true);
}
@@ -251,13 +262,19 @@ bool GlobalHandles::IsWeak(Object** location) {
}
+bool GlobalHandles::IsReallyWeak(Object** location) {
+ return Node::FromLocation(location)->IsReallyWeak();
+}
+
+
void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
// Traversal of GC roots in the global handle list that are marked as
// WEAK or PENDING.
for (Node* current = head_; current != NULL; current = current->next()) {
- if (current->state_ == Node::WEAK
- || current->state_ == Node::PENDING
- || current->state_ == Node::NEAR_DEATH) {
+ if (current->state_ == Node::WEAK ||
+ (!current->really_weak_ &&
+ (current->state_ == Node::PENDING ||
+ current->state_ == Node::NEAR_DEATH))) {
v->VisitPointer(&current->object_);
}
}
@@ -310,7 +327,7 @@ void GlobalHandles::PostGarbageCollectionProcessing() {
void GlobalHandles::IterateRoots(ObjectVisitor* v) {
- // Traversal of global handles marked as NORMAL or NEAR_DEATH.
+ // Traversal of global handles marked as NORMAL.
for (Node* current = head_; current != NULL; current = current->next()) {
if (current->state_ == Node::NORMAL) {
v->VisitPointer(&current->object_);
@@ -333,7 +350,6 @@ void GlobalHandles::TearDown() {
int GlobalHandles::number_of_weak_handles_ = 0;
-int GlobalHandles::number_of_global_object_weak_handles_ = 0;
GlobalHandles::Node* GlobalHandles::head_ = NULL;
GlobalHandles::Node* GlobalHandles::first_free_ = NULL;
@@ -380,6 +396,7 @@ List<ObjectGroup*>* GlobalHandles::ObjectGroups() {
return &groups;
}
+
void GlobalHandles::AddGroup(Object*** handles, size_t length) {
ObjectGroup* new_entry = new ObjectGroup(length);
for (size_t i = 0; i < length; ++i)
@@ -390,7 +407,7 @@ void GlobalHandles::AddGroup(Object*** handles, size_t length) {
void GlobalHandles::RemoveObjectGroups() {
List<ObjectGroup*>* object_groups = ObjectGroups();
- for (int i = 0; i< object_groups->length(); i++) {
+ for (int i = 0; i < object_groups->length(); ++i) {
Christian Plesner Hansen 2009/10/06 13:47:21 Changing from i++ to ++i shouldn't make any differ
delete object_groups->at(i);
}
object_groups->Clear();

Powered by Google App Engine
This is Rietveld 408576698