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

[compiler] Introduce TinyRef and use it in CreateArrayParameters

Bug: v8:7790
Change-Id: I299678102254ffb7d68be3d5cad11b4a4161492f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3068947
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Auto-Submit: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76118}
parent f2477023
......@@ -3160,6 +3160,29 @@ ObjectData* ObjectRef::data() const {
}
}
template <class T>
typename TinyRef<T>::RefType TinyRef<T>::AsRef(JSHeapBroker* broker) const {
if (data_->kind() == kUnserializedHeapObject &&
broker->mode() != JSHeapBroker::kDisabled) {
// Gotta reconstruct to avoid returning a stale unserialized ref.
return MakeRefAssumeMemoryFence<T>(broker,
Handle<T>::cast(data_->object()));
}
return TryMakeRef<T>(broker, data_).value();
}
template <class T>
Handle<T> TinyRef<T>::object() const {
return Handle<T>::cast(data_->object());
}
#define V(Name) \
template class TinyRef<Name>; \
/* TinyRef should contain only one pointer. */ \
STATIC_ASSERT(sizeof(TinyRef<Name>) == kSystemPointerSize);
HEAP_BROKER_OBJECT_LIST(V)
#undef V
Reduction NoChangeBecauseOfMissingData(JSHeapBroker* broker,
const char* function, int line) {
TRACE_MISSING(broker, "data in function " << function << " at line " << line);
......
......@@ -187,6 +187,31 @@ struct ref_traits<Object> {
RefSerializationKind::kNeverSerialized;
};
// A ref without the broker_ field, used when storage size is important.
template <class T>
class TinyRef {
private:
using RefType = typename ref_traits<T>::ref_type;
public:
explicit TinyRef(const RefType& ref) : TinyRef(ref.data_) {}
RefType AsRef(JSHeapBroker* broker) const;
static base::Optional<RefType> AsOptionalRef(JSHeapBroker* broker,
base::Optional<TinyRef<T>> ref) {
if (!ref.has_value()) return {};
return ref->AsRef(broker);
}
Handle<T> object() const;
private:
explicit TinyRef(ObjectData* data) : data_(data) { DCHECK_NOT_NULL(data); }
ObjectData* const data_;
};
#define V(Name) using Name##TinyRef = TinyRef<Name>;
HEAP_BROKER_OBJECT_LIST(V)
#undef V
class V8_EXPORT_PRIVATE ObjectRef {
public:
ObjectRef(JSHeapBroker* broker, ObjectData* data, bool check_type = true)
......@@ -244,6 +269,8 @@ class V8_EXPORT_PRIVATE ObjectRef {
friend class JSHeapBroker;
friend class JSObjectData;
friend class StringData;
template <class T>
friend class TinyRef;
friend std::ostream& operator<<(std::ostream& os, const ObjectRef& ref);
......
......@@ -1120,9 +1120,9 @@ TNode<Object> JSCallReducerAssembler::CopyNode() {
TNode<JSArray> JSCallReducerAssembler::CreateArrayNoThrow(
TNode<Object> ctor, TNode<Number> size, FrameState frame_state) {
return AddNode<JSArray>(graph()->NewNode(
javascript()->CreateArray(1, MaybeHandle<AllocationSite>()), ctor, ctor,
size, ContextInput(), frame_state, effect(), control()));
return AddNode<JSArray>(
graph()->NewNode(javascript()->CreateArray(1, base::nullopt), ctor, ctor,
size, ContextInput(), frame_state, effect(), control()));
}
TNode<JSArray> JSCallReducerAssembler::AllocateEmptyJSArray(
ElementsKind kind, const NativeContextRef& native_context) {
......@@ -2421,8 +2421,8 @@ Reduction JSCallReducer::ReduceArrayConstructor(Node* node) {
node->RemoveInput(n.FeedbackVectorIndex());
NodeProperties::ReplaceValueInput(node, target, 0);
NodeProperties::ReplaceValueInput(node, target, 1);
NodeProperties::ChangeOp(
node, javascript()->CreateArray(arity, MaybeHandle<AllocationSite>()));
NodeProperties::ChangeOp(node,
javascript()->CreateArray(arity, base::nullopt));
return Changed(node);
}
......@@ -4977,8 +4977,8 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
node->ReplaceInput(n.NewTargetIndex(), array_function);
node->RemoveInput(n.FeedbackVectorIndex());
NodeProperties::ChangeOp(
node, javascript()->CreateArray(
arity, feedback_target->AsAllocationSite().object()));
node, javascript()->CreateArray(arity,
feedback_target->AsAllocationSite()));
return Changed(node);
} else if (feedback_target.has_value() &&
!HeapObjectMatcher(new_target).HasResolvedValue() &&
......@@ -5044,7 +5044,7 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
node->ReplaceInput(n.NewTargetIndex(), new_target);
node->RemoveInput(n.FeedbackVectorIndex());
NodeProperties::ChangeOp(
node, javascript()->CreateArray(arity, Handle<AllocationSite>()));
node, javascript()->CreateArray(arity, base::nullopt));
return Changed(node);
}
case Builtin::kObjectConstructor: {
......
......@@ -618,13 +618,7 @@ Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) {
DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
int const arity = static_cast<int>(p.arity());
base::Optional<AllocationSiteRef> site_ref;
{
Handle<AllocationSite> site;
if (p.site().ToHandle(&site)) {
site_ref = MakeRef(broker(), site);
}
}
base::Optional<AllocationSiteRef> site_ref = p.site(broker());
AllocationType allocation = AllocationType::kYoung;
base::Optional<MapRef> initial_map =
......
......@@ -596,12 +596,10 @@ void JSGenericLowering::LowerJSCreateArray(Node* node) {
DCHECK_EQ(interface_descriptor.GetStackParameterCount(), 0);
Node* stub_code = jsgraph()->ArrayConstructorStubConstant();
Node* stub_arity = jsgraph()->Int32Constant(arity);
MaybeHandle<AllocationSite> const maybe_site = p.site();
Handle<AllocationSite> site;
DCHECK_IMPLIES(broker()->is_native_context_independent(),
maybe_site.is_null());
Node* type_info = maybe_site.ToHandle(&site) ? jsgraph()->HeapConstant(site)
: jsgraph()->UndefinedConstant();
base::Optional<AllocationSiteRef> const site = p.site(broker());
DCHECK_IMPLIES(broker()->is_native_context_independent(), !site.has_value());
Node* type_info = site.has_value() ? jsgraph()->Constant(site.value())
: jsgraph()->UndefinedConstant();
Node* receiver = jsgraph()->UndefinedConstant();
node->InsertInput(zone(), 0, stub_code);
node->InsertInput(zone(), 3, stub_arity);
......
......@@ -36,9 +36,7 @@ Reduction JSHeapCopyReducer::Reduce(Node* node) {
break;
}
case IrOpcode::kJSCreateArray: {
CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
Handle<AllocationSite> site;
if (p.site().ToHandle(&site)) MakeRef(broker(), site);
CreateArrayParametersOf(node->op()).site(broker());
break;
}
case IrOpcode::kJSCreateArguments: {
......
......@@ -391,11 +391,20 @@ CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op) {
return OpParameter<CreateArgumentsType>(op);
}
namespace {
template <class T>
Address AddressOrNull(base::Optional<T> ref) {
if (!ref.has_value()) return kNullAddress;
return ref->object().address();
}
} // namespace
bool operator==(CreateArrayParameters const& lhs,
CreateArrayParameters const& rhs) {
return lhs.arity() == rhs.arity() &&
lhs.site().address() == rhs.site().address();
AddressOrNull(lhs.site_) == AddressOrNull(rhs.site_);
}
......@@ -406,14 +415,15 @@ bool operator!=(CreateArrayParameters const& lhs,
size_t hash_value(CreateArrayParameters const& p) {
return base::hash_combine(p.arity(), p.site().address());
return base::hash_combine(p.arity(), AddressOrNull(p.site_));
}
std::ostream& operator<<(std::ostream& os, CreateArrayParameters const& p) {
os << p.arity();
Handle<AllocationSite> site;
if (p.site().ToHandle(&site)) os << ", " << Brief(*site);
if (p.site_.has_value()) {
os << ", " << Brief(*p.site_->object());
}
return os;
}
......@@ -1235,7 +1245,7 @@ const Operator* JSOperatorBuilder::CreateArguments(CreateArgumentsType type) {
}
const Operator* JSOperatorBuilder::CreateArray(
size_t arity, MaybeHandle<AllocationSite> site) {
size_t arity, base::Optional<AllocationSiteRef> site) {
// constructor, new_target, arg1, ..., argN
int const value_input_count = static_cast<int>(arity) + 2;
CreateArrayParameters parameters(arity, site);
......
......@@ -555,24 +555,26 @@ CreateArgumentsType const& CreateArgumentsTypeOf(const Operator* op);
// used as parameter by JSCreateArray operators.
class CreateArrayParameters final {
public:
explicit CreateArrayParameters(size_t arity, MaybeHandle<AllocationSite> site)
CreateArrayParameters(size_t arity, base::Optional<AllocationSiteRef> site)
: arity_(arity), site_(site) {}
size_t arity() const { return arity_; }
MaybeHandle<AllocationSite> site() const { return site_; }
base::Optional<AllocationSiteRef> site(JSHeapBroker* broker) const {
return AllocationSiteTinyRef::AsOptionalRef(broker, site_);
}
private:
size_t const arity_;
MaybeHandle<AllocationSite> const site_;
base::Optional<AllocationSiteTinyRef> const site_;
friend bool operator==(CreateArrayParameters const&,
CreateArrayParameters const&);
friend bool operator!=(CreateArrayParameters const&,
CreateArrayParameters const&);
friend size_t hash_value(CreateArrayParameters const&);
friend std::ostream& operator<<(std::ostream&, CreateArrayParameters const&);
};
bool operator==(CreateArrayParameters const&, CreateArrayParameters const&);
bool operator!=(CreateArrayParameters const&, CreateArrayParameters const&);
size_t hash_value(CreateArrayParameters const&);
std::ostream& operator<<(std::ostream&, CreateArrayParameters const&);
const CreateArrayParameters& CreateArrayParametersOf(const Operator* op);
// Defines shared information for the array iterator that should be created.
......@@ -904,7 +906,8 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* Create();
const Operator* CreateArguments(CreateArgumentsType type);
const Operator* CreateArray(size_t arity, MaybeHandle<AllocationSite> site);
const Operator* CreateArray(size_t arity,
base::Optional<AllocationSiteRef> site);
const Operator* CreateArrayIterator(IterationKind);
const Operator* CreateAsyncFunctionObject(int register_count);
const Operator* CreateCollectionIterator(CollectionKind, IterationKind);
......
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