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

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

Issue 753553002: Phantom references support internal fields (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Don't forget to visit pointers to live objects so they can be updated to new location Created 6 years 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
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 12 matching lines...) Expand all
23 delete[] children; 23 delete[] children;
24 } 24 }
25 25
26 26
27 class GlobalHandles::Node { 27 class GlobalHandles::Node {
28 public: 28 public:
29 // State transition diagram: 29 // State transition diagram:
30 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE } 30 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE }
31 enum State { 31 enum State {
32 FREE = 0, 32 FREE = 0,
33 NORMAL, // Normal global handle. 33 NORMAL, // Normal global handle.
34 WEAK, // Flagged as weak but not yet finalized. 34 WEAK, // Flagged as weak but not yet finalized.
35 PENDING, // Has been recognized as only reachable by weak handles. 35 PENDING, // Has been recognized as only reachable by weak handles.
36 NEAR_DEATH // Callback has informed the handle is near death. 36 NEAR_DEATH, // Callback has informed the handle is near death.
37 NUMBER_OF_NODE_STATES
38 };
39
40 enum WeaknessType {
41 NORMAL_WEAK, // Embedder gets a handle to the dying object.
42 PHANTOM_WEAK, // Embedder gets the parameter they passed in earlier.
43 INTERNAL_FIELDS_WEAK // Embedded gets 2 internal fields from dying object.
37 }; 44 };
38 45
39 // Maps handle location (slot) to the containing node. 46 // Maps handle location (slot) to the containing node.
40 static Node* FromLocation(Object** location) { 47 static Node* FromLocation(Object** location) {
41 DCHECK(OFFSET_OF(Node, object_) == 0); 48 DCHECK(OFFSET_OF(Node, object_) == 0);
42 return reinterpret_cast<Node*>(location); 49 return reinterpret_cast<Node*>(location);
43 } 50 }
44 51
45 Node() { 52 Node() {
46 DCHECK(OFFSET_OF(Node, class_id_) == Internals::kNodeClassIdOffset); 53 DCHECK(OFFSET_OF(Node, class_id_) == Internals::kNodeClassIdOffset);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 object_ = object; 92 object_ = object;
86 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 93 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
87 set_independent(false); 94 set_independent(false);
88 set_partially_dependent(false); 95 set_partially_dependent(false);
89 set_state(NORMAL); 96 set_state(NORMAL);
90 parameter_or_next_free_.parameter = NULL; 97 parameter_or_next_free_.parameter = NULL;
91 weak_callback_ = NULL; 98 weak_callback_ = NULL;
92 IncreaseBlockUses(); 99 IncreaseBlockUses();
93 } 100 }
94 101
102 void Zap() {
picksi1 2014/11/28 12:15:11 Is 'Zap' a known term in the world of GC? For the
Erik Corry 2014/11/28 14:21:25 It's pretty well established, I think.
103 DCHECK(state() != FREE);
104 // Zap the values for eager trapping.
105 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
106 }
107
95 void Release() { 108 void Release() {
96 DCHECK(state() != FREE); 109 DCHECK(state() != FREE);
97 set_state(FREE); 110 set_state(FREE);
98 // Zap the values for eager trapping. 111 // Zap the values for eager trapping.
99 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue); 112 object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
100 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId; 113 class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
101 set_independent(false); 114 set_independent(false);
102 set_partially_dependent(false); 115 set_partially_dependent(false);
103 weak_callback_ = NULL; 116 weak_callback_ = NULL;
104 DecreaseBlockUses(); 117 DecreaseBlockUses();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 flags_ = IsPartiallyDependent::update(flags_, v); 152 flags_ = IsPartiallyDependent::update(flags_, v);
140 } 153 }
141 154
142 bool is_in_new_space_list() { 155 bool is_in_new_space_list() {
143 return IsInNewSpaceList::decode(flags_); 156 return IsInNewSpaceList::decode(flags_);
144 } 157 }
145 void set_in_new_space_list(bool v) { 158 void set_in_new_space_list(bool v) {
146 flags_ = IsInNewSpaceList::update(flags_, v); 159 flags_ = IsInNewSpaceList::update(flags_, v);
147 } 160 }
148 161
149 bool is_zapped_during_weak_callback() { 162 WeaknessType weakness_type() const {
150 return IsZappedDuringWeakCallback::decode(flags_); 163 return NodeWeaknessType::decode(flags_);
151 } 164 }
152 void set_is_zapped_during_weak_callback(bool v) { 165 void set_weakness_type(WeaknessType t) {
153 flags_ = IsZappedDuringWeakCallback::update(flags_, v); 166 flags_ = NodeWeaknessType::update(flags_, t);
picksi1 2014/11/28 12:15:11 is t a good variable name here? should it be weakn
Erik Corry 2014/11/28 14:21:25 Done.
154 } 167 }
155 168
156 bool IsNearDeath() const { 169 bool IsNearDeath() const {
157 // Check for PENDING to ensure correct answer when processing callbacks. 170 // Check for PENDING to ensure correct answer when processing callbacks.
158 return state() == PENDING || state() == NEAR_DEATH; 171 return state() == PENDING || state() == NEAR_DEATH;
159 } 172 }
160 173
161 bool IsWeak() const { return state() == WEAK; } 174 bool IsWeak() const { return state() == WEAK; }
162 175
163 bool IsRetainer() const { return state() != FREE; } 176 bool IsRetainer() const { return state() != FREE; }
(...skipping 23 matching lines...) Expand all
187 } 200 }
188 void clear_partially_dependent() { set_partially_dependent(false); } 201 void clear_partially_dependent() { set_partially_dependent(false); }
189 202
190 // Callback accessor. 203 // Callback accessor.
191 // TODO(svenpanne) Re-enable or nuke later. 204 // TODO(svenpanne) Re-enable or nuke later.
192 // WeakReferenceCallback callback() { return callback_; } 205 // WeakReferenceCallback callback() { return callback_; }
193 206
194 // Callback parameter accessors. 207 // Callback parameter accessors.
195 void set_parameter(void* parameter) { 208 void set_parameter(void* parameter) {
196 DCHECK(state() != FREE); 209 DCHECK(state() != FREE);
210 DCHECK(weakness_type() == NORMAL_WEAK || weakness_type() == PHANTOM_WEAK);
197 parameter_or_next_free_.parameter = parameter; 211 parameter_or_next_free_.parameter = parameter;
198 } 212 }
199 void* parameter() const { 213 void* parameter() const {
200 DCHECK(state() != FREE); 214 DCHECK(state() != FREE);
201 return parameter_or_next_free_.parameter; 215 return parameter_or_next_free_.parameter;
202 } 216 }
203 217
218 void set_internal_fields(
219 int internal_field_index1, int internal_field_index2) {
220 DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK);
221 parameter_or_next_free_.internal_field_indeces.internal_field1 =
222 internal_field_index1;
223 parameter_or_next_free_.internal_field_indeces.internal_field2 =
224 internal_field_index2;
225 }
226
227 int internal_field1() const {
228 DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK);
229 return parameter_or_next_free_.internal_field_indeces.internal_field1;
230 }
231
232 int internal_field2() const {
233 DCHECK(weakness_type() == INTERNAL_FIELDS_WEAK);
234 return parameter_or_next_free_.internal_field_indeces.internal_field2;
235 }
236
204 // Accessors for next free node in the free list. 237 // Accessors for next free node in the free list.
205 Node* next_free() { 238 Node* next_free() {
206 DCHECK(state() == FREE); 239 DCHECK(state() == FREE);
207 return parameter_or_next_free_.next_free; 240 return parameter_or_next_free_.next_free;
208 } 241 }
209 void set_next_free(Node* value) { 242 void set_next_free(Node* value) {
210 DCHECK(state() == FREE); 243 DCHECK(state() == FREE);
211 parameter_or_next_free_.next_free = value; 244 parameter_or_next_free_.next_free = value;
212 } 245 }
213 246
214 void MakeWeak(void* parameter, WeakCallback weak_callback, 247 void MakeWeak(void* parameter, WeakCallback weak_callback) {
215 bool is_zapped_during_weak_callback = false) {
216 DCHECK(weak_callback != NULL); 248 DCHECK(weak_callback != NULL);
217 DCHECK(state() != FREE); 249 DCHECK(state() != FREE);
218 CHECK(object_ != NULL); 250 CHECK(object_ != NULL);
219 set_state(WEAK); 251 set_state(WEAK);
252 set_weakness_type(Node::NORMAL_WEAK);
220 set_parameter(parameter); 253 set_parameter(parameter);
221 set_is_zapped_during_weak_callback(is_zapped_during_weak_callback);
222 weak_callback_ = weak_callback; 254 weak_callback_ = weak_callback;
223 } 255 }
224 256
257 void MakePhantom(void* parameter, PhantomCallback phantom_callback,
258 int internal_field_index1, int internal_field_index2) {
259 DCHECK(phantom_callback != NULL);
260 DCHECK(state() != FREE);
261 CHECK(object_ != NULL);
262 set_state(WEAK);
263 if (parameter != NULL) {
picksi1 2014/11/28 12:15:11 Bikeshed: Might be clearer to swap the if/else bod
Erik Corry 2014/11/28 14:21:25 Done.
264 DCHECK(internal_field_index1 == v8::Object::kNoInternalFieldIndex);
265 DCHECK(internal_field_index2 == v8::Object::kNoInternalFieldIndex);
266 set_weakness_type(Node::PHANTOM_WEAK);
267 set_parameter(parameter);
268 } else {
269 set_weakness_type(Node::INTERNAL_FIELDS_WEAK);
270 set_internal_fields(internal_field_index1, internal_field_index2);
271 }
272 weak_callback_ = reinterpret_cast<WeakCallback>(phantom_callback);
273 }
274
225 void* ClearWeakness() { 275 void* ClearWeakness() {
226 DCHECK(state() != FREE); 276 DCHECK(state() != FREE);
227 void* p = parameter(); 277 void* p = parameter();
228 set_state(NORMAL); 278 set_state(NORMAL);
229 set_parameter(NULL); 279 set_parameter(NULL);
230 return p; 280 return p;
231 } 281 }
232 282
233 bool PostGarbageCollectionProcessing(Isolate* isolate) { 283 bool PostGarbageCollectionProcessing(Isolate* isolate) {
234 if (state() != Node::PENDING) return false; 284 if (state() != Node::PENDING) return false;
235 if (weak_callback_ == NULL) { 285 if (weak_callback_ == NULL) {
236 Release(); 286 Release();
237 return false; 287 return false;
238 } 288 }
239 void* param = parameter();
240 set_state(NEAR_DEATH); 289 set_state(NEAR_DEATH);
241 set_parameter(NULL);
242 290
243 Object** object = location();
244 { 291 {
245 // Check that we are not passing a finalized external string to 292 // Check that we are not passing a finalized external string to
246 // the callback. 293 // the callback.
247 DCHECK(!object_->IsExternalOneByteString() || 294 DCHECK(!object_->IsExternalOneByteString() ||
248 ExternalOneByteString::cast(object_)->resource() != NULL); 295 ExternalOneByteString::cast(object_)->resource() != NULL);
249 DCHECK(!object_->IsExternalTwoByteString() || 296 DCHECK(!object_->IsExternalTwoByteString() ||
250 ExternalTwoByteString::cast(object_)->resource() != NULL); 297 ExternalTwoByteString::cast(object_)->resource() != NULL);
251 // Leaving V8. 298 // Leaving V8.
252 VMState<EXTERNAL> vmstate(isolate); 299 VMState<EXTERNAL> vmstate(isolate);
253 HandleScope handle_scope(isolate); 300 HandleScope handle_scope(isolate);
254 if (is_zapped_during_weak_callback()) { 301 if (weakness_type() == Node::NORMAL_WEAK) {
picksi1 2014/11/28 12:15:11 Could this code be refactored to switch on the wea
Erik Corry 2014/11/28 14:21:25 I have to rewrite this anyway because I have worke
255 // Phantom weak pointer case. 302 Object** object = location();
256 DCHECK(*object == Smi::FromInt(kPhantomReferenceZap));
257 // Make data with a null handle.
258 v8::WeakCallbackData<v8::Value, void> 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, isolate); 303 Handle<Object> handle(*object, isolate);
269 v8::WeakCallbackData<v8::Value, void> data( 304 v8::WeakCallbackData<v8::Value, void> data(
270 reinterpret_cast<v8::Isolate*>(isolate), v8::Utils::ToLocal(handle), 305 reinterpret_cast<v8::Isolate*>(isolate), v8::Utils::ToLocal(handle),
271 param); 306 parameter());
307 set_parameter(NULL);
272 weak_callback_(data); 308 weak_callback_(data);
309 } else {
310 v8::PhantomCallbackData<void>::Callback callback =
311 reinterpret_cast<v8::PhantomCallbackData<void>::Callback>(
312 weak_callback_);
313 if (weakness_type() == Node::PHANTOM_WEAK) {
314 // Phantom weak pointer case.
315 DCHECK(*location() == Smi::FromInt(kPhantomReferenceZap));
316 // Make data with a null handle.
317 v8::PhantomCallbackData<void> data(
318 reinterpret_cast<v8::Isolate*>(isolate), parameter());
319 callback(data);
320 if (state() != FREE) {
picksi1 2014/11/28 12:15:11 There are lots of 'state() != FREE's in the code,
Erik Corry 2014/11/28 14:21:25 Created IsInUse() for this.
321 // Callback does not have to clear the global handle if it is a
322 // phantom handle.
323 Release();
324 }
325 } else {
326 DCHECK(weakness_type() == Node::INTERNAL_FIELDS_WEAK);
327 // Phantom weak pointer case, passing internal fields instead of
328 // parameter.
329 Handle<Object> handle(object(), isolate);
330 Handle<JSObject> jsobject = Handle<JSObject>::cast(handle);
331 v8::PhantomCallbackData<void> data(
332 reinterpret_cast<v8::Isolate*>(isolate),
333 jsobject->GetInternalField(internal_field1()),
334 jsobject->GetInternalField(internal_field2()));
335 // In the future, we want to delay the callback. In that case we will
336 // zap when we queue up, to stop the C++ side accessing the dead V8
337 // object, but we will call Release only after the callback (allowing
338 // the node to be reused).
339 Zap();
340 callback(data);
341 Release();
342 }
273 } 343 }
274 } 344 }
275 // Absence of explicit cleanup or revival of weak handle 345 // Absence of explicit cleanup or revival of weak handle
276 // in most of the cases would lead to memory leak. 346 // in most of the cases would lead to memory leak.
277 CHECK(state() != NEAR_DEATH); 347 CHECK(state() != NEAR_DEATH);
278 return true; 348 return true;
279 } 349 }
280 350
281 inline GlobalHandles* GetGlobalHandles(); 351 inline GlobalHandles* GetGlobalHandles();
282 352
(...skipping 10 matching lines...) Expand all
293 // Note: the most aligned fields should go first. 363 // Note: the most aligned fields should go first.
294 364
295 // Wrapper class ID. 365 // Wrapper class ID.
296 uint16_t class_id_; 366 uint16_t class_id_;
297 367
298 // Index in the containing handle block. 368 // Index in the containing handle block.
299 uint8_t index_; 369 uint8_t index_;
300 370
301 // This stores three flags (independent, partially_dependent and 371 // This stores three flags (independent, partially_dependent and
302 // in_new_space_list) and a State. 372 // in_new_space_list) and a State.
303 class NodeState : public BitField<State, 0, 4> {}; 373 class NodeState : public BitField<State, 0, 3> {};
304 class IsIndependent : public BitField<bool, 4, 1> {}; 374 class IsIndependent : public BitField<bool, 3, 1> {};
305 class IsPartiallyDependent : public BitField<bool, 5, 1> {}; 375 class IsPartiallyDependent : public BitField<bool, 4, 1> {};
306 class IsInNewSpaceList : public BitField<bool, 6, 1> {}; 376 class IsInNewSpaceList : public BitField<bool, 5, 1> {};
307 class IsZappedDuringWeakCallback : public BitField<bool, 7, 1> {}; 377 class NodeWeaknessType : public BitField<WeaknessType, 6, 2> {};
308 378
309 uint8_t flags_; 379 uint8_t flags_;
310 380
311 // Handle specific callback - might be a weak reference in disguise. 381 // Handle specific callback - might be a weak reference in disguise.
312 WeakCallback weak_callback_; 382 WeakCallback weak_callback_;
313 383
314 // Provided data for callback. In FREE state, this is used for 384 // Provided data for callback. In FREE state, this is used for
315 // the free list link. 385 // the free list link.
316 union { 386 union {
317 void* parameter; 387 void* parameter;
388 struct {
389 uint16_t internal_field1;
390 uint16_t internal_field2;
391 } internal_field_indeces;
318 Node* next_free; 392 Node* next_free;
319 } parameter_or_next_free_; 393 } parameter_or_next_free_;
320 394
321 DISALLOW_COPY_AND_ASSIGN(Node); 395 DISALLOW_COPY_AND_ASSIGN(Node);
322 }; 396 };
323 397
324 398
325 class GlobalHandles::NodeBlock { 399 class GlobalHandles::NodeBlock {
326 public: 400 public:
327 static const int kSize = 256; 401 static const int kSize = 256;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 return Node::FromLocation(location)->GetGlobalHandles()->Create(*location); 567 return Node::FromLocation(location)->GetGlobalHandles()->Create(*location);
494 } 568 }
495 569
496 570
497 void GlobalHandles::Destroy(Object** location) { 571 void GlobalHandles::Destroy(Object** location) {
498 if (location != NULL) Node::FromLocation(location)->Release(); 572 if (location != NULL) Node::FromLocation(location)->Release();
499 } 573 }
500 574
501 575
502 void GlobalHandles::MakeWeak(Object** location, void* parameter, 576 void GlobalHandles::MakeWeak(Object** location, void* parameter,
503 WeakCallback weak_callback, PhantomState phantom) { 577 WeakCallback weak_callback) {
504 Node::FromLocation(location) 578 Node::FromLocation(location)->MakeWeak(parameter, weak_callback);
505 ->MakeWeak(parameter, weak_callback, phantom == Phantom);
506 } 579 }
507 580
508 581
582 void GlobalHandles::MakePhantom(Object** location, void* parameter,
583 PhantomCallback phantom_callback,
584 int internal_field_index1,
585 int internal_field_index2) {
586 Node::FromLocation(location)
picksi1 2014/11/28 12:15:11 Do internal_field_index1/2 have anything to do wit
Erik Corry 2014/11/28 14:21:25 Done.
587 ->MakePhantom(parameter, phantom_callback, internal_field_index1,
588 internal_field_index2);
589 }
590
591
509 void* GlobalHandles::ClearWeakness(Object** location) { 592 void* GlobalHandles::ClearWeakness(Object** location) {
510 return Node::FromLocation(location)->ClearWeakness(); 593 return Node::FromLocation(location)->ClearWeakness();
511 } 594 }
512 595
513 596
514 void GlobalHandles::MarkIndependent(Object** location) { 597 void GlobalHandles::MarkIndependent(Object** location) {
515 Node::FromLocation(location)->MarkIndependent(); 598 Node::FromLocation(location)->MarkIndependent();
516 } 599 }
517 600
518 601
(...skipping 14 matching lines...) Expand all
533 616
534 bool GlobalHandles::IsWeak(Object** location) { 617 bool GlobalHandles::IsWeak(Object** location) {
535 return Node::FromLocation(location)->IsWeak(); 618 return Node::FromLocation(location)->IsWeak();
536 } 619 }
537 620
538 621
539 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) { 622 void GlobalHandles::IterateWeakRoots(ObjectVisitor* v) {
540 for (NodeIterator it(this); !it.done(); it.Advance()) { 623 for (NodeIterator it(this); !it.done(); it.Advance()) {
541 Node* node = it.node(); 624 Node* node = it.node();
542 if (node->IsWeakRetainer()) { 625 if (node->IsWeakRetainer()) {
543 if (node->state() == Node::PENDING && 626 // Weakness type can be normal, phantom or internal fields.
544 node->is_zapped_during_weak_callback()) { 627 // For normal weakness we mark through the handle so that
545 *(node->location()) = Smi::FromInt(kPhantomReferenceZap); 628 // the object and things reachable from it are available
629 // to the callback.
630 // In the case of phantom we can zap the object handle now
631 // and we won't need it, so we don't need to mark through it.
632 // In the internal fields case we will need the internal
633 // fields, so we can't zap the handle, but we don't need to
634 // mark through it, because it will die in this GC round.
635 if (node->state() == Node::PENDING) {
picksi1 2014/11/28 12:15:11 switch? Not sure if a 3 case switch beats 2 ifs on
Erik Corry 2014/11/28 14:21:25 The compiler will certainly convert a 3 case switc
636 if (node->weakness_type() == Node::PHANTOM_WEAK) {
637 *(node->location()) = Smi::FromInt(kPhantomReferenceZap);
638 } else if (node->weakness_type() == Node::NORMAL_WEAK) {
639 v->VisitPointer(node->location());
640 } else {
641 DCHECK(node->weakness_type() == Node::INTERNAL_FIELDS_WEAK);
642 }
546 } else { 643 } else {
547 v->VisitPointer(node->location()); 644 v->VisitPointer(node->location());
548 } 645 }
549 } 646 }
550 } 647 }
551 } 648 }
552 649
553 650
554 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) { 651 void GlobalHandles::IdentifyWeakHandles(WeakSlotCallback f) {
555 for (NodeIterator it(this); !it.done(); it.Advance()) { 652 for (NodeIterator it(this); !it.done(); it.Advance()) {
(...skipping 28 matching lines...) Expand all
584 } 681 }
585 } 682 }
586 683
587 684
588 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { 685 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) {
589 for (int i = 0; i < new_space_nodes_.length(); ++i) { 686 for (int i = 0; i < new_space_nodes_.length(); ++i) {
590 Node* node = new_space_nodes_[i]; 687 Node* node = new_space_nodes_[i];
591 DCHECK(node->is_in_new_space_list()); 688 DCHECK(node->is_in_new_space_list());
592 if ((node->is_independent() || node->is_partially_dependent()) && 689 if ((node->is_independent() || node->is_partially_dependent()) &&
593 node->IsWeakRetainer()) { 690 node->IsWeakRetainer()) {
594 if (node->is_zapped_during_weak_callback()) { 691 if (node->weakness_type() == Node::PHANTOM_WEAK) {
595 *(node->location()) = Smi::FromInt(kPhantomReferenceZap); 692 *(node->location()) = Smi::FromInt(kPhantomReferenceZap);
693 } else if (node->weakness_type() == Node::NORMAL_WEAK) {
694 v->VisitPointer(node->location());
596 } else { 695 } else {
597 v->VisitPointer(node->location()); 696 DCHECK(node->weakness_type() == Node::INTERNAL_FIELDS_WEAK);
697 // For this case we only need to trace if it's alive: The tracing of
698 // something that is already alive is just to get the pointer updated
699 // to the new location of the object).
700 if (!node->IsNearDeath()) {
701 v->VisitPointer(node->location());
702 }
598 } 703 }
599 } 704 }
600 } 705 }
601 } 706 }
602 707
603 708
604 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, 709 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
605 WeakSlotCallbackWithHeap can_skip) { 710 WeakSlotCallbackWithHeap can_skip) {
606 ComputeObjectGroupsAndImplicitReferences(); 711 ComputeObjectGroupsAndImplicitReferences();
607 int last = 0; 712 int last = 0;
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 DCHECK_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); 1188 DCHECK_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]);
1084 blocks_[block][offset] = object; 1189 blocks_[block][offset] = object;
1085 if (isolate->heap()->InNewSpace(object)) { 1190 if (isolate->heap()->InNewSpace(object)) {
1086 new_space_indices_.Add(size_); 1191 new_space_indices_.Add(size_);
1087 } 1192 }
1088 *index = size_++; 1193 *index = size_++;
1089 } 1194 }
1090 1195
1091 1196
1092 } } // namespace v8::internal 1197 } } // namespace v8::internal
OLDNEW
« include/v8.h ('K') | « src/global-handles.h ('k') | src/heap/mark-compact.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698