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

Unified Diff: src/heap/store-buffer.cc

Issue 1406133003: [heap] fix crash during the scavenge of ArrayBuffer (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: store-buffer: move IteratePointersToFromSpace Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
« src/heap/store-buffer.h ('K') | « src/heap/store-buffer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/store-buffer.cc
diff --git a/src/heap/store-buffer.cc b/src/heap/store-buffer.cc
index 2ed9deccff4452256b0035dcae86d0e0cdd5fefe..c2e2a68fe4ee2f18df70bd839308463102dd222f 100644
--- a/src/heap/store-buffer.cc
+++ b/src/heap/store-buffer.cc
@@ -8,6 +8,7 @@
#include "src/counters.h"
#include "src/heap/incremental-marking.h"
+#include "src/heap/mark-compact-inl.h"
#include "src/heap/store-buffer-inl.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
@@ -545,6 +546,107 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) {
}
+void StoreBuffer::IterateAndMarkPointersToFromSpace(
+ HeapObject* object, Address start, Address end, bool record_slots,
+ ObjectSlotCallback slot_callback) {
+ Address slot_address = start;
+
+ while (slot_address < end) {
+ Object** slot = reinterpret_cast<Object**>(slot_address);
+ Object* target = *slot;
+ // If the store buffer becomes overfull we mark pages as being exempt from
+ // the store buffer. These pages are scanned to find pointers that point
+ // to the new space. In that case we may hit newly promoted objects and
+ // fix the pointers before the promotion queue gets to them. Thus the 'if'.
+ if (target->IsHeapObject()) {
+ if (heap_->InFromSpace(target)) {
+ slot_callback(reinterpret_cast<HeapObject**>(slot),
+ HeapObject::cast(target));
+ Object* new_target = *slot;
+ if (heap_->InNewSpace(new_target)) {
+ SLOW_DCHECK(heap_->InToSpace(new_target));
+ SLOW_DCHECK(new_target->IsHeapObject());
+ EnterDirectlyIntoStoreBuffer(reinterpret_cast<Address>(slot));
+ }
+ SLOW_DCHECK(!MarkCompactCollector::IsOnEvacuationCandidate(new_target));
+ } else if (record_slots &&
+ MarkCompactCollector::IsOnEvacuationCandidate(target)) {
+ heap_->mark_compact_collector()->RecordSlot(object, slot, target);
+ }
+ }
+ slot_address += kPointerSize;
+ }
+}
+
+
+void StoreBuffer::IteratePointersToFromSpace(HeapObject* target, int size,
+ ObjectSlotCallback slot_callback) {
+ Address obj_address = target->address();
+
+ // We are not collecting slots on new space objects during mutation
+ // thus we have to scan for pointers to evacuation candidates when we
+ // promote objects. But we should not record any slots in non-black
+ // objects. Grey object's slots would be rescanned.
+ // White object might not survive until the end of collection
+ // it would be a violation of the invariant to record it's slots.
+ bool record_slots = false;
+ if (heap_->incremental_marking()->IsCompacting()) {
+ MarkBit mark_bit = Marking::MarkBitFrom(target);
+ record_slots = Marking::IsBlack(mark_bit);
+ }
+
+ // Do not scavenge JSArrayBuffer's contents
+ switch (target->ContentType()) {
+ case HeapObjectContents::kTaggedValues: {
+ IterateAndMarkPointersToFromSpace(target, obj_address, obj_address + size,
+ record_slots, slot_callback);
+ break;
+ }
+ case HeapObjectContents::kMixedValues: {
+ if (target->IsFixedTypedArrayBase()) {
+ IterateAndMarkPointersToFromSpace(
+ target, obj_address + FixedTypedArrayBase::kBasePointerOffset,
+ obj_address + FixedTypedArrayBase::kHeaderSize, record_slots,
+ slot_callback);
+ } else if (target->IsBytecodeArray()) {
+ IterateAndMarkPointersToFromSpace(
+ target, obj_address + BytecodeArray::kConstantPoolOffset,
+ obj_address + BytecodeArray::kHeaderSize, record_slots,
+ slot_callback);
+ } else if (target->IsJSArrayBuffer()) {
+ IterateAndMarkPointersToFromSpace(
+ target, obj_address,
+ obj_address + JSArrayBuffer::kByteLengthOffset + kPointerSize,
+ record_slots, slot_callback);
+ IterateAndMarkPointersToFromSpace(
+ target, obj_address + JSArrayBuffer::kSize, obj_address + size,
+ record_slots, slot_callback);
+#if V8_DOUBLE_FIELDS_UNBOXING
+ } else if (FLAG_unbox_double_fields) {
+ LayoutDescriptorHelper helper(target->map());
+ DCHECK(!helper.all_fields_tagged());
+
+ for (int offset = 0; offset < size;) {
+ int end_of_region_offset;
+ if (helper.IsTagged(offset, size, &end_of_region_offset)) {
+ IterateAndMarkPointersToFromSpace(
+ target, obj_address + offset,
+ obj_address + end_of_region_offset, record_slots,
+ slot_callback);
+ }
+ offset = end_of_region_offset;
+ }
+#endif
+ }
+ break;
+ }
+ case HeapObjectContents::kRawValues: {
+ break;
+ }
+ }
+}
+
+
void StoreBuffer::Compact() {
Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top());
« src/heap/store-buffer.h ('K') | « src/heap/store-buffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698