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

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: Rebase Created 6 years, 1 month 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
« no previous file with comments | « src/global-handles.h ('k') | src/globals.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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> vmstate(isolate);
244 HandleScope handle_scope(isolate); 253 HandleScope handle_scope(isolate);
245 Handle<Object> handle(*object, isolate); 254 if (is_zapped_during_weak_callback()) {
246 v8::WeakCallbackData<v8::Value, void> data( 255 // Phantom weak pointer case.
247 reinterpret_cast<v8::Isolate*>(isolate), 256 DCHECK(*object == Smi::FromInt(kPhantomReferenceZap));
248 v8::Utils::ToLocal(handle), 257 // Make data with a null handle.
249 par); 258 v8::WeakCallbackData<v8::Value, void> data(
250 weak_callback_(data); 259 reinterpret_cast<v8::Isolate*>(isolate), v8::Local<v8::Object>(),
260 param);
261 weak_callback_(data);
262 if (state() != FREE) {
263 // Callback does not have to clear the global handle if it is a
264 // phantom handle.
265 Release();
266 }
267 } else {
268 Handle<Object> handle(object);
269 v8::WeakCallbackData<v8::Value, void> data(
270 reinterpret_cast<v8::Isolate*>(isolate), v8::Utils::ToLocal(handle),
271 param);
272 weak_callback_(data);
273 }
251 } 274 }
252 // Absence of explicit cleanup or revival of weak handle 275 // Absence of explicit cleanup or revival of weak handle
253 // in most of the cases would lead to memory leak. 276 // in most of the cases would lead to memory leak.
254 CHECK(state() != NEAR_DEATH); 277 CHECK(state() != NEAR_DEATH);
255 return true; 278 return true;
256 } 279 }
257 280
258 inline GlobalHandles* GetGlobalHandles(); 281 inline GlobalHandles* GetGlobalHandles();
259 282
260 private: 283 private:
261 inline NodeBlock* FindBlock(); 284 inline NodeBlock* FindBlock();
262 inline void IncreaseBlockUses(); 285 inline void IncreaseBlockUses();
263 inline void DecreaseBlockUses(); 286 inline void DecreaseBlockUses();
264 287
265 // Storage for object pointer. 288 // Storage for object pointer.
266 // Placed first to avoid offset computation. 289 // Placed first to avoid offset computation.
267 Object* object_; 290 Object* object_;
268 291
269 // Next word stores class_id, index, state, and independent. 292 // Next word stores class_id, index, state, and independent.
270 // Note: the most aligned fields should go first. 293 // Note: the most aligned fields should go first.
271 294
272 // Wrapper class ID. 295 // Wrapper class ID.
273 uint16_t class_id_; 296 uint16_t class_id_;
274 297
275 // Index in the containing handle block. 298 // Index in the containing handle block.
276 uint8_t index_; 299 uint8_t index_;
277 300
278 // This stores three flags (independent, partially_dependent and 301 // This stores three flags (independent, partially_dependent and
279 // in_new_space_list) and a State. 302 // in_new_space_list) and a State.
280 class NodeState: public BitField<State, 0, 4> {}; 303 class NodeState : public BitField<State, 0, 4> {};
281 class IsIndependent: public BitField<bool, 4, 1> {}; 304 class IsIndependent : public BitField<bool, 4, 1> {};
282 class IsPartiallyDependent: public BitField<bool, 5, 1> {}; 305 class IsPartiallyDependent : public BitField<bool, 5, 1> {};
283 class IsInNewSpaceList: public BitField<bool, 6, 1> {}; 306 class IsInNewSpaceList : public BitField<bool, 6, 1> {};
307 class IsZappedDuringWeakCallback : public BitField<bool, 7, 1> {};
284 308
285 uint8_t flags_; 309 uint8_t flags_;
286 310
287 // Handle specific callback - might be a weak reference in disguise. 311 // Handle specific callback - might be a weak reference in disguise.
288 WeakCallback weak_callback_; 312 WeakCallback weak_callback_;
289 313
290 // Provided data for callback. In FREE state, this is used for 314 // Provided data for callback. In FREE state, this is used for
291 // the free list link. 315 // the free list link.
292 union { 316 union {
293 void* parameter; 317 void* parameter;
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 DCHECK(location != NULL); 492 DCHECK(location != NULL);
469 return Node::FromLocation(location)->GetGlobalHandles()->Create(*location); 493 return Node::FromLocation(location)->GetGlobalHandles()->Create(*location);
470 } 494 }
471 495
472 496
473 void GlobalHandles::Destroy(Object** location) { 497 void GlobalHandles::Destroy(Object** location) {
474 if (location != NULL) Node::FromLocation(location)->Release(); 498 if (location != NULL) Node::FromLocation(location)->Release();
475 } 499 }
476 500
477 501
478 void GlobalHandles::MakeWeak(Object** location, 502 void GlobalHandles::MakeWeak(Object** location, void* parameter,
479 void* parameter, 503 WeakCallback weak_callback, PhantomState phantom) {
480 WeakCallback weak_callback) { 504 Node::FromLocation(location)
481 Node::FromLocation(location)->MakeWeak(parameter, weak_callback); 505 ->MakeWeak(parameter, weak_callback, phantom == Phantom);
482 } 506 }
483 507
484 508
485 void* GlobalHandles::ClearWeakness(Object** location) { 509 void* GlobalHandles::ClearWeakness(Object** location) {
486 return Node::FromLocation(location)->ClearWeakness(); 510 return Node::FromLocation(location)->ClearWeakness();
487 } 511 }
488 512
489 513
490 void GlobalHandles::MarkIndependent(Object** location) { 514 void GlobalHandles::MarkIndependent(Object** location) {
491 Node::FromLocation(location)->MarkIndependent(); 515 Node::FromLocation(location)->MarkIndependent();
(...skipping 15 matching lines...) Expand all
507 } 531 }
508 532
509 533
510 bool GlobalHandles::IsWeak(Object** location) { 534 bool GlobalHandles::IsWeak(Object** location) {
511 return Node::FromLocation(location)->IsWeak(); 535 return Node::FromLocation(location)->IsWeak();
512 } 536 }
513 537
514 538
515 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { 539 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
516 for (NodeIterator it(this); !it.done(); it.Advance()) { 540 for (NodeIterator it(this); !it.done(); it.Advance()) {
517 if (it.node()->IsWeakRetainer()) v->VisitPointer(it.node()->location()); 541 Node* node = it.node();
542 if (node->IsWeakRetainer()) {
543 if (node->state() == Node::PENDING &&
544 node->is_zapped_during_weak_callback()) {
545 *(node->location()) = Smi::FromInt(kPhantomReferenceZap);
546 } else {
547 v->VisitPointer(node->location());
548 }
549 }
518 } 550 }
519 } 551 }
520 552
521 553
522 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) { 554 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) {
523 for (NodeIterator it(this); !it.done(); it.Advance()) { 555 for (NodeIterator it(this); !it.done(); it.Advance()) {
524 if (it.node()->IsWeak() && f(it.node()->location())) { 556 if (it.node()->IsWeak() && f(it.node()->location())) {
525 it.node()->MarkPending(); 557 it.node()->MarkPending();
526 } 558 }
527 } 559 }
(...skipping 24 matching lines...) Expand all
552 } 584 }
553 } 585 }
554 586
555 587
556 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { 588 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
557 for (int i = 0; i < new_space_nodes_.length(); ++i) { 589 for (int i = 0; i < new_space_nodes_.length(); ++i) {
558 Node* node = new_space_nodes_[i]; 590 Node* node = new_space_nodes_[i];
559 DCHECK(node->is_in_new_space_list()); 591 DCHECK(node->is_in_new_space_list());
560 if ((node->is_independent() || node->is_partially_dependent()) && 592 if ((node->is_independent() || node->is_partially_dependent()) &&
561 node->IsWeakRetainer()) { 593 node->IsWeakRetainer()) {
562 v->VisitPointer(node->location()); 594 if (node->is_zapped_during_weak_callback()) {
595 *(node->location()) = Smi::FromInt(kPhantomReferenceZap);
596 } else {
597 v->VisitPointer(node->location());
598 }
563 } 599 }
564 } 600 }
565 } 601 }
566 602
567 603
568 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, 604 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
569 WeakSlotCallbackWithHeap can_skip) { 605 WeakSlotCallbackWithHeap can_skip) {
570 ComputeObjectGroupsAndImplicitReferences(); 606 ComputeObjectGroupsAndImplicitReferences();
571 int last = 0; 607 int last = 0;
572 bool any_group_was_visited = false; 608 bool any_group_was_visited = false;
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
1047 DCHECK_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); 1083 DCHECK_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]);
1048 blocks_[block][offset] = object; 1084 blocks_[block][offset] = object;
1049 if (isolate->heap()->InNewSpace(object)) { 1085 if (isolate->heap()->InNewSpace(object)) {
1050 new_space_indices_.Add(size_); 1086 new_space_indices_.Add(size_);
1051 } 1087 }
1052 *index = size_++; 1088 *index = size_++;
1053 } 1089 }
1054 1090
1055 1091
1056 } } // namespace v8::internal 1092 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/global-handles.h ('k') | src/globals.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698