Introduce a base pointer field in FixedTypedArrayBase and teach GC about it
This is the first step towards unifying external and on-heap typed arrays. The end-state will be that this base pointer either points to the on-heap values or to the externally allocated array buffer. BUG=v8:3996 R=hpayer@chromium.org LOG=n Review URL: https://codereview.chromium.org/1176263004 Cr-Commit-Position: refs/heads/master@{#29039}
This commit is contained in:
parent
75350f1ef0
commit
6cc3eb66a2
@ -54,8 +54,14 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) {
|
||||
|
||||
int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
|
||||
STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
|
||||
return IsExternalArrayElementsKind(elements_kind)
|
||||
? 0 : (FixedArray::kHeaderSize - kHeapObjectTag);
|
||||
|
||||
if (IsExternalArrayElementsKind(elements_kind)) {
|
||||
return 0;
|
||||
} else if (IsFixedTypedArrayElementsKind(elements_kind)) {
|
||||
return FixedTypedArrayBase::kDataOffset - kHeapObjectTag;
|
||||
} else {
|
||||
return FixedArray::kHeaderSize - kHeapObjectTag;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2421,6 +2421,12 @@ class ScavengingVisitor : public StaticVisitorBase {
|
||||
HeapObject* object) {
|
||||
int object_size = reinterpret_cast<FixedTypedArrayBase*>(object)->size();
|
||||
EvacuateObject<DATA_OBJECT, kWordAligned>(map, slot, object, object_size);
|
||||
|
||||
MapWord map_word = object->map_word();
|
||||
DCHECK(map_word.IsForwardingAddress());
|
||||
FixedTypedArrayBase* target =
|
||||
reinterpret_cast<FixedTypedArrayBase*>(map_word.ToForwardingAddress());
|
||||
target->set_base_pointer(target, SKIP_WRITE_BARRIER);
|
||||
}
|
||||
|
||||
|
||||
@ -2428,6 +2434,12 @@ class ScavengingVisitor : public StaticVisitorBase {
|
||||
HeapObject* object) {
|
||||
int object_size = reinterpret_cast<FixedFloat64Array*>(object)->size();
|
||||
EvacuateObject<DATA_OBJECT, kDoubleAligned>(map, slot, object, object_size);
|
||||
|
||||
MapWord map_word = object->map_word();
|
||||
DCHECK(map_word.IsForwardingAddress());
|
||||
FixedTypedArrayBase* target =
|
||||
reinterpret_cast<FixedTypedArrayBase*>(map_word.ToForwardingAddress());
|
||||
target->set_base_pointer(target, SKIP_WRITE_BARRIER);
|
||||
}
|
||||
|
||||
|
||||
@ -3908,6 +3920,7 @@ AllocationResult Heap::AllocateFixedTypedArray(int length,
|
||||
|
||||
object->set_map(MapForFixedTypedArray(array_type));
|
||||
FixedTypedArrayBase* elements = FixedTypedArrayBase::cast(object);
|
||||
elements->set_base_pointer(elements, SKIP_WRITE_BARRIER);
|
||||
elements->set_length(length);
|
||||
if (initialize) memset(elements->DataPtr(), 0, elements->DataSize());
|
||||
return elements;
|
||||
|
@ -2779,7 +2779,12 @@ void MarkCompactCollector::MigrateObjectTagged(HeapObject* dst, HeapObject* src,
|
||||
|
||||
void MarkCompactCollector::MigrateObjectMixed(HeapObject* dst, HeapObject* src,
|
||||
int size) {
|
||||
if (FLAG_unbox_double_fields) {
|
||||
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);
|
||||
} else if (FLAG_unbox_double_fields) {
|
||||
Address dst_addr = dst->address();
|
||||
Address src_addr = src->address();
|
||||
Address src_slot = src_addr;
|
||||
@ -3198,7 +3203,10 @@ bool MarkCompactCollector::IsSlotInLiveObject(Address slot) {
|
||||
}
|
||||
|
||||
case HeapObjectContents::kMixedValues: {
|
||||
if (FLAG_unbox_double_fields) {
|
||||
if (object->IsFixedTypedArrayBase()) {
|
||||
return static_cast<int>(slot - object->address()) ==
|
||||
FixedTypedArrayBase::kBasePointerOffset;
|
||||
} 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());
|
||||
|
@ -498,7 +498,12 @@ void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) {
|
||||
}
|
||||
|
||||
case HeapObjectContents::kMixedValues: {
|
||||
if (FLAG_unbox_double_fields) {
|
||||
if (heap_object->IsFixedTypedArrayBase()) {
|
||||
FindPointersToNewSpaceInRegion(
|
||||
obj_address + FixedTypedArrayBase::kBasePointerOffset,
|
||||
obj_address + FixedTypedArrayBase::kHeaderSize,
|
||||
slot_callback);
|
||||
} else if (FLAG_unbox_double_fields) {
|
||||
LayoutDescriptorHelper helper(heap_object->map());
|
||||
DCHECK(!helper.all_fields_tagged());
|
||||
for (int offset = start_offset; offset < end_offset;) {
|
||||
|
@ -5928,6 +5928,11 @@ class HObjectAccess final {
|
||||
Representation::Smi());
|
||||
}
|
||||
|
||||
static HObjectAccess ForFixedTypedArrayBaseBasePointer() {
|
||||
return HObjectAccess(kInobject, FixedTypedArrayBase::kBasePointerOffset,
|
||||
Representation::Tagged());
|
||||
}
|
||||
|
||||
static HObjectAccess ForStringHashField() {
|
||||
return HObjectAccess(kInobject,
|
||||
String::kHashFieldOffset,
|
||||
|
@ -9916,6 +9916,8 @@ HValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray(
|
||||
Add<HStoreNamedField>(elements,
|
||||
HObjectAccess::ForFixedArrayLength(),
|
||||
length);
|
||||
Add<HStoreNamedField>(
|
||||
elements, HObjectAccess::ForFixedTypedArrayBaseBasePointer(), elements);
|
||||
|
||||
HValue* filler = Add<HConstant>(static_cast<int32_t>(0));
|
||||
|
||||
|
@ -241,6 +241,7 @@ void FixedTypedArray<Traits>::FixedTypedArrayVerify() {
|
||||
CHECK(IsHeapObject() &&
|
||||
HeapObject::cast(this)->map()->instance_type() ==
|
||||
Traits::kInstanceType);
|
||||
CHECK(base_pointer() == this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1538,6 +1538,9 @@ HeapObjectContents HeapObject::ContentType() {
|
||||
} else if (type == JS_FUNCTION_TYPE) {
|
||||
return HeapObjectContents::kMixedValues;
|
||||
#endif
|
||||
} else if (type >= FIRST_FIXED_TYPED_ARRAY_TYPE &&
|
||||
type <= LAST_FIXED_TYPED_ARRAY_TYPE) {
|
||||
return HeapObjectContents::kMixedValues;
|
||||
} else if (type <= LAST_DATA_TYPE) {
|
||||
// TODO(jochen): Why do we claim that Code and Map contain only raw values?
|
||||
return HeapObjectContents::kRawValues;
|
||||
@ -3877,6 +3880,9 @@ void ExternalFloat64Array::set(int index, double value) {
|
||||
}
|
||||
|
||||
|
||||
ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
|
||||
|
||||
|
||||
void* FixedTypedArrayBase::DataPtr() {
|
||||
return FIELD_ADDR(this, kDataOffset);
|
||||
}
|
||||
@ -7161,6 +7167,19 @@ void Foreign::ForeignIterateBody() {
|
||||
}
|
||||
|
||||
|
||||
void FixedTypedArrayBase::FixedTypedArrayBaseIterateBody(ObjectVisitor* v) {
|
||||
v->VisitPointer(
|
||||
reinterpret_cast<Object**>(FIELD_ADDR(this, kBasePointerOffset)));
|
||||
}
|
||||
|
||||
|
||||
template <typename StaticVisitor>
|
||||
void FixedTypedArrayBase::FixedTypedArrayBaseIterateBody() {
|
||||
StaticVisitor::VisitPointer(
|
||||
reinterpret_cast<Object**>(FIELD_ADDR(this, kBasePointerOffset)));
|
||||
}
|
||||
|
||||
|
||||
void ExternalOneByteString::ExternalOneByteStringIterateBody(ObjectVisitor* v) {
|
||||
typedef v8::String::ExternalOneByteStringResource Resource;
|
||||
v->VisitExternalOneByteString(
|
||||
|
@ -1478,10 +1478,15 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
|
||||
case FREE_SPACE_TYPE:
|
||||
break;
|
||||
|
||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
|
||||
case EXTERNAL_##TYPE##_ARRAY_TYPE: \
|
||||
case FIXED_##TYPE##_ARRAY_TYPE: \
|
||||
break;
|
||||
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
|
||||
case EXTERNAL_##TYPE##_ARRAY_TYPE: \
|
||||
break; \
|
||||
\
|
||||
case FIXED_##TYPE##_ARRAY_TYPE: \
|
||||
reinterpret_cast<FixedTypedArrayBase*>(this) \
|
||||
->FixedTypedArrayBaseIterateBody(v); \
|
||||
break;
|
||||
|
||||
|
||||
TYPED_ARRAYS(TYPED_ARRAY_CASE)
|
||||
#undef TYPED_ARRAY_CASE
|
||||
|
@ -4593,8 +4593,21 @@ class ExternalFloat64Array: public ExternalArray {
|
||||
|
||||
class FixedTypedArrayBase: public FixedArrayBase {
|
||||
public:
|
||||
// [base_pointer]: For now, points to the FixedTypedArrayBase itself.
|
||||
DECL_ACCESSORS(base_pointer, Object)
|
||||
|
||||
// Dispatched behavior.
|
||||
inline void FixedTypedArrayBaseIterateBody(ObjectVisitor* v);
|
||||
|
||||
template <typename StaticVisitor>
|
||||
inline void FixedTypedArrayBaseIterateBody();
|
||||
|
||||
DECLARE_CAST(FixedTypedArrayBase)
|
||||
|
||||
static const int kBasePointerOffset =
|
||||
FixedArrayBase::kHeaderSize + kPointerSize;
|
||||
static const int kHeaderSize = kBasePointerOffset + kPointerSize;
|
||||
|
||||
static const int kDataOffset = DOUBLE_POINTER_ALIGN(kHeaderSize);
|
||||
|
||||
inline int size();
|
||||
|
Loading…
Reference in New Issue
Block a user