[vm/concurrency] Guard Field::length updates.

Issue https://github.com/dart-lang/sdk/issues/36097.

TEST=existing test suite

Change-Id: Id345b3f700d731270606b096f9b1225267eea606
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/173402
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
This commit is contained in:
Alexander Aprelev 2020-11-30 16:29:42 +00:00 committed by commit-bot@chromium.org
parent ba5e72ebe4
commit 1702a66338
3 changed files with 27 additions and 14 deletions

View file

@ -1142,8 +1142,8 @@ class FieldDeserializationCluster : public DeserializationCluster {
field ^= refs.At(i);
field.set_guarded_cid_unsafe(kDynamicCid);
field.set_is_nullable_unsafe(true);
field.set_guarded_list_length(Field::kNoFixedLength);
field.set_guarded_list_length_in_object_offset(
field.set_guarded_list_length_unsafe(Field::kNoFixedLength);
field.set_guarded_list_length_in_object_offset_unsafe(
Field::kUnknownLengthOffset);
field.set_static_type_exactness_state(
StaticTypeExactnessState::NotTracking());
@ -1151,7 +1151,7 @@ class FieldDeserializationCluster : public DeserializationCluster {
} else {
for (intptr_t i = start_index_; i < stop_index_; i++) {
field ^= refs.At(i);
field.InitializeGuardedListLengthInObjectOffset();
field.InitializeGuardedListLengthInObjectOffset(/*unsafe=*/true);
}
}
}

View file

@ -10130,12 +10130,13 @@ void Field::InitializeNew(const Field& result,
#endif // !defined(PRODUCT)
result.set_guarded_cid_unsafe(use_guarded_cid ? kIllegalCid : kDynamicCid);
result.set_is_nullable_unsafe(use_guarded_cid ? false : true);
result.set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
result.set_guarded_list_length_in_object_offset_unsafe(
Field::kUnknownLengthOffset);
// Presently, we only attempt to remember the list length for final fields.
if (is_final && use_guarded_cid) {
result.set_guarded_list_length(Field::kUnknownFixedLength);
result.set_guarded_list_length_unsafe(Field::kUnknownFixedLength);
} else {
result.set_guarded_list_length(Field::kNoFixedLength);
result.set_guarded_list_length_unsafe(Field::kNoFixedLength);
}
}
@ -10219,7 +10220,7 @@ intptr_t Field::guarded_list_length() const {
return Smi::Value(raw_ptr()->guarded_list_length_);
}
void Field::set_guarded_list_length(intptr_t list_length) const {
void Field::set_guarded_list_length_unsafe(intptr_t list_length) const {
ASSERT(Thread::Current()->IsMutatorThread());
ASSERT(IsOriginal());
StoreSmi(&raw_ptr()->guarded_list_length_, Smi::New(list_length));
@ -10229,7 +10230,7 @@ intptr_t Field::guarded_list_length_in_object_offset() const {
return raw_ptr()->guarded_list_length_in_object_offset_ + kHeapObjectTag;
}
void Field::set_guarded_list_length_in_object_offset(
void Field::set_guarded_list_length_in_object_offset_unsafe(
intptr_t list_length_offset) const {
ASSERT(Thread::Current()->IsMutatorThread());
ASSERT(IsOriginal());
@ -10610,15 +10611,17 @@ const char* Field::GuardedPropertiesAsCString() const {
class_name, exactness);
}
void Field::InitializeGuardedListLengthInObjectOffset() const {
void Field::InitializeGuardedListLengthInObjectOffset(bool unsafe) const {
auto setter = unsafe ? &Field::set_guarded_list_length_in_object_offset_unsafe
: &Field::set_guarded_list_length_in_object_offset;
ASSERT(IsOriginal());
if (needs_length_check() &&
(guarded_list_length() != Field::kUnknownFixedLength)) {
const intptr_t offset = GetListLengthOffset(guarded_cid());
set_guarded_list_length_in_object_offset(offset);
(this->*setter)(offset);
ASSERT(offset != Field::kUnknownLengthOffset);
} else {
set_guarded_list_length_in_object_offset(Field::kUnknownLengthOffset);
(this->*setter)(Field::kUnknownLengthOffset);
}
}

View file

@ -4188,12 +4188,22 @@ class Field : public Object {
// been determined. If length is kNoFixedLength this field has multiple
// list lengths associated with it and cannot be predicted.
intptr_t guarded_list_length() const;
void set_guarded_list_length(intptr_t list_length) const;
void set_guarded_list_length_unsafe(intptr_t list_length) const;
void set_guarded_list_length(intptr_t list_length) const {
DEBUG_ASSERT(
IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
set_guarded_list_length_unsafe(list_length);
}
static intptr_t guarded_list_length_offset() {
return OFFSET_OF(FieldLayout, guarded_list_length_);
}
intptr_t guarded_list_length_in_object_offset() const;
void set_guarded_list_length_in_object_offset(intptr_t offset) const;
void set_guarded_list_length_in_object_offset_unsafe(intptr_t offset) const;
void set_guarded_list_length_in_object_offset(intptr_t offset) const {
DEBUG_ASSERT(
IsolateGroup::Current()->program_lock()->IsCurrentThreadWriter());
set_guarded_list_length_in_object_offset_unsafe(offset);
}
static intptr_t guarded_list_length_in_object_offset_offset() {
return OFFSET_OF(FieldLayout, guarded_list_length_in_object_offset_);
}
@ -4273,7 +4283,7 @@ class Field : public Object {
// deoptimization of dependent optimized code.
void RecordStore(const Object& value) const;
void InitializeGuardedListLengthInObjectOffset() const;
void InitializeGuardedListLengthInObjectOffset(bool unsafe = false) const;
// Return the list of optimized code objects that were optimized under
// assumptions about guarded class id and nullability of this field.