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

Side by Side Diff: src/objects-visiting-inl.h

Issue 11575007: Make embedded maps in optimized code weak. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix skipping of maps in visitors. Created 7 years, 11 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
« src/objects.cc ('K') | « src/objects-inl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 void StaticMarkingVisitor<StaticVisitor>::VisitMap( 254 void StaticMarkingVisitor<StaticVisitor>::VisitMap(
255 Map* map, HeapObject* object) { 255 Map* map, HeapObject* object) {
256 Heap* heap = map->GetHeap(); 256 Heap* heap = map->GetHeap();
257 Map* map_object = Map::cast(object); 257 Map* map_object = Map::cast(object);
258 258
259 // Clears the cache of ICs related to this map. 259 // Clears the cache of ICs related to this map.
260 if (FLAG_cleanup_code_caches_at_gc) { 260 if (FLAG_cleanup_code_caches_at_gc) {
261 map_object->ClearCodeCache(heap); 261 map_object->ClearCodeCache(heap);
262 } 262 }
263 263
264 // When map collection is enabled we have to mark through map's 264 // When map collection is enabled we have to mark through map's transitions
265 // transitions and back pointers in a special way to make these links 265 // and back pointers in a special way to make these links weak.
266 // weak. Only maps for subclasses of JSReceiver can have transitions. 266 if (FLAG_collect_maps && map_object->CanTransition()) {
267 STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
268 if (FLAG_collect_maps &&
269 map_object->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
270 MarkMapContents(heap, map_object); 267 MarkMapContents(heap, map_object);
271 } else { 268 } else {
272 StaticVisitor::VisitPointers(heap, 269 StaticVisitor::VisitPointers(heap,
273 HeapObject::RawField(object, Map::kPointerFieldsBeginOffset), 270 HeapObject::RawField(object, Map::kPointerFieldsBeginOffset),
274 HeapObject::RawField(object, Map::kPointerFieldsEndOffset)); 271 HeapObject::RawField(object, Map::kPointerFieldsEndOffset));
275 } 272 }
276 } 273 }
277 274
278 275
279 template<typename StaticVisitor> 276 template<typename StaticVisitor>
280 void StaticMarkingVisitor<StaticVisitor>::VisitCode( 277 void StaticMarkingVisitor<StaticVisitor>::VisitCode(
281 Map* map, HeapObject* object) { 278 Map* map, HeapObject* object) {
282 Heap* heap = map->GetHeap(); 279 Heap* heap = map->GetHeap();
283 Code* code = Code::cast(object); 280 Code* code = Code::cast(object);
284 if (FLAG_cleanup_code_caches_at_gc) { 281 if (FLAG_cleanup_code_caches_at_gc) {
285 code->ClearTypeFeedbackCells(heap); 282 code->ClearTypeFeedbackCells(heap);
286 } 283 }
287 if (FLAG_age_code && !Serializer::enabled()) { 284 if (FLAG_age_code && !Serializer::enabled()) {
288 code->MakeOlder(heap->mark_compact_collector()->marking_parity()); 285 code->MakeOlder(heap->mark_compact_collector()->marking_parity());
289 } 286 }
290 code->CodeIterateBody<StaticVisitor>(heap); 287 code->CodeIterateBody<StaticVisitor, Code::SKIP_EMBEDDED_MAPS>(heap);
291 } 288 }
292 289
293 290
294 template<typename StaticVisitor> 291 template<typename StaticVisitor>
295 void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfo( 292 void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfo(
296 Map* map, HeapObject* object) { 293 Map* map, HeapObject* object) {
297 Heap* heap = map->GetHeap(); 294 Heap* heap = map->GetHeap();
298 SharedFunctionInfo* shared = SharedFunctionInfo::cast(object); 295 SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
299 if (shared->ic_age() != heap->global_ic_age()) { 296 if (shared->ic_age() != heap->global_ic_age()) {
300 shared->ResetForNewContext(heap->global_ic_age()); 297 shared->ResetForNewContext(heap->global_ic_age());
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 // array slot, since it will be implicitly recorded when the pointer 384 // array slot, since it will be implicitly recorded when the pointer
388 // fields of this map are visited. 385 // fields of this map are visited.
389 TransitionArray* transitions = map->unchecked_transition_array(); 386 TransitionArray* transitions = map->unchecked_transition_array();
390 if (transitions->IsTransitionArray()) { 387 if (transitions->IsTransitionArray()) {
391 MarkTransitionArray(heap, transitions); 388 MarkTransitionArray(heap, transitions);
392 } else { 389 } else {
393 // Already marked by marking map->GetBackPointer() above. 390 // Already marked by marking map->GetBackPointer() above.
394 ASSERT(transitions->IsMap() || transitions->IsUndefined()); 391 ASSERT(transitions->IsMap() || transitions->IsUndefined());
395 } 392 }
396 393
394 // Mark prototype dependent codes array but do not push it onto marking
395 // stack, this will make references from it weak. We will clean dead
Michael Starzinger 2013/01/21 10:31:48 One "dead" oughta be enough. :)
ulan 2013/01/21 13:11:57 Done.
396 // dead codes when we iterate over maps in ClearNonLiveTransitions.
397 Object** slot = HeapObject::RawField(reinterpret_cast<HeapObject*>(map),
Michael Starzinger 2013/01/21 10:31:48 The reinterpret_cast shouldn't be necessary, a Map
ulan 2013/01/21 13:11:57 Done.
398 Map::kDependentCodesOffset);
399 HeapObject* obj = HeapObject::cast(*slot);
400 heap->mark_compact_collector()->RecordSlot(slot, slot, obj);
401 StaticVisitor::MarkObjectWithoutPush(heap, obj);
402
397 // Mark the pointer fields of the Map. Since the transitions array has 403 // Mark the pointer fields of the Map. Since the transitions array has
398 // been marked already, it is fine that one of these fields contains a 404 // been marked already, it is fine that one of these fields contains a
399 // pointer to it. 405 // pointer to it.
400 StaticVisitor::VisitPointers(heap, 406 StaticVisitor::VisitPointers(heap,
401 HeapObject::RawField(map, Map::kPointerFieldsBeginOffset), 407 HeapObject::RawField(map, Map::kPointerFieldsBeginOffset),
402 HeapObject::RawField(map, Map::kPointerFieldsEndOffset)); 408 HeapObject::RawField(map, Map::kPointerFieldsEndOffset));
403 } 409 }
404 410
405 411
406 template<typename StaticVisitor> 412 template<typename StaticVisitor>
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 636
631 void Code::CodeIterateBody(ObjectVisitor* v) { 637 void Code::CodeIterateBody(ObjectVisitor* v) {
632 int mode_mask = RelocInfo::kCodeTargetMask | 638 int mode_mask = RelocInfo::kCodeTargetMask |
633 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 639 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
634 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) | 640 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
635 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | 641 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
636 RelocInfo::ModeMask(RelocInfo::JS_RETURN) | 642 RelocInfo::ModeMask(RelocInfo::JS_RETURN) |
637 RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) | 643 RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
638 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); 644 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
639 645
640 // There are two places where we iterate code bodies: here and the 646 // There are two places where we iterate code bodies: here and the non-
641 // templated CodeIterateBody (below). They should be kept in sync. 647 // templated CodeIterateBody (above). They should be kept in sync. The only
648 // difference between the two versions is in handling of embedded maps.
649 // Static marking visitors do not visit embedded maps, but most of the non-
650 // static visitors need to visit embedded maps. Non-static visitor can skip
651 // embedded maps by overriding VisitEmbeddedPointer, like
652 // VerifyMarkingVisitor does.
642 IteratePointer(v, kRelocationInfoOffset); 653 IteratePointer(v, kRelocationInfoOffset);
643 IteratePointer(v, kHandlerTableOffset); 654 IteratePointer(v, kHandlerTableOffset);
644 IteratePointer(v, kDeoptimizationDataOffset); 655 IteratePointer(v, kDeoptimizationDataOffset);
645 IteratePointer(v, kTypeFeedbackInfoOffset); 656 IteratePointer(v, kTypeFeedbackInfoOffset);
646 657
647 RelocIterator it(this, mode_mask); 658 RelocIterator it(this, mode_mask);
648 for (; !it.done(); it.next()) { 659 for (; !it.done(); it.next()) {
649 it.rinfo()->Visit(v); 660 it.rinfo()->Visit(v);
650 } 661 }
651 } 662 }
652 663
653 664
654 template<typename StaticVisitor> 665 template<typename StaticVisitor, Code::EmbeddedMapVisitMode map_visit_mode>
655 void Code::CodeIterateBody(Heap* heap) { 666 void Code::CodeIterateBody(Heap* heap) {
656 int mode_mask = RelocInfo::kCodeTargetMask | 667 int mode_mask = RelocInfo::kCodeTargetMask |
657 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | 668 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
658 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) | 669 RelocInfo::ModeMask(RelocInfo::GLOBAL_PROPERTY_CELL) |
659 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | 670 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
660 RelocInfo::ModeMask(RelocInfo::JS_RETURN) | 671 RelocInfo::ModeMask(RelocInfo::JS_RETURN) |
661 RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) | 672 RelocInfo::ModeMask(RelocInfo::DEBUG_BREAK_SLOT) |
662 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY); 673 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY);
663 674
664 // There are two places where we iterate code bodies: here and the 675 // There are two places where we iterate code bodies: here and the non-
665 // non-templated CodeIterateBody (above). They should be kept in sync. 676 // templated CodeIterateBody (above). They should be kept in sync. The only
677 // difference between the two versions is in handling of embedded maps.
678 // Static marking visitors do not visit embedded maps, but most of the non-
679 // static visitors need to visit embedded maps. Non-static visitor can skip
680 // embedded maps by overriding VisitEmbeddedPointer, like
681 // VerifyMarkingVisitor does.
666 StaticVisitor::VisitPointer( 682 StaticVisitor::VisitPointer(
667 heap, 683 heap,
668 reinterpret_cast<Object**>(this->address() + kRelocationInfoOffset)); 684 reinterpret_cast<Object**>(this->address() + kRelocationInfoOffset));
669 StaticVisitor::VisitPointer( 685 StaticVisitor::VisitPointer(
670 heap, 686 heap,
671 reinterpret_cast<Object**>(this->address() + kHandlerTableOffset)); 687 reinterpret_cast<Object**>(this->address() + kHandlerTableOffset));
672 StaticVisitor::VisitPointer( 688 StaticVisitor::VisitPointer(
673 heap, 689 heap,
674 reinterpret_cast<Object**>(this->address() + kDeoptimizationDataOffset)); 690 reinterpret_cast<Object**>(this->address() + kDeoptimizationDataOffset));
675 StaticVisitor::VisitPointer( 691 StaticVisitor::VisitPointer(
676 heap, 692 heap,
677 reinterpret_cast<Object**>(this->address() + kTypeFeedbackInfoOffset)); 693 reinterpret_cast<Object**>(this->address() + kTypeFeedbackInfoOffset));
678 694
679 RelocIterator it(this, mode_mask); 695 RelocIterator it(this, mode_mask);
680 for (; !it.done(); it.next()) { 696 if (map_visit_mode == SKIP_EMBEDDED_MAPS && kind() == OPTIMIZED_FUNCTION) {
ulan 2013/01/17 09:35:10 Maybe I should just move this to VisitEmbeddedPoin
Michael Starzinger 2013/01/21 10:31:48 Yes, good idea, I am very much in favor of this su
ulan 2013/01/21 13:11:57 Done.
681 it.rinfo()->template Visit<StaticVisitor>(heap); 697 // Treat embedded maps in optimized code as weak.
698 for (; !it.done(); it.next()) {
699 RelocInfo* info = it.rinfo();
700 if (!RelocInfo::IsEmbeddedObject(info->rmode()) ||
701 !info->target_object()->IsMap() ||
702 !Map::cast(info->target_object())->CanTransition()) {
703 it.rinfo()->template Visit<StaticVisitor>(heap);
704 }
705 }
706 } else {
707 for (; !it.done(); it.next()) {
708 it.rinfo()->template Visit<StaticVisitor>(heap);
709 }
682 } 710 }
683 } 711 }
684 712
685 713
686 } } // namespace v8::internal 714 } } // namespace v8::internal
687 715
688 #endif // V8_OBJECTS_VISITING_INL_H_ 716 #endif // V8_OBJECTS_VISITING_INL_H_
OLDNEW
« src/objects.cc ('K') | « src/objects-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698