| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 // object->IsConsString() && !object->IsSymbol() && | 539 // object->IsConsString() && !object->IsSymbol() && |
| 540 // (ConsString::cast(object)->second() == HEAP->empty_string()) | 540 // (ConsString::cast(object)->second() == HEAP->empty_string()) |
| 541 // except the maps for the object and its possible substrings might be | 541 // except the maps for the object and its possible substrings might be |
| 542 // marked. | 542 // marked. |
| 543 HeapObject* object = HeapObject::cast(*p); | 543 HeapObject* object = HeapObject::cast(*p); |
| 544 Map* map = object->map(); | 544 Map* map = object->map(); |
| 545 InstanceType type = map->instance_type(); | 545 InstanceType type = map->instance_type(); |
| 546 if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object; | 546 if ((type & kShortcutTypeMask) != kShortcutTypeTag) return object; |
| 547 | 547 |
| 548 Object* second = reinterpret_cast<ConsString*>(object)->unchecked_second(); | 548 Object* second = reinterpret_cast<ConsString*>(object)->unchecked_second(); |
| 549 Heap* heap = map->heap(); | 549 Heap* heap = map->GetHeap(); |
| 550 if (second != heap->raw_unchecked_empty_string()) { | 550 if (second != heap->raw_unchecked_empty_string()) { |
| 551 return object; | 551 return object; |
| 552 } | 552 } |
| 553 | 553 |
| 554 // Since we don't have the object's start, it is impossible to update the | 554 // Since we don't have the object's start, it is impossible to update the |
| 555 // page dirty marks. Therefore, we only replace the string with its left | 555 // page dirty marks. Therefore, we only replace the string with its left |
| 556 // substring when page dirty marks do not change. | 556 // substring when page dirty marks do not change. |
| 557 // TODO(gc): Seems like we could relax this restriction with store buffers. | 557 // TODO(gc): Seems like we could relax this restriction with store buffers. |
| 558 Object* first = reinterpret_cast<ConsString*>(object)->unchecked_first(); | 558 Object* first = reinterpret_cast<ConsString*>(object)->unchecked_first(); |
| 559 if (!heap->InNewSpace(object) && heap->InNewSpace(first)) return object; | 559 if (!heap->InNewSpace(object) && heap->InNewSpace(first)) return object; |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 typedef FlexibleBodyVisitor<StaticMarkingVisitor, | 742 typedef FlexibleBodyVisitor<StaticMarkingVisitor, |
| 743 JSObject::BodyDescriptor, | 743 JSObject::BodyDescriptor, |
| 744 void> JSObjectVisitor; | 744 void> JSObjectVisitor; |
| 745 | 745 |
| 746 typedef FlexibleBodyVisitor<StaticMarkingVisitor, | 746 typedef FlexibleBodyVisitor<StaticMarkingVisitor, |
| 747 StructBodyDescriptor, | 747 StructBodyDescriptor, |
| 748 void> StructObjectVisitor; | 748 void> StructObjectVisitor; |
| 749 | 749 |
| 750 static void VisitCode(Map* map, HeapObject* object) { | 750 static void VisitCode(Map* map, HeapObject* object) { |
| 751 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>( | 751 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>( |
| 752 map->heap()); | 752 map->GetHeap()); |
| 753 } | 753 } |
| 754 | 754 |
| 755 // Code flushing support. | 755 // Code flushing support. |
| 756 | 756 |
| 757 // How many collections newly compiled code object will survive before being | 757 // How many collections newly compiled code object will survive before being |
| 758 // flushed. | 758 // flushed. |
| 759 static const int kCodeAgeThreshold = 5; | 759 static const int kCodeAgeThreshold = 5; |
| 760 | 760 |
| 761 inline static bool HasSourceCode(SharedFunctionInfo* info) { | 761 inline static bool HasSourceCode(SharedFunctionInfo* info) { |
| 762 Object* undefined = HEAP->raw_unchecked_undefined_value(); | 762 Object* undefined = HEAP->raw_unchecked_undefined_value(); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 888 if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap(); | 888 if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap(); |
| 889 | 889 |
| 890 FixedBodyVisitor<StaticMarkingVisitor, | 890 FixedBodyVisitor<StaticMarkingVisitor, |
| 891 SharedFunctionInfo::BodyDescriptor, | 891 SharedFunctionInfo::BodyDescriptor, |
| 892 void>::Visit(map, object); | 892 void>::Visit(map, object); |
| 893 } | 893 } |
| 894 | 894 |
| 895 | 895 |
| 896 static void VisitSharedFunctionInfoAndFlushCode(Map* map, | 896 static void VisitSharedFunctionInfoAndFlushCode(Map* map, |
| 897 HeapObject* object) { | 897 HeapObject* object) { |
| 898 MarkCompactCollector* collector = map->heap()->mark_compact_collector(); | 898 MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); |
| 899 if (!collector->is_code_flushing_enabled()) { | 899 if (!collector->is_code_flushing_enabled()) { |
| 900 VisitSharedFunctionInfoGeneric(map, object); | 900 VisitSharedFunctionInfoGeneric(map, object); |
| 901 return; | 901 return; |
| 902 } | 902 } |
| 903 VisitSharedFunctionInfoAndFlushCodeGeneric(map, object, false); | 903 VisitSharedFunctionInfoAndFlushCodeGeneric(map, object, false); |
| 904 } | 904 } |
| 905 | 905 |
| 906 | 906 |
| 907 static void VisitSharedFunctionInfoAndFlushCodeGeneric( | 907 static void VisitSharedFunctionInfoAndFlushCodeGeneric( |
| 908 Map* map, HeapObject* object, bool known_flush_code_candidate) { | 908 Map* map, HeapObject* object, bool known_flush_code_candidate) { |
| 909 Heap* heap = map->heap(); | 909 Heap* heap = map->GetHeap(); |
| 910 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object); | 910 SharedFunctionInfo* shared = reinterpret_cast<SharedFunctionInfo*>(object); |
| 911 | 911 |
| 912 if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap(); | 912 if (shared->IsInobjectSlackTrackingInProgress()) shared->DetachInitialMap(); |
| 913 | 913 |
| 914 if (!known_flush_code_candidate) { | 914 if (!known_flush_code_candidate) { |
| 915 known_flush_code_candidate = IsFlushable(shared); | 915 known_flush_code_candidate = IsFlushable(shared); |
| 916 if (known_flush_code_candidate) { | 916 if (known_flush_code_candidate) { |
| 917 heap->mark_compact_collector()->code_flusher()->AddCandidate(shared); | 917 heap->mark_compact_collector()->code_flusher()->AddCandidate(shared); |
| 918 } | 918 } |
| 919 } | 919 } |
| 920 | 920 |
| 921 VisitSharedFunctionInfoFields(heap, object, known_flush_code_candidate); | 921 VisitSharedFunctionInfoFields(heap, object, known_flush_code_candidate); |
| 922 } | 922 } |
| 923 | 923 |
| 924 | 924 |
| 925 static void VisitCodeEntry(Heap* heap, Address entry_address) { | 925 static void VisitCodeEntry(Heap* heap, Address entry_address) { |
| 926 Object* code = Code::GetObjectFromEntryAddress(entry_address); | 926 Object* code = Code::GetObjectFromEntryAddress(entry_address); |
| 927 Object* old_code = code; | 927 Object* old_code = code; |
| 928 VisitPointer(heap, &code); | 928 VisitPointer(heap, &code); |
| 929 if (code != old_code) { | 929 if (code != old_code) { |
| 930 Memory::Address_at(entry_address) = | 930 Memory::Address_at(entry_address) = |
| 931 reinterpret_cast<Code*>(code)->entry(); | 931 reinterpret_cast<Code*>(code)->entry(); |
| 932 } | 932 } |
| 933 } | 933 } |
| 934 | 934 |
| 935 | 935 |
| 936 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { | 936 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { |
| 937 Heap* heap = map->heap(); | 937 Heap* heap = map->GetHeap(); |
| 938 MarkCompactCollector* collector = heap->mark_compact_collector(); | 938 MarkCompactCollector* collector = heap->mark_compact_collector(); |
| 939 if (!collector->is_code_flushing_enabled()) { | 939 if (!collector->is_code_flushing_enabled()) { |
| 940 VisitJSFunction(map, object); | 940 VisitJSFunction(map, object); |
| 941 return; | 941 return; |
| 942 } | 942 } |
| 943 | 943 |
| 944 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); | 944 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); |
| 945 // The function must have a valid context and not be a builtin. | 945 // The function must have a valid context and not be a builtin. |
| 946 bool flush_code_candidate = false; | 946 bool flush_code_candidate = false; |
| 947 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { | 947 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 989 } | 989 } |
| 990 | 990 |
| 991 | 991 |
| 992 #define SLOT_ADDR(obj, offset) \ | 992 #define SLOT_ADDR(obj, offset) \ |
| 993 reinterpret_cast<Object**>((obj)->address() + offset) | 993 reinterpret_cast<Object**>((obj)->address() + offset) |
| 994 | 994 |
| 995 | 995 |
| 996 static inline void VisitJSFunctionFields(Map* map, | 996 static inline void VisitJSFunctionFields(Map* map, |
| 997 JSFunction* object, | 997 JSFunction* object, |
| 998 bool flush_code_candidate) { | 998 bool flush_code_candidate) { |
| 999 Heap* heap = map->heap(); | 999 Heap* heap = map->GetHeap(); |
| 1000 | 1000 |
| 1001 VisitPointers(heap, | 1001 VisitPointers(heap, |
| 1002 SLOT_ADDR(object, JSFunction::kPropertiesOffset), | 1002 SLOT_ADDR(object, JSFunction::kPropertiesOffset), |
| 1003 SLOT_ADDR(object, JSFunction::kCodeEntryOffset)); | 1003 SLOT_ADDR(object, JSFunction::kCodeEntryOffset)); |
| 1004 | 1004 |
| 1005 if (!flush_code_candidate) { | 1005 if (!flush_code_candidate) { |
| 1006 VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset); | 1006 VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset); |
| 1007 } else { | 1007 } else { |
| 1008 // Don't visit code object. | 1008 // Don't visit code object. |
| 1009 | 1009 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); | 1300 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); |
| 1301 | 1301 |
| 1302 // Mark the Object* fields of the Map. | 1302 // Mark the Object* fields of the Map. |
| 1303 // Since the descriptor array has been marked already, it is fine | 1303 // Since the descriptor array has been marked already, it is fine |
| 1304 // that one of these fields contains a pointer to it. | 1304 // that one of these fields contains a pointer to it. |
| 1305 Object** start_slot = HeapObject::RawField(map, | 1305 Object** start_slot = HeapObject::RawField(map, |
| 1306 Map::kPointerFieldsBeginOffset); | 1306 Map::kPointerFieldsBeginOffset); |
| 1307 | 1307 |
| 1308 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset); | 1308 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset); |
| 1309 | 1309 |
| 1310 StaticMarkingVisitor::VisitPointers(map->heap(), start_slot, end_slot); | 1310 StaticMarkingVisitor::VisitPointers(map->GetHeap(), start_slot, end_slot); |
| 1311 } | 1311 } |
| 1312 | 1312 |
| 1313 | 1313 |
| 1314 void MarkCompactCollector::MarkDescriptorArray( | 1314 void MarkCompactCollector::MarkDescriptorArray( |
| 1315 DescriptorArray* descriptors) { | 1315 DescriptorArray* descriptors) { |
| 1316 // TODO(gc) ISOLATES MERGE | 1316 // TODO(gc) ISOLATES MERGE |
| 1317 MarkBit descriptors_mark = HEAP->marking()->MarkBitFrom(descriptors); | 1317 MarkBit descriptors_mark = HEAP->marking()->MarkBitFrom(descriptors); |
| 1318 if (descriptors_mark.Get()) return; | 1318 if (descriptors_mark.Get()) return; |
| 1319 // Empty descriptor array is marked as a root before any maps are marked. | 1319 // Empty descriptor array is marked as a root before any maps are marked. |
| 1320 ASSERT(descriptors != HEAP->raw_unchecked_empty_descriptor_array()); | 1320 ASSERT(descriptors != HEAP->raw_unchecked_empty_descriptor_array()); |
| (...skipping 1334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2655 } | 2655 } |
| 2656 | 2656 |
| 2657 | 2657 |
| 2658 void MarkCompactCollector::Initialize() { | 2658 void MarkCompactCollector::Initialize() { |
| 2659 StaticPointersToNewGenUpdatingVisitor::Initialize(); | 2659 StaticPointersToNewGenUpdatingVisitor::Initialize(); |
| 2660 StaticMarkingVisitor::Initialize(); | 2660 StaticMarkingVisitor::Initialize(); |
| 2661 } | 2661 } |
| 2662 | 2662 |
| 2663 | 2663 |
| 2664 } } // namespace v8::internal | 2664 } } // namespace v8::internal |
| OLD | NEW |