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

Side by Side Diff: src/global-handles.cc

Issue 649563006: Introduce phantom weak handles in the API and use them internally for debug info (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/global-handles.h" 8 #include "src/global-handles.h"
9 9
10 #include "src/vm-state-inl.h" 10 #include "src/vm-state-inl.h"
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 flags_ = IsPartiallyDependent::update(flags_, v); 139 flags_ = IsPartiallyDependent::update(flags_, v);
140 } 140 }
141 141
142 bool is_in_new_space_list() { 142 bool is_in_new_space_list() {
143 return IsInNewSpaceList::decode(flags_); 143 return IsInNewSpaceList::decode(flags_);
144 } 144 }
145 void set_in_new_space_list(bool v) { 145 void set_in_new_space_list(bool v) {
146 flags_ = IsInNewSpaceList::update(flags_, v); 146 flags_ = IsInNewSpaceList::update(flags_, v);
147 } 147 }
148 148
149 bool is_zapped_during_weak_callback() {
150 return IsZappedDuringWeakCallback::decode(flags_);
151 }
152 void set_is_zapped_during_weak_callback(bool v) {
153 flags_ = IsZappedDuringWeakCallback::update(flags_, v);
154 }
155
149 bool IsNearDeath() const { 156 bool IsNearDeath() const {
150 // Check for PENDING to ensure correct answer when processing callbacks. 157 // Check for PENDING to ensure correct answer when processing callbacks.
151 return state() == PENDING || state() == NEAR_DEATH; 158 return state() == PENDING || state() == NEAR_DEATH;
152 } 159 }
153 160
154 bool IsWeak() const { return state() == WEAK; } 161 bool IsWeak() const { return state() == WEAK; }
155 162
156 bool IsRetainer() const { return state() != FREE; } 163 bool IsRetainer() const { return state() != FREE; }
157 164
158 bool IsStrongRetainer() const { return state() == NORMAL; } 165 bool IsStrongRetainer() const { return state() == NORMAL; }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 // Accessors for next free node in the free list. 204 // Accessors for next free node in the free list.
198 Node* next_free() { 205 Node* next_free() {
199 DCHECK(state() == FREE); 206 DCHECK(state() == FREE);
200 return parameter_or_next_free_.next_free; 207 return parameter_or_next_free_.next_free;
201 } 208 }
202 void set_next_free(Node* value) { 209 void set_next_free(Node* value) {
203 DCHECK(state() == FREE); 210 DCHECK(state() == FREE);
204 parameter_or_next_free_.next_free = value; 211 parameter_or_next_free_.next_free = value;
205 } 212 }
206 213
207 void MakeWeak(void* parameter, WeakCallback weak_callback) { 214 void MakeWeak(void* parameter, WeakCallback weak_callback,
215 bool is_zapped_during_weak_callback = false) {
208 DCHECK(weak_callback != NULL); 216 DCHECK(weak_callback != NULL);
209 DCHECK(state() != FREE); 217 DCHECK(state() != FREE);
210 CHECK(object_ != NULL); 218 CHECK(object_ != NULL);
211 set_state(WEAK); 219 set_state(WEAK);
212 set_parameter(parameter); 220 set_parameter(parameter);
221 set_is_zapped_during_weak_callback(is_zapped_during_weak_callback);
213 weak_callback_ = weak_callback; 222 weak_callback_ = weak_callback;
214 } 223 }
215 224
216 void* ClearWeakness() { 225 void* ClearWeakness() {
217 DCHECK(state() != FREE); 226 DCHECK(state() != FREE);
218 void* p = parameter(); 227 void* p = parameter();
219 set_state(NORMAL); 228 set_state(NORMAL);
220 set_parameter(NULL); 229 set_parameter(NULL);
221 return p; 230 return p;
222 } 231 }
223 232
224 bool PostGarbageCollectionProcessing(Isolate* isolate) { 233 bool PostGarbageCollectionProcessing(Isolate* isolate) {
225 if (state() != Node::PENDING) return false; 234 if (state() != Node::PENDING) return false;
226 if (weak_callback_ == NULL) { 235 if (weak_callback_ == NULL) {
227 Release(); 236 Release();
228 return false; 237 return false;
229 } 238 }
230 void* par = parameter(); 239 void* param = parameter();
231 set_state(NEAR_DEATH); 240 set_state(NEAR_DEATH);
232 set_parameter(NULL); 241 set_parameter(NULL);
233 242
234 Object** object = location(); 243 Object** object = location();
235 { 244 {
236 // Check that we are not passing a finalized external string to 245 // Check that we are not passing a finalized external string to
237 // the callback. 246 // the callback.
238 DCHECK(!object_->IsExternalOneByteString() || 247 DCHECK(!object_->IsExternalOneByteString() ||
239 ExternalOneByteString::cast(object_)->resource() != NULL); 248 ExternalOneByteString::cast(object_)->resource() != NULL);
240 DCHECK(!object_->IsExternalTwoByteString() || 249 DCHECK(!object_->IsExternalTwoByteString() ||
241 ExternalTwoByteString::cast(object_)->resource() != NULL); 250 ExternalTwoByteString::cast(object_)->resource() != NULL);
242 // Leaving V8. 251 // Leaving V8.
243 VMState<EXTERNAL> state(isolate); 252 VMState<EXTERNAL> state(isolate);
244 HandleScope handle_scope(isolate); 253 HandleScope handle_scope(isolate);
245 Handle<Object> handle(*object, isolate); 254 Handle<Object> handle(*object, isolate);
255 if (is_zapped_during_weak_callback()) {
256 DCHECK(*handle == Smi::FromInt(kPhantomReferenceZap));
257 }
246 v8::WeakCallbackData<v8::Value, void> data( 258 v8::WeakCallbackData<v8::Value, void> data(
247 reinterpret_cast<v8::Isolate*>(isolate), 259 reinterpret_cast<v8::Isolate*>(isolate), v8::Utils::ToLocal(handle),
248 v8::Utils::ToLocal(handle), 260 param);
249 par);
250 weak_callback_(data); 261 weak_callback_(data);
251 } 262 }
252 // Absence of explicit cleanup or revival of weak handle 263 // Absence of explicit cleanup or revival of weak handle
253 // in most of the cases would lead to memory leak. 264 // in most of the cases would lead to memory leak.
254 CHECK(state() != NEAR_DEATH); 265 CHECK(state() != NEAR_DEATH);
255 return true; 266 return true;
256 } 267 }
257 268
258 inline GlobalHandles* GetGlobalHandles(); 269 inline GlobalHandles* GetGlobalHandles();
259 270
(...skipping 10 matching lines...) Expand all
270 // Note: the most aligned fields should go first. 281 // Note: the most aligned fields should go first.
271 282
272 // Wrapper class ID. 283 // Wrapper class ID.
273 uint16_t class_id_; 284 uint16_t class_id_;
274 285
275 // Index in the containing handle block. 286 // Index in the containing handle block.
276 uint8_t index_; 287 uint8_t index_;
277 288
278 // This stores three flags (independent, partially_dependent and 289 // This stores three flags (independent, partially_dependent and
279 // in_new_space_list) and a State. 290 // in_new_space_list) and a State.
280 class NodeState: public BitField<State, 0, 4> {}; 291 class NodeState : public BitField<State, 0, 4> {};
281 class IsIndependent: public BitField<bool, 4, 1> {}; 292 class IsIndependent : public BitField<bool, 4, 1> {};
282 class IsPartiallyDependent: public BitField<bool, 5, 1> {}; 293 class IsPartiallyDependent : public BitField<bool, 5, 1> {};
283 class IsInNewSpaceList: public BitField<bool, 6, 1> {}; 294 class IsInNewSpaceList : public BitField<bool, 6, 1> {};
295 class IsZappedDuringWeakCallback : public BitField<bool, 7, 1> {};
284 296
285 uint8_t flags_; 297 uint8_t flags_;
286 298
287 // Handle specific callback - might be a weak reference in disguise. 299 // Handle specific callback - might be a weak reference in disguise.
288 WeakCallback weak_callback_; 300 WeakCallback weak_callback_;
289 301
290 // Provided data for callback. In FREE state, this is used for 302 // Provided data for callback. In FREE state, this is used for
291 // the free list link. 303 // the free list link.
292 union { 304 union {
293 void* parameter; 305 void* parameter;
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 DCHECK(location != NULL); 480 DCHECK(location != NULL);
469 return Node::FromLocation(location)->GetGlobalHandles()->Create(*location); 481 return Node::FromLocation(location)->GetGlobalHandles()->Create(*location);
470 } 482 }
471 483
472 484
473 void GlobalHandles::Destroy(Object** location) { 485 void GlobalHandles::Destroy(Object** location) {
474 if (location != NULL) Node::FromLocation(location)->Release(); 486 if (location != NULL) Node::FromLocation(location)->Release();
475 } 487 }
476 488
477 489
478 void GlobalHandles::MakeWeak(Object** location, 490 void GlobalHandles::MakeWeak(Object** location, void* parameter,
479 void* parameter, 491 WeakCallback weak_callback, PhantomState phantom) {
480 WeakCallback weak_callback) { 492 Node::FromLocation(location)
481 Node::FromLocation(location)->MakeWeak(parameter, weak_callback); 493 ->MakeWeak(parameter, weak_callback, phantom == Phantom);
482 } 494 }
483 495
484 496
485 void* GlobalHandles::ClearWeakness(Object** location) { 497 void* GlobalHandles::ClearWeakness(Object** location) {
486 return Node::FromLocation(location)->ClearWeakness(); 498 return Node::FromLocation(location)->ClearWeakness();
487 } 499 }
488 500
489 501
490 void GlobalHandles::MarkIndependent(Object** location) { 502 void GlobalHandles::MarkIndependent(Object** location) {
491 Node::FromLocation(location)->MarkIndependent(); 503 Node::FromLocation(location)->MarkIndependent();
(...skipping 15 matching lines...) Expand all
507 } 519 }
508 520
509 521
510 bool GlobalHandles::IsWeak(Object** location) { 522 bool GlobalHandles::IsWeak(Object** location) {
511 return Node::FromLocation(location)->IsWeak(); 523 return Node::FromLocation(location)->IsWeak();
512 } 524 }
513 525
514 526
515 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { 527 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
516 for (NodeIterator it(this); !it.done(); it.Advance()) { 528 for (NodeIterator it(this); !it.done(); it.Advance()) {
517 if (it.node()->IsWeakRetainer()) v->VisitPointer(it.node()->location()); 529 if (it.node()->IsWeakRetainer()) {
530 if (it.node()->state() == Node::PENDING &&
531 it.node()->is_zapped_during_weak_callback()) {
532 *(it.node()->location()) = Smi::FromInt(kPhantomReferenceZap);
533 } else {
534 v->VisitPointer(it.node()->location());
535 }
536 }
518 } 537 }
519 } 538 }
520 539
521 540
522 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) { 541 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) {
523 for (NodeIterator it(this); !it.done(); it.Advance()) { 542 for (NodeIterator it(this); !it.done(); it.Advance()) {
524 if (it.node()->IsWeak() && f(it.node()->location())) { 543 if (it.node()->IsWeak() && f(it.node()->location())) {
525 it.node()->MarkPending(); 544 it.node()->MarkPending();
526 } 545 }
527 } 546 }
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 DCHECK_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); 1066 DCHECK_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]);
1048 blocks_[block][offset] = object; 1067 blocks_[block][offset] = object;
1049 if (isolate->heap()->InNewSpace(object)) { 1068 if (isolate->heap()->InNewSpace(object)) {
1050 new_space_indices_.Add(size_); 1069 new_space_indices_.Add(size_);
1051 } 1070 }
1052 *index = size_++; 1071 *index = size_++;
1053 } 1072 }
1054 1073
1055 1074
1056 } } // namespace v8::internal 1075 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698