Skip to content

Commit cc6d54c

Browse files
ripsawridgeV8 LUCI CQ
authored andcommitted
[compiler] Fix invalid MakeRef use in JSArrayRef::length_unsafe()
Since we are reading an Object field, it could be that the gc predicate fails. Therefore, this CL changes to TryMakeRef, and makes the return value of length_unsafe() optional. Bug: v8:7790, v8:12282 Change-Id: I86a8bcc6649d5e8121e52f8947b8331fcf242887 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3200078 Reviewed-by: Jakob Gruber <[email protected]> Commit-Queue: Michael Stanton <[email protected]> Cr-Commit-Position: refs/heads/main@{#77209}
1 parent 75c130a commit cc6d54c

File tree

2 files changed

+13
-9
lines changed

2 files changed

+13
-9
lines changed

src/compiler/heap-refs.cc

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2456,13 +2456,14 @@ ObjectRef JSArrayRef::GetBoilerplateLength() const {
24562456
// Safe to read concurrently because:
24572457
// - boilerplates are immutable after initialization.
24582458
// - boilerplates are published into the feedback vector.
2459-
return length_unsafe();
2459+
// These facts also mean we can expect a valid value.
2460+
return length_unsafe().value();
24602461
}
24612462

2462-
ObjectRef JSArrayRef::length_unsafe() const {
2463+
base::Optional<ObjectRef> JSArrayRef::length_unsafe() const {
24632464
if (data_->should_access_heap() || broker()->is_concurrent_inlining()) {
2464-
return MakeRef(broker(),
2465-
object()->length(broker()->isolate(), kRelaxedLoad));
2465+
return TryMakeRef(broker(),
2466+
object()->length(broker()->isolate(), kRelaxedLoad));
24662467
} else {
24672468
return ObjectRef{broker(), data()->AsJSArray()->length()};
24682469
}
@@ -2491,14 +2492,16 @@ base::Optional<ObjectRef> JSArrayRef::GetOwnCowElement(
24912492
// `elements`. We rely on the invariant that any `length` change will
24922493
// also result in an `elements` change to make this safe. The `elements`
24932494
// consistency check in the caller thus also guards the value of `length`.
2494-
ObjectRef length_ref = length_unsafe();
2495+
base::Optional<ObjectRef> length_ref = length_unsafe();
2496+
2497+
if (!length_ref.has_value()) return {};
24952498

24962499
// Likewise we only deal with smi lengths.
2497-
if (!length_ref.IsSmi()) return {};
2500+
if (!length_ref->IsSmi()) return {};
24982501

24992502
base::Optional<Object> result = ConcurrentLookupIterator::TryGetOwnCowElement(
25002503
broker()->isolate(), *elements_ref.AsFixedArray().object(), elements_kind,
2501-
length_ref.AsSmi(), index);
2504+
length_ref->AsSmi(), index);
25022505
if (!result.has_value()) return {};
25032506

25042507
return TryMakeRef(broker(), result.value());

src/compiler/heap-refs.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -866,8 +866,9 @@ class JSArrayRef : public JSObjectRef {
866866

867867
// The `JSArray::length` property; not safe to use in general, but can be
868868
// used in some special cases that guarantee a valid `length` value despite
869-
// concurrent reads.
870-
ObjectRef length_unsafe() const;
869+
// concurrent reads. The result needs to be optional in case the
870+
// return value was created too recently to pass the gc predicate.
871+
base::Optional<ObjectRef> length_unsafe() const;
871872
};
872873

873874
class ScopeInfoRef : public HeapObjectRef {

0 commit comments

Comments
 (0)