[compiler] Replace EnsureElementsTenured by IsElementsTenured

We can't mutate heap state from the compiler thread; turn this into a
predicate and emit generic code if it returns false.

Bug: v8:7790
Change-Id: I6186a87e178d0c0206b6e7659fa2a41bf65fd835
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2876845
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74596}
This commit is contained in:
Jakob Gruber 2021-05-10 14:39:30 +02:00 committed by V8 LUCI CQ
parent 0b507c5eb0
commit 6d99f9334b
3 changed files with 8 additions and 25 deletions

View File

@ -2346,22 +2346,14 @@ void JSObjectData::SerializeRecursiveAsBoilerplate(JSHeapBroker* broker,
Isolate* const isolate = broker->isolate(); Isolate* const isolate = broker->isolate();
Handle<FixedArrayBase> elements_object(boilerplate->elements(), isolate); Handle<FixedArrayBase> elements_object(boilerplate->elements(), isolate);
// Boilerplates need special serialization - we need to make sure COW arrays // Boilerplate objects should only be reachable from their allocation site,
// are tenured. Boilerplate objects should only be reachable from their // so it is safe to assume that the elements have not been serialized yet.
// allocation site, so it is safe to assume that the elements have not been
// serialized yet.
bool const empty_or_cow = bool const empty_or_cow =
elements_object->length() == 0 || elements_object->length() == 0 ||
elements_object->map() == ReadOnlyRoots(isolate).fixed_cow_array_map(); elements_object->map() == ReadOnlyRoots(isolate).fixed_cow_array_map();
if (empty_or_cow) { if (empty_or_cow) {
// We need to make sure copy-on-write elements are tenured. cow_or_empty_elements_tenured_ = !ObjectInYoungGeneration(*elements_object);
if (ObjectInYoungGeneration(*elements_object)) {
elements_object = isolate->factory()->CopyAndTenureFixedCOWArray(
Handle<FixedArray>::cast(elements_object));
boilerplate->set_elements(*elements_object);
}
cow_or_empty_elements_tenured_ = true;
} }
DCHECK_NULL(elements_); DCHECK_NULL(elements_);
@ -3015,21 +3007,12 @@ void JSObjectRef::SerializeElements() {
data()->AsJSObject()->SerializeElements(broker()); data()->AsJSObject()->SerializeElements(broker());
} }
void JSObjectRef::EnsureElementsTenured() { bool JSObjectRef::IsElementsTenured() {
if (data_->should_access_heap()) { if (data_->should_access_heap()) {
Handle<FixedArrayBase> object_elements = elements().value().object(); Handle<FixedArrayBase> object_elements = elements().value().object();
if (ObjectInYoungGeneration(*object_elements)) { return !ObjectInYoungGeneration(*object_elements);
// If we would like to pretenure a fixed cow array, we must ensure that
// the array is already in old space, otherwise we'll create too many
// old-to-new-space pointers (overflowing the store buffer).
object_elements =
broker()->isolate()->factory()->CopyAndTenureFixedCOWArray(
Handle<FixedArray>::cast(object_elements));
object()->set_elements(*object_elements);
}
return;
} }
CHECK(data()->AsJSObject()->cow_or_empty_elements_tenured()); return data()->AsJSObject()->cow_or_empty_elements_tenured();
} }
FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const { FieldIndex MapRef::GetFieldIndexFor(InternalIndex descriptor_index) const {

View File

@ -336,7 +336,7 @@ class JSObjectRef : public JSReceiverRef {
base::Optional<FixedArrayBaseRef> elements() const; base::Optional<FixedArrayBaseRef> elements() const;
void SerializeElements(); void SerializeElements();
void EnsureElementsTenured(); bool IsElementsTenured();
ElementsKind GetElementsKind() const; ElementsKind GetElementsKind() const;
void SerializeObjectCreateMap(); void SerializeObjectCreateMap();

View File

@ -1763,7 +1763,7 @@ base::Optional<Node*> JSCreateLowering::TryAllocateFastLiteralElements(
MapRef elements_map = boilerplate_elements.map(); MapRef elements_map = boilerplate_elements.map();
if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) { if (boilerplate_elements.length() == 0 || elements_map.IsFixedCowArrayMap()) {
if (allocation == AllocationType::kOld) { if (allocation == AllocationType::kOld) {
boilerplate.EnsureElementsTenured(); if (!boilerplate.IsElementsTenured()) return {};
boilerplate_elements = boilerplate.elements().value(); boilerplate_elements = boilerplate.elements().value();
} }
return jsgraph()->HeapConstant(boilerplate_elements.object()); return jsgraph()->HeapConstant(boilerplate_elements.object());