Commit ca7f2852 authored by Jakob Gruber's avatar Jakob Gruber Committed by V8 LUCI CQ

[compiler] Introduce TryMakeRef/MakeRef factory functions

In the near future we'll have more cases where Ref construction is not
guaranteed to succeed. Currently, we don't have convenient patterns to
support optional construction. This CL adds the following helpers:

 base::Optional<FooRef> ref = TryMakeRef(broker, o);
 if (!ref.has_value()) return {};  // bailout
 // .. use ref.

Or, in the case where construction is guaranteed to succeed:

 FooRef ref = MakeRef(broker, o);
 // .. use ref.

Bug: v8:7790
Change-Id: I759235c314056c080d79ec413125d3957452c64c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2859169Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74325}
parent 15803e5f
This diff is collapsed.
......@@ -151,23 +151,10 @@ class ObjectData : public ZoneObject {
namespace {
template <class T>
constexpr RefSerializationKind RefSerializationKindOf() {
CONSTEXPR_DCHECK(false); // The default impl should never be called.
return RefSerializationKind::kSerialized;
}
#define DEFINE_REF_SERIALIZATION_KIND(Name, Kind) \
template <> \
constexpr RefSerializationKind RefSerializationKindOf<Name>() { \
return Kind; \
}
HEAP_BROKER_OBJECT_LIST(DEFINE_REF_SERIALIZATION_KIND)
#undef DEFINE_REF_SERIALIZATION_KIND
template <class T>
constexpr bool IsSerializedRef() {
return RefSerializationKindOf<T>() == RefSerializationKind::kSerialized;
return ref_traits<T>::ref_serialization_kind ==
RefSerializationKind::kSerialized;
}
RefSerializationKind RefSerializationKindOf(ObjectData* const data) {
......@@ -178,7 +165,7 @@ RefSerializationKind RefSerializationKindOf(ObjectData* const data) {
} \
/* NOLINTNEXTLINE(readability/braces) */ \
else if (o.Is##Name()) { \
return RefSerializationKindOf<Name>();
return ref_traits<Name>::ref_serialization_kind;
HEAP_BROKER_OBJECT_LIST(DEFINE_REF_SERIALIZATION_KIND)
#undef DEFINE_REF_SERIALIZATION_KIND
}
......@@ -3225,7 +3212,7 @@ base::Optional<ObjectRef> FixedArrayRef::TryGet(int i) const {
}
Float64 FixedDoubleArrayRef::GetFromImmutableFixedDoubleArray(int i) const {
STATIC_ASSERT(RefSerializationKindOf<FixedDoubleArray>() ==
STATIC_ASSERT(ref_traits<FixedDoubleArray>::ref_serialization_kind ==
RefSerializationKind::kNeverSerialized);
return Float64::FromBits(object()->get_representation(i));
}
......
......@@ -40,7 +40,12 @@ struct WasmModule;
namespace compiler {
class CompilationDependencies;
struct FeedbackSource;
class JSHeapBroker;
class ObjectData;
class PerIsolateCompilerCache;
class PropertyAccessInfo;
// Whether we are loading a property or storing to a property.
// For a store during literal creation, do not walk up the prototype chain.
......@@ -131,16 +136,22 @@ enum class RefSerializationKind {
/* Subtypes of Object */ \
V(HeapObject, RefSerializationKind::kBackgroundSerialized)
class CompilationDependencies;
struct FeedbackSource;
class JSHeapBroker;
class ObjectData;
class PerIsolateCompilerCache;
class PropertyAccessInfo;
#define FORWARD_DECL(Name, ...) class Name##Ref;
HEAP_BROKER_OBJECT_LIST(FORWARD_DECL)
#undef FORWARD_DECL
template <class T>
struct ref_traits;
#define REF_TRAITS(Name, Kind) \
template <> \
struct ref_traits<Name> { \
using ref_type = Name##Ref; \
static constexpr RefSerializationKind ref_serialization_kind = Kind; \
};
HEAP_BROKER_OBJECT_LIST(REF_TRAITS)
#undef REF_TYPE
class V8_EXPORT_PRIVATE ObjectRef {
public:
enum class BackgroundSerialization {
......
......@@ -11,6 +11,7 @@
#include "src/compiler/access-info.h"
#include "src/compiler/feedback-source.h"
#include "src/compiler/globals.h"
#include "src/compiler/heap-refs.h"
#include "src/compiler/processed-feedback.h"
#include "src/compiler/refs-map.h"
#include "src/compiler/serializer-hints.h"
......@@ -557,6 +558,27 @@ class V8_NODISCARD UnparkedScopeIfNeeded {
base::Optional<UnparkedScope> unparked_scope;
};
// Usage:
//
// base::Optional<FooRef> ref = TryMakeRef(broker, o);
// if (!ref.has_value()) return {}; // bailout
//
// or
//
// FooRef ref = MakeRef(broker, o);
template <class T>
base::Optional<typename ref_traits<T>::ref_type> TryMakeRef(
JSHeapBroker* broker, T object) {
ObjectData* data = broker->TryGetOrCreateData(object);
if (data == nullptr) return {};
return {typename ref_traits<T>::ref_type(broker, data)};
}
template <class T>
typename ref_traits<T>::ref_type MakeRef(JSHeapBroker* broker, T object) {
return TryMakeRef(broker, object).value();
}
} // namespace compiler
} // namespace internal
} // namespace v8
......
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