Commit ad0afdae authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[ubsan] Duplicate FixedArray{,Base} temporarily

In preparation for incrementally migrating subclasses to deriving
from FixedArrayPtr/FixedArrayBasePtr. Once that is done for all
subclasses, this duplication will be dropped again.

Bug: v8:3770
Change-Id: I6d664997fdcb18f7c0f37183d9f920ae30f3b749
Reviewed-on: https://chromium-review.googlesource.com/c/1345325Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57702}
parent a119ed63
...@@ -2046,6 +2046,11 @@ Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array, ...@@ -2046,6 +2046,11 @@ Handle<FixedArray> Factory::CopyFixedArrayWithMap(Handle<FixedArray> array,
Handle<Map> map) { Handle<Map> map) {
return CopyArrayWithMap(array, map); return CopyArrayWithMap(array, map);
} }
// TODO(3770): Replacement for the above, temporarily separate.
Handle<FixedArrayPtr> Factory::CopyFixedArrayWithMap(
Handle<FixedArrayPtr> array, Handle<Map> map) {
return CopyArrayWithMap(array, map);
}
Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array, Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array,
int grow_by, int grow_by,
......
...@@ -513,6 +513,8 @@ class V8_EXPORT_PRIVATE Factory { ...@@ -513,6 +513,8 @@ class V8_EXPORT_PRIVATE Factory {
Handle<FixedArray> CopyFixedArrayWithMap(Handle<FixedArray> array, Handle<FixedArray> CopyFixedArrayWithMap(Handle<FixedArray> array,
Handle<Map> map); Handle<Map> map);
Handle<FixedArrayPtr> CopyFixedArrayWithMap(Handle<FixedArrayPtr> array,
Handle<Map> map);
Handle<FixedArray> CopyFixedArrayAndGrow( Handle<FixedArray> CopyFixedArrayAndGrow(
Handle<FixedArray> array, int grow_by, Handle<FixedArray> array, int grow_by,
......
...@@ -10292,6 +10292,27 @@ Handle<FixedArray> FixedArray::SetAndGrow(Isolate* isolate, ...@@ -10292,6 +10292,27 @@ Handle<FixedArray> FixedArray::SetAndGrow(Isolate* isolate,
new_array->set(index, *value); new_array->set(index, *value);
return new_array; return new_array;
} }
Handle<FixedArrayPtr> FixedArrayPtr::SetAndGrow(Isolate* isolate,
Handle<FixedArrayPtr> array,
int index, Handle<Object> value,
PretenureFlag pretenure) {
if (index < array->length()) {
array->set(index, *value);
return array;
}
int capacity = array->length();
do {
capacity = JSObject::NewElementsCapacity(capacity);
} while (capacity <= index);
Handle<FixedArrayPtr> new_array(
isolate->factory()
->NewUninitializedFixedArray(capacity, pretenure)
.location());
array->CopyTo(0, *new_array, 0, array->length());
new_array->FillWithHoles(array->length(), new_array->length());
new_array->set(index, *value);
return new_array;
}
bool FixedArray::ContainsSortedNumbers() { bool FixedArray::ContainsSortedNumbers() {
for (int i = 1; i < length(); ++i) { for (int i = 1; i < length(); ++i) {
...@@ -10306,6 +10327,9 @@ bool FixedArray::ContainsSortedNumbers() { ...@@ -10306,6 +10327,9 @@ bool FixedArray::ContainsSortedNumbers() {
} }
return true; return true;
} }
bool FixedArrayPtr::ContainsSortedNumbers() {
return reinterpret_cast<FixedArray*>(ptr())->ContainsSortedNumbers();
}
Handle<FixedArray> FixedArray::ShrinkOrEmpty(Isolate* isolate, Handle<FixedArray> FixedArray::ShrinkOrEmpty(Isolate* isolate,
Handle<FixedArray> array, Handle<FixedArray> array,
...@@ -10317,6 +10341,18 @@ Handle<FixedArray> FixedArray::ShrinkOrEmpty(Isolate* isolate, ...@@ -10317,6 +10341,18 @@ Handle<FixedArray> FixedArray::ShrinkOrEmpty(Isolate* isolate,
return array; return array;
} }
} }
Handle<FixedArrayPtr> FixedArrayPtr::ShrinkOrEmpty(Isolate* isolate,
Handle<FixedArrayPtr> array,
int new_length) {
if (new_length == 0) {
// TODO(3770): Drop type conversion.
return Handle<FixedArrayPtr>(
array->GetReadOnlyRoots().empty_fixed_array_handle().location());
} else {
array->Shrink(isolate, new_length);
return array;
}
}
void FixedArray::Shrink(Isolate* isolate, int new_length) { void FixedArray::Shrink(Isolate* isolate, int new_length) {
DCHECK(0 < new_length && new_length <= length()); DCHECK(0 < new_length && new_length <= length());
...@@ -10324,6 +10360,13 @@ void FixedArray::Shrink(Isolate* isolate, int new_length) { ...@@ -10324,6 +10360,13 @@ void FixedArray::Shrink(Isolate* isolate, int new_length) {
isolate->heap()->RightTrimFixedArray(this, length() - new_length); isolate->heap()->RightTrimFixedArray(this, length() - new_length);
} }
} }
void FixedArrayPtr::Shrink(Isolate* isolate, int new_length) {
DCHECK(0 < new_length && new_length <= length());
if (new_length < length()) {
isolate->heap()->RightTrimFixedArray(reinterpret_cast<FixedArray*>(ptr()),
length() - new_length);
}
}
void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos,
int len) const { int len) const {
...@@ -10336,16 +10379,17 @@ void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, ...@@ -10336,16 +10379,17 @@ void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos,
dest->set(dest_pos+index, get(pos+index), mode); dest->set(dest_pos+index, get(pos+index), mode);
} }
} }
void FixedArrayPtr::CopyTo(int pos, FixedArrayPtr dest, int dest_pos,
#ifdef DEBUG int len) const {
bool FixedArray::IsEqualTo(FixedArray* other) { DisallowHeapAllocation no_gc;
if (length() != other->length()) return false; // Return early if len == 0 so that we don't try to read the write barrier off
for (int i = 0 ; i < length(); ++i) { // a canonical read-only empty fixed array.
if (get(i) != other->get(i)) return false; if (len == 0) return;
WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
for (int index = 0; index < len; index++) {
dest->set(dest_pos + index, get(pos + index), mode);
} }
return true;
} }
#endif
void JSObject::PrototypeRegistryCompactionCallback(HeapObject* value, void JSObject::PrototypeRegistryCompactionCallback(HeapObject* value,
int old_index, int old_index,
......
...@@ -18,10 +18,15 @@ ...@@ -18,10 +18,15 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
OBJECT_CONSTRUCTORS_IMPL(FixedArrayBasePtr, HeapObjectPtr)
OBJECT_CONSTRUCTORS_IMPL(FixedArrayPtr, FixedArrayBasePtr)
CAST_ACCESSOR(ArrayList) CAST_ACCESSOR(ArrayList)
CAST_ACCESSOR(ByteArray) CAST_ACCESSOR(ByteArray)
CAST_ACCESSOR(FixedArray) CAST_ACCESSOR(FixedArray)
CAST_ACCESSOR2(FixedArrayPtr)
CAST_ACCESSOR(FixedArrayBase) CAST_ACCESSOR(FixedArrayBase)
CAST_ACCESSOR2(FixedArrayBasePtr)
CAST_ACCESSOR(FixedDoubleArray) CAST_ACCESSOR(FixedDoubleArray)
CAST_ACCESSOR(FixedTypedArrayBase) CAST_ACCESSOR(FixedTypedArrayBase)
CAST_ACCESSOR(TemplateList) CAST_ACCESSOR(TemplateList)
...@@ -29,7 +34,9 @@ CAST_ACCESSOR(WeakFixedArray) ...@@ -29,7 +34,9 @@ CAST_ACCESSOR(WeakFixedArray)
CAST_ACCESSOR(WeakArrayList) CAST_ACCESSOR(WeakArrayList)
SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
SMI_ACCESSORS(FixedArrayBasePtr, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset) SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBasePtr, length, kLengthOffset)
SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset) SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset) SYNCHRONIZED_SMI_ACCESSORS(WeakFixedArray, length, kLengthOffset)
...@@ -40,12 +47,18 @@ SMI_ACCESSORS(WeakArrayList, length, kLengthOffset) ...@@ -40,12 +47,18 @@ SMI_ACCESSORS(WeakArrayList, length, kLengthOffset)
Object* FixedArrayBase::unchecked_synchronized_length() const { Object* FixedArrayBase::unchecked_synchronized_length() const {
return ACQUIRE_READ_FIELD(this, kLengthOffset); return ACQUIRE_READ_FIELD(this, kLengthOffset);
} }
Object* FixedArrayBasePtr::unchecked_synchronized_length() const {
return ACQUIRE_READ_FIELD(this, kLengthOffset);
}
ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset) ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
ObjectSlot FixedArray::GetFirstElementAddress() { ObjectSlot FixedArray::GetFirstElementAddress() {
return ObjectSlot(FIELD_ADDR(this, OffsetOfElementAt(0))); return ObjectSlot(FIELD_ADDR(this, OffsetOfElementAt(0)));
} }
ObjectSlot FixedArrayPtr::GetFirstElementAddress() {
return ObjectSlot(FIELD_ADDR(this, OffsetOfElementAt(0)));
}
bool FixedArray::ContainsOnlySmisOrHoles() { bool FixedArray::ContainsOnlySmisOrHoles() {
Object* the_hole = GetReadOnlyRoots().the_hole_value(); Object* the_hole = GetReadOnlyRoots().the_hole_value();
...@@ -56,15 +69,26 @@ bool FixedArray::ContainsOnlySmisOrHoles() { ...@@ -56,15 +69,26 @@ bool FixedArray::ContainsOnlySmisOrHoles() {
} }
return true; return true;
} }
bool FixedArrayPtr::ContainsOnlySmisOrHoles() {
return reinterpret_cast<FixedArray*>(ptr())->ContainsOnlySmisOrHoles();
}
Object* FixedArray::get(int index) const { Object* FixedArray::get(int index) const {
DCHECK(index >= 0 && index < this->length()); DCHECK(index >= 0 && index < this->length());
return RELAXED_READ_FIELD(this, kHeaderSize + index * kPointerSize); return RELAXED_READ_FIELD(this, kHeaderSize + index * kPointerSize);
} }
Object* FixedArrayPtr::get(int index) const {
DCHECK(index >= 0 && index < this->length());
return RELAXED_READ_FIELD(this, kHeaderSize + index * kPointerSize);
}
Handle<Object> FixedArray::get(FixedArray* array, int index, Isolate* isolate) { Handle<Object> FixedArray::get(FixedArray* array, int index, Isolate* isolate) {
return handle(array->get(index), isolate); return handle(array->get(index), isolate);
} }
Handle<Object> FixedArrayPtr::get(FixedArrayPtr array, int index,
Isolate* isolate) {
return handle(array->get(index), isolate);
}
template <class T> template <class T>
MaybeHandle<T> FixedArray::GetValue(Isolate* isolate, int index) const { MaybeHandle<T> FixedArray::GetValue(Isolate* isolate, int index) const {
...@@ -72,6 +96,12 @@ MaybeHandle<T> FixedArray::GetValue(Isolate* isolate, int index) const { ...@@ -72,6 +96,12 @@ MaybeHandle<T> FixedArray::GetValue(Isolate* isolate, int index) const {
if (obj->IsUndefined(isolate)) return MaybeHandle<T>(); if (obj->IsUndefined(isolate)) return MaybeHandle<T>();
return Handle<T>(T::cast(obj), isolate); return Handle<T>(T::cast(obj), isolate);
} }
template <class T>
MaybeHandle<T> FixedArrayPtr::GetValue(Isolate* isolate, int index) const {
Object* obj = get(index);
if (obj->IsUndefined(isolate)) return MaybeHandle<T>();
return Handle<T>(T::cast(obj), isolate);
}
template <class T> template <class T>
Handle<T> FixedArray::GetValueChecked(Isolate* isolate, int index) const { Handle<T> FixedArray::GetValueChecked(Isolate* isolate, int index) const {
...@@ -79,10 +109,19 @@ Handle<T> FixedArray::GetValueChecked(Isolate* isolate, int index) const { ...@@ -79,10 +109,19 @@ Handle<T> FixedArray::GetValueChecked(Isolate* isolate, int index) const {
CHECK(!obj->IsUndefined(isolate)); CHECK(!obj->IsUndefined(isolate));
return Handle<T>(T::cast(obj), isolate); return Handle<T>(T::cast(obj), isolate);
} }
template <class T>
Handle<T> FixedArrayPtr::GetValueChecked(Isolate* isolate, int index) const {
Object* obj = get(index);
CHECK(!obj->IsUndefined(isolate));
return Handle<T>(T::cast(obj), isolate);
}
bool FixedArray::is_the_hole(Isolate* isolate, int index) { bool FixedArray::is_the_hole(Isolate* isolate, int index) {
return get(index)->IsTheHole(isolate); return get(index)->IsTheHole(isolate);
} }
bool FixedArrayPtr::is_the_hole(Isolate* isolate, int index) {
return get(index)->IsTheHole(isolate);
}
void FixedArray::set(int index, Smi value) { void FixedArray::set(int index, Smi value) {
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map()); DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
...@@ -91,6 +130,9 @@ void FixedArray::set(int index, Smi value) { ...@@ -91,6 +130,9 @@ void FixedArray::set(int index, Smi value) {
int offset = kHeaderSize + index * kPointerSize; int offset = kHeaderSize + index * kPointerSize;
RELAXED_WRITE_FIELD(this, offset, value); RELAXED_WRITE_FIELD(this, offset, value);
} }
void FixedArrayPtr::set(int index, Smi value) {
reinterpret_cast<FixedArray*>(ptr())->set(index, value);
}
void FixedArray::set(int index, Object* value) { void FixedArray::set(int index, Object* value) {
DCHECK_NE(GetReadOnlyRoots().fixed_cow_array_map(), map()); DCHECK_NE(GetReadOnlyRoots().fixed_cow_array_map(), map());
...@@ -101,6 +143,9 @@ void FixedArray::set(int index, Object* value) { ...@@ -101,6 +143,9 @@ void FixedArray::set(int index, Object* value) {
RELAXED_WRITE_FIELD(this, offset, value); RELAXED_WRITE_FIELD(this, offset, value);
WRITE_BARRIER(this, offset, value); WRITE_BARRIER(this, offset, value);
} }
void FixedArrayPtr::set(int index, Object* value) {
reinterpret_cast<FixedArray*>(ptr())->set(index, value);
}
void FixedArray::set(int index, Object* value, WriteBarrierMode mode) { void FixedArray::set(int index, Object* value, WriteBarrierMode mode) {
DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map()); DCHECK_NE(map(), GetReadOnlyRoots().fixed_cow_array_map());
...@@ -110,6 +155,9 @@ void FixedArray::set(int index, Object* value, WriteBarrierMode mode) { ...@@ -110,6 +155,9 @@ void FixedArray::set(int index, Object* value, WriteBarrierMode mode) {
RELAXED_WRITE_FIELD(this, offset, value); RELAXED_WRITE_FIELD(this, offset, value);
CONDITIONAL_WRITE_BARRIER(this, offset, value, mode); CONDITIONAL_WRITE_BARRIER(this, offset, value, mode);
} }
void FixedArrayPtr::set(int index, Object* value, WriteBarrierMode mode) {
reinterpret_cast<FixedArray*>(ptr())->set(index, value, mode);
}
void FixedArray::NoWriteBarrierSet(FixedArray* array, int index, void FixedArray::NoWriteBarrierSet(FixedArray* array, int index,
Object* value) { Object* value) {
...@@ -119,24 +167,44 @@ void FixedArray::NoWriteBarrierSet(FixedArray* array, int index, ...@@ -119,24 +167,44 @@ void FixedArray::NoWriteBarrierSet(FixedArray* array, int index,
DCHECK(!Heap::InNewSpace(value)); DCHECK(!Heap::InNewSpace(value));
RELAXED_WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); RELAXED_WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
} }
void FixedArrayPtr::NoWriteBarrierSet(FixedArrayPtr array, int index,
Object* value) {
DCHECK_NE(array->map(), array->GetReadOnlyRoots().fixed_cow_array_map());
DCHECK_GE(index, 0);
DCHECK_LT(index, array->length());
DCHECK(!Heap::InNewSpace(value));
RELAXED_WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
}
void FixedArray::set_undefined(int index) { void FixedArray::set_undefined(int index) {
set_undefined(GetReadOnlyRoots(), index); set_undefined(GetReadOnlyRoots(), index);
} }
void FixedArrayPtr::set_undefined(int index) {
reinterpret_cast<FixedArray*>(ptr())->set_undefined(index);
}
void FixedArray::set_undefined(Isolate* isolate, int index) { void FixedArray::set_undefined(Isolate* isolate, int index) {
set_undefined(ReadOnlyRoots(isolate), index); set_undefined(ReadOnlyRoots(isolate), index);
} }
void FixedArrayPtr::set_undefined(Isolate* isolate, int index) {
reinterpret_cast<FixedArray*>(ptr())->set_undefined(isolate, index);
}
void FixedArray::set_undefined(ReadOnlyRoots ro_roots, int index) { void FixedArray::set_undefined(ReadOnlyRoots ro_roots, int index) {
FixedArray::NoWriteBarrierSet(this, index, ro_roots.undefined_value()); FixedArray::NoWriteBarrierSet(this, index, ro_roots.undefined_value());
} }
void FixedArray::set_null(int index) { set_null(GetReadOnlyRoots(), index); } void FixedArray::set_null(int index) { set_null(GetReadOnlyRoots(), index); }
void FixedArrayPtr::set_null(int index) {
reinterpret_cast<FixedArray*>(ptr())->set_null(index);
}
void FixedArray::set_null(Isolate* isolate, int index) { void FixedArray::set_null(Isolate* isolate, int index) {
set_null(ReadOnlyRoots(isolate), index); set_null(ReadOnlyRoots(isolate), index);
} }
void FixedArrayPtr::set_null(Isolate* isolate, int index) {
reinterpret_cast<FixedArray*>(ptr())->set_null(isolate, index);
}
void FixedArray::set_null(ReadOnlyRoots ro_roots, int index) { void FixedArray::set_null(ReadOnlyRoots ro_roots, int index) {
FixedArray::NoWriteBarrierSet(this, index, ro_roots.null_value()); FixedArray::NoWriteBarrierSet(this, index, ro_roots.null_value());
...@@ -145,10 +213,16 @@ void FixedArray::set_null(ReadOnlyRoots ro_roots, int index) { ...@@ -145,10 +213,16 @@ void FixedArray::set_null(ReadOnlyRoots ro_roots, int index) {
void FixedArray::set_the_hole(int index) { void FixedArray::set_the_hole(int index) {
set_the_hole(GetReadOnlyRoots(), index); set_the_hole(GetReadOnlyRoots(), index);
} }
void FixedArrayPtr::set_the_hole(int index) {
reinterpret_cast<FixedArray*>(ptr())->set_the_hole(index);
}
void FixedArray::set_the_hole(Isolate* isolate, int index) { void FixedArray::set_the_hole(Isolate* isolate, int index) {
set_the_hole(ReadOnlyRoots(isolate), index); set_the_hole(ReadOnlyRoots(isolate), index);
} }
void FixedArrayPtr::set_the_hole(Isolate* isolate, int index) {
reinterpret_cast<FixedArray*>(ptr())->set_the_hole(isolate, index);
}
void FixedArray::set_the_hole(ReadOnlyRoots ro_roots, int index) { void FixedArray::set_the_hole(ReadOnlyRoots ro_roots, int index) {
FixedArray::NoWriteBarrierSet(this, index, ro_roots.the_hole_value()); FixedArray::NoWriteBarrierSet(this, index, ro_roots.the_hole_value());
...@@ -159,20 +233,37 @@ void FixedArray::FillWithHoles(int from, int to) { ...@@ -159,20 +233,37 @@ void FixedArray::FillWithHoles(int from, int to) {
set_the_hole(i); set_the_hole(i);
} }
} }
void FixedArrayPtr::FillWithHoles(int from, int to) {
for (int i = from; i < to; i++) {
set_the_hole(i);
}
}
ObjectSlot FixedArray::data_start() { ObjectSlot FixedArray::data_start() {
return HeapObject::RawField(this, OffsetOfElementAt(0)); return HeapObject::RawField(this, OffsetOfElementAt(0));
} }
ObjectSlot FixedArrayPtr::data_start() {
return RawField(OffsetOfElementAt(0));
}
ObjectSlot FixedArray::RawFieldOfElementAt(int index) { ObjectSlot FixedArray::RawFieldOfElementAt(int index) {
return HeapObject::RawField(this, OffsetOfElementAt(index)); return HeapObject::RawField(this, OffsetOfElementAt(index));
} }
ObjectSlot FixedArrayPtr::RawFieldOfElementAt(int index) {
return RawField(OffsetOfElementAt(index));
}
void FixedArray::MoveElements(Heap* heap, int dst_index, int src_index, int len, void FixedArray::MoveElements(Heap* heap, int dst_index, int src_index, int len,
WriteBarrierMode mode) { WriteBarrierMode mode) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
heap->MoveElements(this, dst_index, src_index, len, mode); heap->MoveElements(this, dst_index, src_index, len, mode);
} }
void FixedArrayPtr::MoveElements(Heap* heap, int dst_index, int src_index,
int len, WriteBarrierMode mode) {
DisallowHeapAllocation no_gc;
heap->MoveElements(reinterpret_cast<FixedArray*>(ptr()), dst_index, src_index,
len, mode);
}
double FixedDoubleArray::get_scalar(int index) { double FixedDoubleArray::get_scalar(int index) {
DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() && DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
......
...@@ -102,6 +102,43 @@ class FixedArrayBase : public HeapObject { ...@@ -102,6 +102,43 @@ class FixedArrayBase : public HeapObject {
static const int kHeaderSize = kLengthOffset + kPointerSize; static const int kHeaderSize = kLengthOffset + kPointerSize;
}; };
// TODO(3770): Replacement for the above.
class FixedArrayBasePtr : public HeapObjectPtr {
public:
// [length]: length of the array.
inline int length() const;
inline void set_length(int value);
// Get and set the length using acquire loads and release stores.
inline int synchronized_length() const;
inline void synchronized_set_length(int value);
inline Object* unchecked_synchronized_length() const;
// TODO(3770): Temporary.
operator FixedArrayBase*() const {
return reinterpret_cast<FixedArrayBase*>(ptr());
}
DECL_CAST2(FixedArrayBasePtr)
// Maximal allowed size, in bytes, of a single FixedArrayBase.
// Prevents overflowing size computations, as well as extreme memory
// consumption.
#ifdef V8_HOST_ARCH_32_BIT
static const int kMaxSize = 512 * MB;
#else
static const int kMaxSize = 1024 * MB;
#endif // V8_HOST_ARCH_32_BIT
// Layout description.
// Length is smi tagged when it is stored.
static const int kLengthOffset = FixedArrayBase::kLengthOffset;
static const int kHeaderSize = FixedArrayBase::kHeaderSize;
OBJECT_CONSTRUCTORS(FixedArrayBasePtr, HeapObjectPtr)
};
// FixedArray describes fixed-sized arrays with element type Object*. // FixedArray describes fixed-sized arrays with element type Object*.
class FixedArray : public FixedArrayBase { class FixedArray : public FixedArrayBase {
public: public:
...@@ -187,10 +224,6 @@ class FixedArray : public FixedArrayBase { ...@@ -187,10 +224,6 @@ class FixedArray : public FixedArrayBase {
// Dispatched behavior. // Dispatched behavior.
DECL_PRINTER(FixedArray) DECL_PRINTER(FixedArray)
DECL_VERIFIER(FixedArray) DECL_VERIFIER(FixedArray)
#ifdef DEBUG
// Checks if two FixedArrays have identical contents.
bool IsEqualTo(FixedArray* other);
#endif
typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor; typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
...@@ -210,6 +243,105 @@ class FixedArray : public FixedArrayBase { ...@@ -210,6 +243,105 @@ class FixedArray : public FixedArrayBase {
DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray); DISALLOW_IMPLICIT_CONSTRUCTORS(FixedArray);
}; };
// TODO(3770): Replacement for the above.
class FixedArrayPtr : public FixedArrayBasePtr {
public:
// TODO(3770): Temporary.
operator FixedArray*() const { return reinterpret_cast<FixedArray*>(ptr()); }
// Setter and getter for elements.
inline Object* get(int index) const;
static inline Handle<Object> get(FixedArrayPtr array, int index,
Isolate* isolate);
template <class T>
MaybeHandle<T> GetValue(Isolate* isolate, int index) const;
template <class T>
Handle<T> GetValueChecked(Isolate* isolate, int index) const;
// Return a grown copy if the index is bigger than the array's length.
static Handle<FixedArrayPtr> SetAndGrow(
Isolate* isolate, Handle<FixedArrayPtr> array, int index,
Handle<Object> value, PretenureFlag pretenure = NOT_TENURED);
// Setter that uses write barrier.
inline void set(int index, Object* value);
inline bool is_the_hole(Isolate* isolate, int index);
// Setter that doesn't need write barrier.
inline void set(int index, Smi value);
// Setter with explicit barrier mode.
inline void set(int index, Object* value, WriteBarrierMode mode);
// Setters for frequently used oddballs located in old space.
inline void set_undefined(int index);
inline void set_undefined(Isolate* isolate, int index);
inline void set_null(int index);
inline void set_null(Isolate* isolate, int index);
inline void set_the_hole(int index);
inline void set_the_hole(Isolate* isolate, int index);
inline ObjectSlot GetFirstElementAddress();
inline bool ContainsOnlySmisOrHoles();
// Returns true iff the elements are Numbers and sorted ascending.
bool ContainsSortedNumbers();
// Gives access to raw memory which stores the array's data.
inline ObjectSlot data_start();
inline void MoveElements(Heap* heap, int dst_index, int src_index, int len,
WriteBarrierMode mode);
inline void FillWithHoles(int from, int to);
// Shrink the array and insert filler objects. {new_length} must be > 0.
void Shrink(Isolate* isolate, int new_length);
// If {new_length} is 0, return the canonical empty FixedArray. Otherwise
// like above.
static Handle<FixedArrayPtr> ShrinkOrEmpty(Isolate* isolate,
Handle<FixedArrayPtr> array,
int new_length);
// Copy a sub array from the receiver to dest.
void CopyTo(int pos, FixedArrayPtr dest, int dest_pos, int len) const;
// Garbage collection support.
static constexpr int SizeFor(int length) {
return kHeaderSize + length * kPointerSize;
}
// Code Generation support.
static constexpr int OffsetOfElementAt(int index) { return SizeFor(index); }
// Garbage collection support.
inline ObjectSlot RawFieldOfElementAt(int index);
DECL_CAST2(FixedArrayPtr)
// Maximally allowed length of a FixedArray.
static const int kMaxLength = (kMaxSize - kHeaderSize) / kPointerSize;
static_assert(Internals::IsValidSmi(kMaxLength),
"FixedArray maxLength not a Smi");
// Maximally allowed length for regular (non large object space) object.
STATIC_ASSERT(kMaxRegularHeapObjectSize < kMaxSize);
static const int kMaxRegularLength =
(kMaxRegularHeapObjectSize - kHeaderSize) / kPointerSize;
// Dispatched behavior.
DECL_PRINTER(FixedArrayPtr)
DECL_VERIFIER(FixedArrayPtr)
typedef FlexibleBodyDescriptor<kHeaderSize> BodyDescriptor;
protected:
// Set operation on FixedArray without using write barriers. Can
// only be used for storing old space objects or smis.
static inline void NoWriteBarrierSet(FixedArrayPtr array, int index,
Object* value);
OBJECT_CONSTRUCTORS(FixedArrayPtr, FixedArrayBasePtr)
};
// FixedArray alias added only because of IsFixedArrayExact() predicate, which // FixedArray alias added only because of IsFixedArrayExact() predicate, which
// checks for the exact instance type FIXED_ARRAY_TYPE instead of a range // checks for the exact instance type FIXED_ARRAY_TYPE instead of a range
// check: [FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE]. // check: [FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE].
......
...@@ -46,6 +46,13 @@ STRUCT_LIST(TYPE_CHECK_FORWARDER) ...@@ -46,6 +46,13 @@ STRUCT_LIST(TYPE_CHECK_FORWARDER)
ODDBALL_LIST(TYPE_CHECK_FORWARDER) ODDBALL_LIST(TYPE_CHECK_FORWARDER)
#undef TYPE_CHECK_FORWARDER #undef TYPE_CHECK_FORWARDER
bool ObjectPtr::IsFixedArrayBasePtr() const {
return reinterpret_cast<Object*>(ptr())->IsFixedArrayBase();
}
bool ObjectPtr::IsFixedArrayPtr() const {
return reinterpret_cast<Object*>(ptr())->IsFixedArray();
}
double ObjectPtr::Number() const { double ObjectPtr::Number() const {
return reinterpret_cast<Object*>(ptr())->Number(); return reinterpret_cast<Object*>(ptr())->Number();
} }
......
...@@ -57,6 +57,10 @@ class ObjectPtr { ...@@ -57,6 +57,10 @@ class ObjectPtr {
ODDBALL_LIST(IS_TYPE_FUNCTION_DECL) ODDBALL_LIST(IS_TYPE_FUNCTION_DECL)
#undef IS_TYPE_FUNCTION_DECL #undef IS_TYPE_FUNCTION_DECL
// TODO(3770): Drop these after migrating the respective classes:
inline bool IsFixedArrayBasePtr() const;
inline bool IsFixedArrayPtr() const;
inline bool IsObject() const { return true; } inline bool IsObject() const { return true; }
inline double Number() const; inline double Number() const;
inline bool ToInt32(int32_t* value) const; inline bool ToInt32(int32_t* value) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment