Commit 12779b16 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Use unchecked length getter for concurrent marking of FixedArray.

If the fixed array is being concurrently left-trimmed then checked
getter can assert because the length is not necessarily a Smi.

This patch uses unchecked length getter to cache the length as Object*.
Only if the marker manages to color the array black, we are guaranteed
that the cached length is a Smi.

This patch also uses unchecked cast for FixedArray in HeapVisitor
for concurrent marker.

Note that this patch only affects debug mode.

Bug: chromium:694255
Change-Id: I5016a2234a9f5fb98b498e06f5d1428b3f1cc3c6
Reviewed-on: https://chromium-review.googlesource.com/817554
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49970}
parent bbf43d84
......@@ -187,9 +187,14 @@ class ConcurrentMarkingVisitor final
// ===========================================================================
int VisitFixedArray(Map* map, FixedArray* object) {
int length = object->synchronized_length();
int size = FixedArray::SizeFor(length);
// The synchronized_length() function checks that the length is a Smi.
// This is not necessarily the case if the array is being left-trimmed.
Object* length = object->unchecked_synchronized_length();
if (!ShouldVisit(object)) return 0;
// The cached length must be the actual length as the array is not black.
// Left trimming marks the array black before over-writing the length.
DCHECK(length->IsSmi());
int size = FixedArray::SizeFor(Smi::ToInt(length));
VisitMapPointer(object, object->map_slot());
FixedArray::BodyDescriptor::IterateBody(object, size, this);
return size;
......@@ -382,6 +387,12 @@ SeqTwoByteString* ConcurrentMarkingVisitor::Cast(HeapObject* object) {
return reinterpret_cast<SeqTwoByteString*>(object);
}
// Fixed array can become a free space during left trimming.
template <>
FixedArray* ConcurrentMarkingVisitor::Cast(HeapObject* object) {
return reinterpret_cast<FixedArray*>(object);
}
class ConcurrentMarking::Task : public CancelableTask {
public:
Task(Isolate* isolate, ConcurrentMarking* concurrent_marking,
......
......@@ -30,6 +30,10 @@ CAST_ACCESSOR(WeakFixedArray)
SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
SYNCHRONIZED_SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
Object* FixedArrayBase::unchecked_synchronized_length() const {
return ACQUIRE_READ_FIELD(this, kLengthOffset);
}
ACCESSORS(FixedTypedArrayBase, base_pointer, Object, kBasePointerOffset)
Object** FixedArray::GetFirstElementAddress() {
......
......@@ -74,6 +74,8 @@ class FixedArrayBase : public HeapObject {
inline int synchronized_length() const;
inline void synchronized_set_length(int value);
inline Object* unchecked_synchronized_length() const;
DECL_CAST(FixedArrayBase)
static int GetMaxLengthForNewSpaceAllocation(ElementsKind kind);
......
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