OLD | NEW |
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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 void MakeWeak(void* parameter, WeakCallback weak_callback) { | 223 void MakeWeak(void* parameter, WeakCallback weak_callback) { |
224 DCHECK(weak_callback != NULL); | 224 DCHECK(weak_callback != NULL); |
225 DCHECK(IsInUse()); | 225 DCHECK(IsInUse()); |
226 CHECK(object_ != NULL); | 226 CHECK(object_ != NULL); |
227 set_state(WEAK); | 227 set_state(WEAK); |
228 set_weakness_type(NORMAL_WEAK); | 228 set_weakness_type(NORMAL_WEAK); |
229 set_parameter(parameter); | 229 set_parameter(parameter); |
230 weak_callback_ = weak_callback; | 230 weak_callback_ = weak_callback; |
231 } | 231 } |
232 | 232 |
233 void MakePhantom(void* parameter, int number_of_internal_fields, | 233 void MakeWeak(void* parameter, |
234 PhantomCallbackData<void>::Callback phantom_callback) { | 234 WeakCallbackInfo<void>::Callback phantom_callback, |
235 DCHECK(number_of_internal_fields >= 0); | 235 v8::WeakCallbackType type) { |
236 DCHECK(number_of_internal_fields <= 2); | 236 DCHECK(phantom_callback != nullptr); |
237 DCHECK(phantom_callback != NULL); | |
238 DCHECK(IsInUse()); | 237 DCHECK(IsInUse()); |
239 CHECK(object_ != NULL); | 238 CHECK(object_ != nullptr); |
240 set_state(WEAK); | 239 set_state(WEAK); |
241 if (number_of_internal_fields == 0) { | 240 switch (type) { |
242 set_weakness_type(PHANTOM_WEAK_0_INTERNAL_FIELDS); | 241 case v8::WeakCallbackType::kParameter: |
243 } else if (number_of_internal_fields == 1) { | 242 set_weakness_type(PHANTOM_WEAK); |
244 set_weakness_type(PHANTOM_WEAK_1_INTERNAL_FIELDS); | 243 break; |
245 } else { | 244 case v8::WeakCallbackType::kInternalFields: |
246 set_weakness_type(PHANTOM_WEAK_2_INTERNAL_FIELDS); | 245 set_weakness_type(PHANTOM_WEAK_2_INTERNAL_FIELDS); |
| 246 break; |
247 } | 247 } |
248 set_parameter(parameter); | 248 set_parameter(parameter); |
249 weak_callback_ = reinterpret_cast<WeakCallback>(phantom_callback); | 249 weak_callback_ = reinterpret_cast<WeakCallback>(phantom_callback); |
250 } | 250 } |
251 | 251 |
252 void* ClearWeakness() { | 252 void* ClearWeakness() { |
253 DCHECK(IsInUse()); | 253 DCHECK(IsInUse()); |
254 void* p = parameter(); | 254 void* p = parameter(); |
255 set_state(NORMAL); | 255 set_state(NORMAL); |
256 set_parameter(NULL); | 256 set_parameter(NULL); |
257 return p; | 257 return p; |
258 } | 258 } |
259 | 259 |
260 void CollectPhantomCallbackData( | 260 void CollectPhantomCallbackData( |
261 Isolate* isolate, | 261 Isolate* isolate, |
262 List<PendingPhantomCallback>* pending_phantom_callbacks) { | 262 List<PendingPhantomCallback>* pending_phantom_callbacks) { |
263 if (state() != PENDING) return; | 263 if (state() != PENDING) return; |
264 if (weak_callback_ != NULL) { | 264 if (weak_callback_ != NULL) { |
265 if (weakness_type() == NORMAL_WEAK) return; | 265 if (weakness_type() == NORMAL_WEAK) return; |
266 | 266 |
267 v8::Isolate* api_isolate = reinterpret_cast<v8::Isolate*>(isolate); | 267 v8::Isolate* api_isolate = reinterpret_cast<v8::Isolate*>(isolate); |
268 | 268 |
269 DCHECK(weakness_type() == PHANTOM_WEAK_0_INTERNAL_FIELDS || | 269 DCHECK(weakness_type() == PHANTOM_WEAK || |
270 weakness_type() == PHANTOM_WEAK_1_INTERNAL_FIELDS || | |
271 weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS); | 270 weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS); |
272 | 271 |
273 Object* internal_field0 = nullptr; | 272 Object* internal_field0 = nullptr; |
274 Object* internal_field1 = nullptr; | 273 Object* internal_field1 = nullptr; |
275 if (weakness_type() != PHANTOM_WEAK_0_INTERNAL_FIELDS) { | 274 if (weakness_type() != PHANTOM_WEAK) { |
276 JSObject* jsobject = reinterpret_cast<JSObject*>(object()); | 275 if (object()->IsJSObject()) { |
277 DCHECK(jsobject->IsJSObject()); | 276 JSObject* jsobject = JSObject::cast(object()); |
278 DCHECK(jsobject->GetInternalFieldCount() >= 1); | 277 int field_count = jsobject->GetInternalFieldCount(); |
279 internal_field0 = jsobject->GetInternalField(0); | 278 if (field_count > 0) { |
280 if (weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS) { | 279 internal_field0 = jsobject->GetInternalField(0); |
281 DCHECK(jsobject->GetInternalFieldCount() >= 2); | 280 if (!internal_field0->IsSmi()) internal_field0 = nullptr; |
282 internal_field1 = jsobject->GetInternalField(1); | 281 } |
| 282 if (field_count > 1) { |
| 283 internal_field1 = jsobject->GetInternalField(1); |
| 284 if (!internal_field1->IsSmi()) internal_field1 = nullptr; |
| 285 } |
283 } | 286 } |
284 } | 287 } |
285 | 288 |
286 // Zap with harmless value. | 289 // Zap with harmless value. |
287 *location() = Smi::FromInt(0); | 290 *location() = Smi::FromInt(0); |
288 typedef PhantomCallbackData<void> Data; | 291 typedef v8::WeakCallbackInfo<void> Data; |
289 | |
290 if (!internal_field0->IsSmi()) internal_field0 = nullptr; | |
291 if (!internal_field1->IsSmi()) internal_field1 = nullptr; | |
292 | 292 |
293 Data data(api_isolate, parameter(), internal_field0, internal_field1); | 293 Data data(api_isolate, parameter(), internal_field0, internal_field1); |
294 Data::Callback callback = | 294 Data::Callback callback = |
295 reinterpret_cast<Data::Callback>(weak_callback_); | 295 reinterpret_cast<Data::Callback>(weak_callback_); |
296 | 296 |
297 pending_phantom_callbacks->Add( | 297 pending_phantom_callbacks->Add( |
298 PendingPhantomCallback(this, data, callback)); | 298 PendingPhantomCallback(this, data, callback)); |
299 DCHECK(IsInUse()); | 299 DCHECK(IsInUse()); |
300 set_state(NEAR_DEATH); | 300 set_state(NEAR_DEATH); |
301 } | 301 } |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 if (location != NULL) Node::FromLocation(location)->Release(); | 555 if (location != NULL) Node::FromLocation(location)->Release(); |
556 } | 556 } |
557 | 557 |
558 | 558 |
559 void GlobalHandles::MakeWeak(Object** location, void* parameter, | 559 void GlobalHandles::MakeWeak(Object** location, void* parameter, |
560 WeakCallback weak_callback) { | 560 WeakCallback weak_callback) { |
561 Node::FromLocation(location)->MakeWeak(parameter, weak_callback); | 561 Node::FromLocation(location)->MakeWeak(parameter, weak_callback); |
562 } | 562 } |
563 | 563 |
564 | 564 |
565 typedef PhantomCallbackData<void>::Callback GenericCallback; | 565 typedef v8::WeakCallbackInfo<void>::Callback GenericCallback; |
566 | 566 |
567 | 567 |
568 void GlobalHandles::MakePhantom(Object** location, void* parameter, | 568 void GlobalHandles::MakeWeak(Object** location, void* parameter, |
569 int number_of_internal_fields, | 569 GenericCallback phantom_callback, |
570 GenericCallback phantom_callback) { | 570 v8::WeakCallbackType type) { |
571 Node::FromLocation(location) | 571 Node::FromLocation(location)->MakeWeak(parameter, phantom_callback, type); |
572 ->MakePhantom(parameter, number_of_internal_fields, phantom_callback); | |
573 } | 572 } |
574 | 573 |
575 | 574 |
576 void GlobalHandles::CollectAllPhantomCallbackData() { | 575 void GlobalHandles::CollectAllPhantomCallbackData() { |
577 for (NodeIterator it(this); !it.done(); it.Advance()) { | 576 for (NodeIterator it(this); !it.done(); it.Advance()) { |
578 Node* node = it.node(); | 577 Node* node = it.node(); |
579 node->CollectPhantomCallbackData(isolate(), &pending_phantom_callbacks_); | 578 node->CollectPhantomCallbackData(isolate(), &pending_phantom_callbacks_); |
580 } | 579 } |
581 } | 580 } |
582 | 581 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 if (node->IsWeakRetainer()) { | 625 if (node->IsWeakRetainer()) { |
627 // Weakness type can be normal or phantom, with or without internal | 626 // Weakness type can be normal or phantom, with or without internal |
628 // fields). For normal weakness we mark through the handle so that the | 627 // fields). For normal weakness we mark through the handle so that the |
629 // object and things reachable from it are available to the callback. | 628 // object and things reachable from it are available to the callback. |
630 // | 629 // |
631 // In the case of phantom with no internal fields, we can zap the object | 630 // In the case of phantom with no internal fields, we can zap the object |
632 // handle now and we won't need it, so we don't need to mark through it. | 631 // handle now and we won't need it, so we don't need to mark through it. |
633 // In the internal fields case we will need the internal | 632 // In the internal fields case we will need the internal |
634 // fields, so we can't zap the handle. | 633 // fields, so we can't zap the handle. |
635 if (node->state() == Node::PENDING) { | 634 if (node->state() == Node::PENDING) { |
636 if (node->weakness_type() == PHANTOM_WEAK_0_INTERNAL_FIELDS) { | 635 if (node->weakness_type() == PHANTOM_WEAK) { |
637 *(node->location()) = Smi::FromInt(0); | 636 *(node->location()) = Smi::FromInt(0); |
638 } else if (node->weakness_type() == NORMAL_WEAK) { | 637 } else if (node->weakness_type() == NORMAL_WEAK) { |
639 v->VisitPointer(node->location()); | 638 v->VisitPointer(node->location()); |
640 } else { | 639 } else { |
641 DCHECK(node->weakness_type() == PHANTOM_WEAK_1_INTERNAL_FIELDS || | 640 DCHECK(node->weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS); |
642 node->weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS); | |
643 } | 641 } |
644 } else { | 642 } else { |
645 // Node is not pending, so that means the object survived. We still | 643 // Node is not pending, so that means the object survived. We still |
646 // need to visit the pointer in case the object moved, eg. because of | 644 // need to visit the pointer in case the object moved, eg. because of |
647 // compaction. | 645 // compaction. |
648 v->VisitPointer(node->location()); | 646 v->VisitPointer(node->location()); |
649 } | 647 } |
650 } | 648 } |
651 } | 649 } |
652 } | 650 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 } | 683 } |
686 } | 684 } |
687 | 685 |
688 | 686 |
689 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { | 687 void GlobalHandles::IterateNewSpaceWeakIndependentRoots(ObjectVisitor* v) { |
690 for (int i = 0; i < new_space_nodes_.length(); ++i) { | 688 for (int i = 0; i < new_space_nodes_.length(); ++i) { |
691 Node* node = new_space_nodes_[i]; | 689 Node* node = new_space_nodes_[i]; |
692 DCHECK(node->is_in_new_space_list()); | 690 DCHECK(node->is_in_new_space_list()); |
693 if ((node->is_independent() || node->is_partially_dependent()) && | 691 if ((node->is_independent() || node->is_partially_dependent()) && |
694 node->IsWeakRetainer()) { | 692 node->IsWeakRetainer()) { |
695 if (node->weakness_type() == PHANTOM_WEAK_0_INTERNAL_FIELDS) { | 693 if (node->weakness_type() == PHANTOM_WEAK) { |
696 *(node->location()) = Smi::FromInt(0); | 694 *(node->location()) = Smi::FromInt(0); |
697 } else if (node->weakness_type() == NORMAL_WEAK) { | 695 } else if (node->weakness_type() == NORMAL_WEAK) { |
698 v->VisitPointer(node->location()); | 696 v->VisitPointer(node->location()); |
699 } else { | 697 } else { |
700 DCHECK(node->weakness_type() == PHANTOM_WEAK_1_INTERNAL_FIELDS || | 698 DCHECK(node->weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS); |
701 node->weakness_type() == PHANTOM_WEAK_2_INTERNAL_FIELDS); | |
702 // For this case we only need to trace if it's alive: The tracing of | 699 // For this case we only need to trace if it's alive: The tracing of |
703 // something that is already alive is just to get the pointer updated | 700 // something that is already alive is just to get the pointer updated |
704 // to the new location of the object). | 701 // to the new location of the object). |
705 DCHECK(node->state() != Node::NEAR_DEATH); | 702 DCHECK(node->state() != Node::NEAR_DEATH); |
706 if (node->state() != Node::PENDING) { | 703 if (node->state() != Node::PENDING) { |
707 v->VisitPointer(node->location()); | 704 v->VisitPointer(node->location()); |
708 } | 705 } |
709 } | 706 } |
710 } | 707 } |
711 } | 708 } |
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1242 DCHECK_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); | 1239 DCHECK_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); |
1243 blocks_[block][offset] = object; | 1240 blocks_[block][offset] = object; |
1244 if (isolate->heap()->InNewSpace(object)) { | 1241 if (isolate->heap()->InNewSpace(object)) { |
1245 new_space_indices_.Add(size_); | 1242 new_space_indices_.Add(size_); |
1246 } | 1243 } |
1247 *index = size_++; | 1244 *index = size_++; |
1248 } | 1245 } |
1249 | 1246 |
1250 | 1247 |
1251 } } // namespace v8::internal | 1248 } } // namespace v8::internal |
OLD | NEW |