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

Unified Diff: src/heap/mark-compact.cc

Issue 1441453002: Avoid manual object's body traversal in GC. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments + removed HeapObject::ContentType() Created 5 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 side-by-side diff with in-line comments
Download patch
Index: src/heap/mark-compact.cc
diff --git a/src/heap/mark-compact.cc b/src/heap/mark-compact.cc
index 1a67ccd2eed6e94e7df4ca21824a84e2fd2f262b..b92d33eba407f38e1a05a585bb65ce171368466c 100644
--- a/src/heap/mark-compact.cc
+++ b/src/heap/mark-compact.cc
@@ -2621,6 +2621,40 @@ void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Object* target) {
}
+class RecordMigratedSlotVisitor final : public ObjectVisitor {
+ public:
+ RecordMigratedSlotVisitor(MarkCompactCollector* collector,
+ SlotsBuffer** evacuation_slots_buffer)
+ : collector_(collector),
+ evacuation_slots_buffer_(evacuation_slots_buffer) {}
+
+ V8_INLINE void VisitPointer(Object** p) override {
+ collector_->RecordMigratedSlot(*p, reinterpret_cast<Address>(p),
+ evacuation_slots_buffer_);
+ }
+
+ V8_INLINE void VisitPointers(Object** start, Object** end) override {
+ while (start < end) {
+ collector_->RecordMigratedSlot(*start, reinterpret_cast<Address>(start),
+ evacuation_slots_buffer_);
+ ++start;
+ }
+ }
+
+ V8_INLINE void VisitCodeEntry(Address code_entry_slot) override {
+ if (collector_->compacting_) {
+ Address code_entry = Memory::Address_at(code_entry_slot);
+ collector_->RecordMigratedCodeEntrySlot(code_entry, code_entry_slot,
+ evacuation_slots_buffer_);
+ }
+ }
+
+ private:
+ MarkCompactCollector* collector_;
+ SlotsBuffer** evacuation_slots_buffer_;
+};
+
+
// We scavenge new space simultaneously with sweeping. This is done in two
// passes.
//
@@ -2646,26 +2680,10 @@ void MarkCompactCollector::MigrateObject(
DCHECK_OBJECT_SIZE(size);
DCHECK(evacuation_slots_buffer != nullptr);
DCHECK(IsAligned(size, kPointerSize));
- switch (src->ContentType()) {
- case HeapObjectContents::kTaggedValues:
- MigrateObjectTagged(dst, src, size, evacuation_slots_buffer);
- break;
-
- case HeapObjectContents::kMixedValues:
- MigrateObjectMixed(dst, src, size, evacuation_slots_buffer);
- break;
-
- case HeapObjectContents::kRawValues:
- MigrateObjectRaw(dst, src, size);
- break;
- }
- if (compacting_ && dst->IsJSFunction()) {
- Address code_entry_slot = dst->address() + JSFunction::kCodeEntryOffset;
- Address code_entry = Memory::Address_at(code_entry_slot);
- RecordMigratedCodeEntrySlot(code_entry, code_entry_slot,
- evacuation_slots_buffer);
- }
+ heap()->MoveBlock(dst->address(), src->address(), size);
+ RecordMigratedSlotVisitor visitor(this, evacuation_slots_buffer);
+ dst->IterateBody(&visitor);
} else if (dest == CODE_SPACE) {
DCHECK_CODEOBJECT_SIZE(size, heap()->code_space());
DCHECK(evacuation_slots_buffer != nullptr);
@@ -2684,90 +2702,6 @@ void MarkCompactCollector::MigrateObject(
}
-void MarkCompactCollector::MigrateObjectTagged(
- HeapObject* dst, HeapObject* src, int size,
- SlotsBuffer** evacuation_slots_buffer) {
- Address src_slot = src->address();
- Address dst_slot = dst->address();
- for (int remaining = size / kPointerSize; remaining > 0; remaining--) {
- Object* value = Memory::Object_at(src_slot);
- Memory::Object_at(dst_slot) = value;
- RecordMigratedSlot(value, dst_slot, evacuation_slots_buffer);
- src_slot += kPointerSize;
- dst_slot += kPointerSize;
- }
-}
-
-
-void MarkCompactCollector::MigrateObjectMixed(
- HeapObject* dst, HeapObject* src, int size,
- SlotsBuffer** evacuation_slots_buffer) {
- if (src->IsFixedTypedArrayBase()) {
- heap()->MoveBlock(dst->address(), src->address(), size);
- Address base_pointer_slot =
- dst->address() + FixedTypedArrayBase::kBasePointerOffset;
- RecordMigratedSlot(Memory::Object_at(base_pointer_slot), base_pointer_slot,
- evacuation_slots_buffer);
- } else if (src->IsBytecodeArray()) {
- heap()->MoveBlock(dst->address(), src->address(), size);
- Address constant_pool_slot =
- dst->address() + BytecodeArray::kConstantPoolOffset;
- RecordMigratedSlot(Memory::Object_at(constant_pool_slot),
- constant_pool_slot, evacuation_slots_buffer);
- } else if (src->IsJSArrayBuffer()) {
- heap()->MoveBlock(dst->address(), src->address(), size);
-
- // Visit inherited JSObject properties and byte length of ArrayBuffer
- Address regular_slot = dst->address() + JSArrayBuffer::kPropertiesOffset;
- Address regular_slots_end =
- dst->address() + JSArrayBuffer::kByteLengthOffset + kPointerSize;
- while (regular_slot < regular_slots_end) {
- RecordMigratedSlot(Memory::Object_at(regular_slot), regular_slot,
- evacuation_slots_buffer);
- regular_slot += kPointerSize;
- }
-
- // Skip backing store and visit just internal fields
- Address internal_field_slot = dst->address() + JSArrayBuffer::kSize;
- Address internal_fields_end =
- dst->address() + JSArrayBuffer::kSizeWithInternalFields;
- while (internal_field_slot < internal_fields_end) {
- RecordMigratedSlot(Memory::Object_at(internal_field_slot),
- internal_field_slot, evacuation_slots_buffer);
- internal_field_slot += kPointerSize;
- }
- } else if (FLAG_unbox_double_fields) {
- Address dst_addr = dst->address();
- Address src_addr = src->address();
- Address src_slot = src_addr;
- Address dst_slot = dst_addr;
-
- LayoutDescriptorHelper helper(src->map());
- DCHECK(!helper.all_fields_tagged());
- for (int remaining = size / kPointerSize; remaining > 0; remaining--) {
- Object* value = Memory::Object_at(src_slot);
-
- Memory::Object_at(dst_slot) = value;
-
- if (helper.IsTagged(static_cast<int>(src_slot - src_addr))) {
- RecordMigratedSlot(value, dst_slot, evacuation_slots_buffer);
- }
-
- src_slot += kPointerSize;
- dst_slot += kPointerSize;
- }
- } else {
- UNREACHABLE();
- }
-}
-
-
-void MarkCompactCollector::MigrateObjectRaw(HeapObject* dst, HeapObject* src,
- int size) {
- heap()->MoveBlock(dst->address(), src->address(), size);
-}
-
-
static inline void UpdateSlot(Isolate* isolate, ObjectVisitor* v,
SlotsBuffer::SlotType slot_type, Address addr) {
switch (slot_type) {
@@ -3110,45 +3044,8 @@ bool MarkCompactCollector::IsSlotInLiveObject(Address slot) {
}
DCHECK(object != NULL);
-
- switch (object->ContentType()) {
- case HeapObjectContents::kTaggedValues:
- return true;
-
- case HeapObjectContents::kRawValues: {
- InstanceType type = object->map()->instance_type();
- // Slots in maps and code can't be invalid because they are never
- // shrunk.
- if (type == MAP_TYPE || type == CODE_TYPE) return true;
-
- // Consider slots in objects that contain ONLY raw data as invalid.
- return false;
- }
-
- case HeapObjectContents::kMixedValues: {
- if (object->IsFixedTypedArrayBase()) {
- return static_cast<int>(slot - object->address()) ==
- FixedTypedArrayBase::kBasePointerOffset;
- } else if (object->IsBytecodeArray()) {
- return static_cast<int>(slot - object->address()) ==
- BytecodeArray::kConstantPoolOffset;
- } else if (object->IsJSArrayBuffer()) {
- int off = static_cast<int>(slot - object->address());
- return (off >= JSArrayBuffer::kPropertiesOffset &&
- off <= JSArrayBuffer::kByteLengthOffset) ||
- (off >= JSArrayBuffer::kSize &&
- off < JSArrayBuffer::kSizeWithInternalFields);
- } else if (FLAG_unbox_double_fields) {
- // Filter out slots that happen to point to unboxed double fields.
- LayoutDescriptorHelper helper(object->map());
- DCHECK(!helper.all_fields_tagged());
- return helper.IsTagged(static_cast<int>(slot - object->address()));
- }
- break;
- }
- }
- UNREACHABLE();
- return true;
+ int offset = static_cast<int>(slot - object->address());
+ return object->IsValidSlot(offset);
}
« no previous file with comments | « src/heap/mark-compact.h ('k') | src/heap/spaces.cc » ('j') | src/heap/spaces.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698