| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1fdec65 commit 972a0c8
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2755,6 +2755,28 @@ void MarkCompactCollector::MigrateObjectMixed(HeapObject* dst, HeapObject* src, | |||
| 2755 | 2755 | Address base_pointer_slot = | |
| 2756 | 2756 | dst->address() + FixedTypedArrayBase::kBasePointerOffset; | |
| 2757 | 2757 | RecordMigratedSlot(Memory::Object_at(base_pointer_slot), base_pointer_slot); | |
| 2758 | + } else if (src->IsJSArrayBuffer()) { | ||
| 2759 | + heap()->MoveBlock(dst->address(), src->address(), size); | ||
| 2760 | + | ||
| 2761 | + // Visit inherited JSObject properties and byte length of ArrayBuffer | ||
| 2762 | + Address regular_slot = | ||
| 2763 | + dst->address() + JSArrayBuffer::BodyDescriptor::kStartOffset; | ||
| 2764 | + Address regular_slots_end = | ||
| 2765 | + dst->address() + JSArrayBuffer::kByteLengthOffset + kPointerSize; | ||
| 2766 | + while (regular_slot < regular_slots_end) { | ||
| 2767 | + RecordMigratedSlot(Memory::Object_at(regular_slot), regular_slot); | ||
| 2768 | + regular_slot += kPointerSize; | ||
| 2769 | + } | ||
| 2770 | + | ||
| 2771 | + // Skip backing store and visit just internal fields | ||
| 2772 | + Address internal_field_slot = dst->address() + JSArrayBuffer::kSize; | ||
| 2773 | + Address internal_fields_end = | ||
| 2774 | + dst->address() + JSArrayBuffer::kSizeWithInternalFields; | ||
| 2775 | + while (internal_field_slot < internal_fields_end) { | ||
| 2776 | + RecordMigratedSlot(Memory::Object_at(internal_field_slot), | ||
| 2777 | + internal_field_slot); | ||
| 2778 | + internal_field_slot += kPointerSize; | ||
| 2779 | + } | ||
| 2758 | 2780 | } else if (FLAG_unbox_double_fields) { | |
| 2759 | 2781 | Address dst_addr = dst->address(); | |
| 2760 | 2782 | Address src_addr = src->address(); | |
@@ -3178,6 +3200,12 @@ bool MarkCompactCollector::IsSlotInLiveObject(Address slot) { | |||
| 3178 | 3200 | if (object->IsFixedTypedArrayBase()) { | |
| 3179 | 3201 | return static_cast<int>(slot - object->address()) == | |
| 3180 | 3202 | FixedTypedArrayBase::kBasePointerOffset; | |
| 3203 | + } else if (object->IsJSArrayBuffer()) { | ||
| 3204 | + int off = static_cast<int>(slot - object->address()); | ||
| 3205 | + return (off >= JSArrayBuffer::BodyDescriptor::kStartOffset && | ||
| 3206 | + off <= JSArrayBuffer::kByteLengthOffset) || | ||
| 3207 | + (off >= JSArrayBuffer::kSize && | ||
| 3208 | + off < JSArrayBuffer::kSizeWithInternalFields); | ||
| 3181 | 3209 | } else if (FLAG_unbox_double_fields) { | |
| 3182 | 3210 | // Filter out slots that happen to point to unboxed double fields. | |
| 3183 | 3211 | LayoutDescriptorHelper helper(object->map()); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -91,10 +91,8 @@ int StaticNewSpaceVisitor<StaticVisitor>::VisitJSArrayBuffer( | |||
| 91 | 91 | Map* map, HeapObject* object) { | |
| 92 | 92 | Heap* heap = map->GetHeap(); | |
| 93 | 93 | ||
| 94 | - VisitPointers( | ||
| 95 | - heap, object, | ||
| 96 | - HeapObject::RawField(object, JSArrayBuffer::BodyDescriptor::kStartOffset), | ||
| 97 | - HeapObject::RawField(object, JSArrayBuffer::kSizeWithInternalFields)); | ||
| 94 | + JSArrayBuffer::JSArrayBufferIterateBody< | ||
| 95 | + StaticNewSpaceVisitor<StaticVisitor> >(heap, object); | ||
| 98 | 96 | if (!JSArrayBuffer::cast(object)->is_external()) { | |
| 99 | 97 | heap->RegisterLiveArrayBuffer(true, | |
| 100 | 98 | JSArrayBuffer::cast(object)->backing_store()); | |
@@ -517,10 +515,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitJSArrayBuffer( | |||
| 517 | 515 | Map* map, HeapObject* object) { | |
| 518 | 516 | Heap* heap = map->GetHeap(); | |
| 519 | 517 | ||
| 520 | - StaticVisitor::VisitPointers( | ||
| 521 | - heap, object, | ||
| 522 | - HeapObject::RawField(object, JSArrayBuffer::BodyDescriptor::kStartOffset), | ||
| 523 | - HeapObject::RawField(object, JSArrayBuffer::kSizeWithInternalFields)); | ||
| 518 | + JSArrayBuffer::JSArrayBufferIterateBody<StaticVisitor>(heap, object); | ||
| 524 | 519 | if (!JSArrayBuffer::cast(object)->is_external()) { | |
| 525 | 520 | heap->RegisterLiveArrayBuffer(false, | |
| 526 | 521 | JSArrayBuffer::cast(object)->backing_store()); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -219,7 +219,6 @@ void HeapObject::IterateBody(InstanceType type, int object_size, | |||
| 219 | 219 | case JS_VALUE_TYPE: | |
| 220 | 220 | case JS_DATE_TYPE: | |
| 221 | 221 | case JS_ARRAY_TYPE: | |
| 222 | - case JS_ARRAY_BUFFER_TYPE: | ||
| 223 | 222 | case JS_TYPED_ARRAY_TYPE: | |
| 224 | 223 | case JS_DATA_VIEW_TYPE: | |
| 225 | 224 | case JS_SET_TYPE: | |
@@ -235,6 +234,9 @@ void HeapObject::IterateBody(InstanceType type, int object_size, | |||
| 235 | 234 | case JS_MESSAGE_OBJECT_TYPE: | |
| 236 | 235 | JSObject::BodyDescriptor::IterateBody(this, object_size, v); | |
| 237 | 236 | break; | |
| 237 | + case JS_ARRAY_BUFFER_TYPE: | ||
| 238 | + JSArrayBuffer::JSArrayBufferIterateBody(this, v); | ||
| 239 | + break; | ||
| 238 | 240 | case JS_FUNCTION_TYPE: | |
| 239 | 241 | reinterpret_cast<JSFunction*>(this) | |
| 240 | 242 | ->JSFunctionIterateBody(object_size, v); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -492,6 +492,17 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) { | |||
| 492 | 492 | obj_address + FixedTypedArrayBase::kBasePointerOffset, | |
| 493 | 493 | obj_address + FixedTypedArrayBase::kHeaderSize, | |
| 494 | 494 | slot_callback); | |
| 495 | + } else if (heap_object->IsJSArrayBuffer()) { | ||
| 496 | + FindPointersToNewSpaceInRegion( | ||
| 497 | + obj_address + | ||
| 498 | + JSArrayBuffer::BodyDescriptor::kStartOffset, | ||
| 499 | + obj_address + JSArrayBuffer::kByteLengthOffset + | ||
| 500 | + kPointerSize, | ||
| 501 | + slot_callback); | ||
| 502 | + FindPointersToNewSpaceInRegion( | ||
| 503 | + obj_address + JSArrayBuffer::kSize, | ||
| 504 | + obj_address + JSArrayBuffer::kSizeWithInternalFields, | ||
| 505 | + slot_callback); | ||
| 495 | 506 | } else if (FLAG_unbox_double_fields) { | |
| 496 | 507 | LayoutDescriptorHelper helper(heap_object->map()); | |
| 497 | 508 | DCHECK(!helper.all_fields_tagged()); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1483,6 +1483,8 @@ HeapObjectContents HeapObject::ContentType() { | |||
| 1483 | 1483 | } else if (type >= FIRST_FIXED_TYPED_ARRAY_TYPE && | |
| 1484 | 1484 | type <= LAST_FIXED_TYPED_ARRAY_TYPE) { | |
| 1485 | 1485 | return HeapObjectContents::kMixedValues; | |
| 1486 | + } else if (type == JS_ARRAY_BUFFER_TYPE) { | ||
| 1487 | + return HeapObjectContents::kMixedValues; | ||
| 1486 | 1488 | } else if (type <= LAST_DATA_TYPE) { | |
| 1487 | 1489 | // TODO(jochen): Why do we claim that Code and Map contain only raw values? | |
| 1488 | 1490 | return HeapObjectContents::kRawValues; | |
@@ -6516,6 +6518,32 @@ void JSArrayBuffer::set_is_shared(bool value) { | |||
| 6516 | 6518 | } | |
| 6517 | 6519 | ||
| 6518 | 6520 | ||
| 6521 | + // static | ||
| 6522 | + template <typename StaticVisitor> | ||
| 6523 | + void JSArrayBuffer::JSArrayBufferIterateBody(Heap* heap, HeapObject* obj) { | ||
| 6524 | + StaticVisitor::VisitPointers( | ||
| 6525 | + heap, obj, | ||
| 6526 | + HeapObject::RawField(obj, JSArrayBuffer::BodyDescriptor::kStartOffset), | ||
| 6527 | + HeapObject::RawField(obj, | ||
| 6528 | + JSArrayBuffer::kByteLengthOffset + kPointerSize)); | ||
| 6529 | + StaticVisitor::VisitPointers( | ||
| 6530 | + heap, obj, HeapObject::RawField(obj, JSArrayBuffer::kSize), | ||
| 6531 | + HeapObject::RawField(obj, JSArrayBuffer::kSizeWithInternalFields)); | ||
| 6532 | + } | ||
| 6533 | + | ||
| 6534 | + | ||
| 6535 | + void JSArrayBuffer::JSArrayBufferIterateBody(HeapObject* obj, | ||
| 6536 | + ObjectVisitor* v) { | ||
| 6537 | + v->VisitPointers( | ||
| 6538 | + HeapObject::RawField(obj, JSArrayBuffer::BodyDescriptor::kStartOffset), | ||
| 6539 | + HeapObject::RawField(obj, | ||
| 6540 | + JSArrayBuffer::kByteLengthOffset + kPointerSize)); | ||
| 6541 | + v->VisitPointers( | ||
| 6542 | + HeapObject::RawField(obj, JSArrayBuffer::kSize), | ||
| 6543 | + HeapObject::RawField(obj, JSArrayBuffer::kSizeWithInternalFields)); | ||
| 6544 | + } | ||
| 6545 | + | ||
| 6546 | + | ||
| 6519 | 6547 | Object* JSArrayBufferView::byte_offset() const { | |
| 6520 | 6548 | if (WasNeutered()) return Smi::FromInt(0); | |
| 6521 | 6549 | return Object::cast(READ_FIELD(this, kByteOffsetOffset)); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9451,9 +9451,14 @@ class JSArrayBuffer: public JSObject { | |||
| 9451 | 9451 | DECLARE_PRINTER(JSArrayBuffer) | |
| 9452 | 9452 | DECLARE_VERIFIER(JSArrayBuffer) | |
| 9453 | 9453 | ||
| 9454 | - static const int kBackingStoreOffset = JSObject::kHeaderSize; | ||
| 9455 | - static const int kByteLengthOffset = kBackingStoreOffset + kPointerSize; | ||
| 9456 | - static const int kBitFieldSlot = kByteLengthOffset + kPointerSize; | ||
| 9454 | + static const int kByteLengthOffset = JSObject::kHeaderSize; | ||
| 9455 | + | ||
| 9456 | + // NOTE: GC will visit objects fields: | ||
| 9457 | + // 1. From JSObject::BodyDescriptor::kStartOffset to kByteLengthOffset + | ||
| 9458 | + // kPointerSize | ||
| 9459 | + // 2. From start of the internal fields and up to the end of them | ||
| 9460 | + static const int kBackingStoreOffset = kByteLengthOffset + kPointerSize; | ||
| 9461 | + static const int kBitFieldSlot = kBackingStoreOffset + kPointerSize; | ||
| 9457 | 9462 | #if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT | |
| 9458 | 9463 | static const int kBitFieldOffset = kBitFieldSlot; | |
| 9459 | 9464 | #else | |
@@ -9464,6 +9469,12 @@ class JSArrayBuffer: public JSObject { | |||
| 9464 | 9469 | static const int kSizeWithInternalFields = | |
| 9465 | 9470 | kSize + v8::ArrayBuffer::kInternalFieldCount * kPointerSize; | |
| 9466 | 9471 | ||
| 9472 | + template <typename StaticVisitor> | ||
| 9473 | + static inline void JSArrayBufferIterateBody(Heap* heap, HeapObject* obj); | ||
| 9474 | + | ||
| 9475 | + static inline void JSArrayBufferIterateBody(HeapObject* obj, | ||
| 9476 | + ObjectVisitor* v); | ||
| 9477 | + | ||
| 9467 | 9478 | class IsExternal : public BitField<bool, 1, 1> {}; | |
| 9468 | 9479 | class IsNeuterable : public BitField<bool, 2, 1> {}; | |
| 9469 | 9480 | class WasNeutered : public BitField<bool, 3, 1> {}; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14220,6 +14220,28 @@ THREADED_TEST(DataView) { | |||
| 14220 | 14220 | } | |
| 14221 | 14221 | ||
| 14222 | 14222 | ||
| 14223 | + THREADED_TEST(SkipArrayBufferBackingStoreDuringGC) { | ||
| 14224 | + LocalContext env; | ||
| 14225 | + v8::Isolate* isolate = env->GetIsolate(); | ||
| 14226 | + v8::HandleScope handle_scope(isolate); | ||
| 14227 | + | ||
| 14228 | + // Make sure the pointer looks like a heap object | ||
| 14229 | + uint8_t* store_ptr = reinterpret_cast<uint8_t*>(i::kHeapObjectTag); | ||
| 14230 | + | ||
| 14231 | + // Create ArrayBuffer with pointer-that-cannot-be-visited in the backing store | ||
| 14232 | + Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate, store_ptr, 8); | ||
| 14233 | + | ||
| 14234 | + // Should not crash | ||
| 14235 | + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in survivor space now | ||
| 14236 | + CcTest::heap()->CollectGarbage(i::NEW_SPACE); // in old gen now | ||
| 14237 | + CcTest::heap()->CollectAllGarbage(); | ||
| 14238 | + CcTest::heap()->CollectAllGarbage(); | ||
| 14239 | + | ||
| 14240 | + // Should not move the pointer | ||
| 14241 | + CHECK_EQ(ab->GetContents().Data(), store_ptr); | ||
| 14242 | + } | ||
| 14243 | + | ||
| 14244 | + | ||
| 14223 | 14245 | THREADED_TEST(SharedUint8Array) { | |
| 14224 | 14246 | i::FLAG_harmony_sharedarraybuffer = true; | |
| 14225 | 14247 | TypedArrayTestHelper<uint8_t, v8::Uint8Array, i::FixedUint8Array, | |
| Back | FazBrowse Home | New Git URL |
0 commit comments