mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:07:11 +00:00
[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:
parent
ba5e72ebe4
commit
1702a66338
3 changed files with 27 additions and 14 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue