11cb0ef41Sopenharmony_ci// Copyright 2019 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_COMPILER_PROCESSED_FEEDBACK_H_
61cb0ef41Sopenharmony_ci#define V8_COMPILER_PROCESSED_FEEDBACK_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/compiler/feedback-source.h"
91cb0ef41Sopenharmony_ci#include "src/compiler/heap-refs.h"
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cinamespace v8 {
121cb0ef41Sopenharmony_cinamespace internal {
131cb0ef41Sopenharmony_cinamespace compiler {
141cb0ef41Sopenharmony_ci
151cb0ef41Sopenharmony_ciclass BinaryOperationFeedback;
161cb0ef41Sopenharmony_ciclass CallFeedback;
171cb0ef41Sopenharmony_ciclass CompareOperationFeedback;
181cb0ef41Sopenharmony_ciclass ElementAccessFeedback;
191cb0ef41Sopenharmony_ciclass ForInFeedback;
201cb0ef41Sopenharmony_ciclass GlobalAccessFeedback;
211cb0ef41Sopenharmony_ciclass InstanceOfFeedback;
221cb0ef41Sopenharmony_ciclass LiteralFeedback;
231cb0ef41Sopenharmony_ciclass NamedAccessFeedback;
241cb0ef41Sopenharmony_ciclass RegExpLiteralFeedback;
251cb0ef41Sopenharmony_ciclass TemplateObjectFeedback;
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ciclass ProcessedFeedback : public ZoneObject {
281cb0ef41Sopenharmony_ci public:
291cb0ef41Sopenharmony_ci  enum Kind {
301cb0ef41Sopenharmony_ci    kInsufficient,
311cb0ef41Sopenharmony_ci    kBinaryOperation,
321cb0ef41Sopenharmony_ci    kCall,
331cb0ef41Sopenharmony_ci    kCompareOperation,
341cb0ef41Sopenharmony_ci    kElementAccess,
351cb0ef41Sopenharmony_ci    kForIn,
361cb0ef41Sopenharmony_ci    kGlobalAccess,
371cb0ef41Sopenharmony_ci    kInstanceOf,
381cb0ef41Sopenharmony_ci    kLiteral,
391cb0ef41Sopenharmony_ci    kNamedAccess,
401cb0ef41Sopenharmony_ci    kRegExpLiteral,
411cb0ef41Sopenharmony_ci    kTemplateObject,
421cb0ef41Sopenharmony_ci  };
431cb0ef41Sopenharmony_ci  Kind kind() const { return kind_; }
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  FeedbackSlotKind slot_kind() const { return slot_kind_; }
461cb0ef41Sopenharmony_ci  bool IsInsufficient() const { return kind() == kInsufficient; }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  BinaryOperationFeedback const& AsBinaryOperation() const;
491cb0ef41Sopenharmony_ci  CallFeedback const& AsCall() const;
501cb0ef41Sopenharmony_ci  CompareOperationFeedback const& AsCompareOperation() const;
511cb0ef41Sopenharmony_ci  ElementAccessFeedback const& AsElementAccess() const;
521cb0ef41Sopenharmony_ci  ForInFeedback const& AsForIn() const;
531cb0ef41Sopenharmony_ci  GlobalAccessFeedback const& AsGlobalAccess() const;
541cb0ef41Sopenharmony_ci  InstanceOfFeedback const& AsInstanceOf() const;
551cb0ef41Sopenharmony_ci  NamedAccessFeedback const& AsNamedAccess() const;
561cb0ef41Sopenharmony_ci  LiteralFeedback const& AsLiteral() const;
571cb0ef41Sopenharmony_ci  RegExpLiteralFeedback const& AsRegExpLiteral() const;
581cb0ef41Sopenharmony_ci  TemplateObjectFeedback const& AsTemplateObject() const;
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci protected:
611cb0ef41Sopenharmony_ci  ProcessedFeedback(Kind kind, FeedbackSlotKind slot_kind);
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci private:
641cb0ef41Sopenharmony_ci  Kind const kind_;
651cb0ef41Sopenharmony_ci  FeedbackSlotKind const slot_kind_;
661cb0ef41Sopenharmony_ci};
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ciclass InsufficientFeedback final : public ProcessedFeedback {
691cb0ef41Sopenharmony_ci public:
701cb0ef41Sopenharmony_ci  explicit InsufficientFeedback(FeedbackSlotKind slot_kind);
711cb0ef41Sopenharmony_ci};
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ciclass GlobalAccessFeedback : public ProcessedFeedback {
741cb0ef41Sopenharmony_ci public:
751cb0ef41Sopenharmony_ci  GlobalAccessFeedback(PropertyCellRef cell, FeedbackSlotKind slot_kind);
761cb0ef41Sopenharmony_ci  GlobalAccessFeedback(ContextRef script_context, int slot_index,
771cb0ef41Sopenharmony_ci                       bool immutable, FeedbackSlotKind slot_kind);
781cb0ef41Sopenharmony_ci  explicit GlobalAccessFeedback(FeedbackSlotKind slot_kind);  // Megamorphic
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  bool IsMegamorphic() const;
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci  bool IsPropertyCell() const;
831cb0ef41Sopenharmony_ci  PropertyCellRef property_cell() const;
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ci  bool IsScriptContextSlot() const;
861cb0ef41Sopenharmony_ci  ContextRef script_context() const;
871cb0ef41Sopenharmony_ci  int slot_index() const;
881cb0ef41Sopenharmony_ci  bool immutable() const;
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  base::Optional<ObjectRef> GetConstantHint() const;
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci private:
931cb0ef41Sopenharmony_ci  base::Optional<ObjectRef> const cell_or_context_;
941cb0ef41Sopenharmony_ci  int const index_and_immutable_;
951cb0ef41Sopenharmony_ci};
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ciclass KeyedAccessMode {
981cb0ef41Sopenharmony_ci public:
991cb0ef41Sopenharmony_ci  static KeyedAccessMode FromNexus(FeedbackNexus const& nexus);
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ci  AccessMode access_mode() const;
1021cb0ef41Sopenharmony_ci  bool IsLoad() const;
1031cb0ef41Sopenharmony_ci  bool IsStore() const;
1041cb0ef41Sopenharmony_ci  KeyedAccessLoadMode load_mode() const;
1051cb0ef41Sopenharmony_ci  KeyedAccessStoreMode store_mode() const;
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci private:
1081cb0ef41Sopenharmony_ci  AccessMode const access_mode_;
1091cb0ef41Sopenharmony_ci  union LoadStoreMode {
1101cb0ef41Sopenharmony_ci    LoadStoreMode(KeyedAccessLoadMode load_mode);
1111cb0ef41Sopenharmony_ci    LoadStoreMode(KeyedAccessStoreMode store_mode);
1121cb0ef41Sopenharmony_ci    KeyedAccessLoadMode load_mode;
1131cb0ef41Sopenharmony_ci    KeyedAccessStoreMode store_mode;
1141cb0ef41Sopenharmony_ci  } const load_store_mode_;
1151cb0ef41Sopenharmony_ci
1161cb0ef41Sopenharmony_ci  KeyedAccessMode(AccessMode access_mode, KeyedAccessLoadMode load_mode);
1171cb0ef41Sopenharmony_ci  KeyedAccessMode(AccessMode access_mode, KeyedAccessStoreMode store_mode);
1181cb0ef41Sopenharmony_ci};
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ciclass ElementAccessFeedback : public ProcessedFeedback {
1211cb0ef41Sopenharmony_ci public:
1221cb0ef41Sopenharmony_ci  ElementAccessFeedback(Zone* zone, KeyedAccessMode const& keyed_mode,
1231cb0ef41Sopenharmony_ci                        FeedbackSlotKind slot_kind);
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci  KeyedAccessMode keyed_mode() const;
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci  // A transition group is a target and a possibly empty set of sources that can
1281cb0ef41Sopenharmony_ci  // transition to the target. It is represented as a non-empty vector with the
1291cb0ef41Sopenharmony_ci  // target at index 0.
1301cb0ef41Sopenharmony_ci  using TransitionGroup = ZoneVector<Handle<Map>>;
1311cb0ef41Sopenharmony_ci  ZoneVector<TransitionGroup> const& transition_groups() const;
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  bool HasOnlyStringMaps(JSHeapBroker* broker) const;
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  void AddGroup(TransitionGroup&& group);
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  // Refine {this} by trying to restrict it to the maps in {inferred_maps}. A
1381cb0ef41Sopenharmony_ci  // transition group's target is kept iff it is in {inferred_maps} or if more
1391cb0ef41Sopenharmony_ci  // than one of its sources is in {inferred_maps}. Here's an (unrealistic)
1401cb0ef41Sopenharmony_ci  // example showing all the possible situations:
1411cb0ef41Sopenharmony_ci  //
1421cb0ef41Sopenharmony_ci  // inferred_maps = [a0, a2, c1, c2, d1, e0, e1]
1431cb0ef41Sopenharmony_ci  //
1441cb0ef41Sopenharmony_ci  // Groups before:                     Groups after:
1451cb0ef41Sopenharmony_ci  // [a0, a1, a2]                       [a0, a2]
1461cb0ef41Sopenharmony_ci  // [b0]
1471cb0ef41Sopenharmony_ci  // [c0, c1, c2, c3]                   [c0, c1, c2]
1481cb0ef41Sopenharmony_ci  // [d0, d1]                           [d1]
1491cb0ef41Sopenharmony_ci  // [e0, e1]                           [e0, e1]
1501cb0ef41Sopenharmony_ci  //
1511cb0ef41Sopenharmony_ci  ElementAccessFeedback const& Refine(
1521cb0ef41Sopenharmony_ci      JSHeapBroker* broker, ZoneVector<MapRef> const& inferred_maps) const;
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci private:
1551cb0ef41Sopenharmony_ci  KeyedAccessMode const keyed_mode_;
1561cb0ef41Sopenharmony_ci  ZoneVector<TransitionGroup> transition_groups_;
1571cb0ef41Sopenharmony_ci};
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ciclass NamedAccessFeedback : public ProcessedFeedback {
1601cb0ef41Sopenharmony_ci public:
1611cb0ef41Sopenharmony_ci  NamedAccessFeedback(NameRef const& name, ZoneVector<MapRef> const& maps,
1621cb0ef41Sopenharmony_ci                      FeedbackSlotKind slot_kind);
1631cb0ef41Sopenharmony_ci
1641cb0ef41Sopenharmony_ci  NameRef const& name() const { return name_; }
1651cb0ef41Sopenharmony_ci  ZoneVector<MapRef> const& maps() const { return maps_; }
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci private:
1681cb0ef41Sopenharmony_ci  NameRef const name_;
1691cb0ef41Sopenharmony_ci  ZoneVector<MapRef> const maps_;
1701cb0ef41Sopenharmony_ci};
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ciclass CallFeedback : public ProcessedFeedback {
1731cb0ef41Sopenharmony_ci public:
1741cb0ef41Sopenharmony_ci  CallFeedback(base::Optional<HeapObjectRef> target, float frequency,
1751cb0ef41Sopenharmony_ci               SpeculationMode mode, CallFeedbackContent call_feedback_content,
1761cb0ef41Sopenharmony_ci               FeedbackSlotKind slot_kind)
1771cb0ef41Sopenharmony_ci      : ProcessedFeedback(kCall, slot_kind),
1781cb0ef41Sopenharmony_ci        target_(target),
1791cb0ef41Sopenharmony_ci        frequency_(frequency),
1801cb0ef41Sopenharmony_ci        mode_(mode),
1811cb0ef41Sopenharmony_ci        content_(call_feedback_content) {}
1821cb0ef41Sopenharmony_ci
1831cb0ef41Sopenharmony_ci  base::Optional<HeapObjectRef> target() const { return target_; }
1841cb0ef41Sopenharmony_ci  float frequency() const { return frequency_; }
1851cb0ef41Sopenharmony_ci  SpeculationMode speculation_mode() const { return mode_; }
1861cb0ef41Sopenharmony_ci  CallFeedbackContent call_feedback_content() const { return content_; }
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ci private:
1891cb0ef41Sopenharmony_ci  base::Optional<HeapObjectRef> const target_;
1901cb0ef41Sopenharmony_ci  float const frequency_;
1911cb0ef41Sopenharmony_ci  SpeculationMode const mode_;
1921cb0ef41Sopenharmony_ci  CallFeedbackContent const content_;
1931cb0ef41Sopenharmony_ci};
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_citemplate <class T, ProcessedFeedback::Kind K>
1961cb0ef41Sopenharmony_ciclass SingleValueFeedback : public ProcessedFeedback {
1971cb0ef41Sopenharmony_ci public:
1981cb0ef41Sopenharmony_ci  explicit SingleValueFeedback(T value, FeedbackSlotKind slot_kind)
1991cb0ef41Sopenharmony_ci      : ProcessedFeedback(K, slot_kind), value_(value) {
2001cb0ef41Sopenharmony_ci    DCHECK(
2011cb0ef41Sopenharmony_ci        (K == kBinaryOperation && slot_kind == FeedbackSlotKind::kBinaryOp) ||
2021cb0ef41Sopenharmony_ci        (K == kCompareOperation && slot_kind == FeedbackSlotKind::kCompareOp) ||
2031cb0ef41Sopenharmony_ci        (K == kForIn && slot_kind == FeedbackSlotKind::kForIn) ||
2041cb0ef41Sopenharmony_ci        (K == kInstanceOf && slot_kind == FeedbackSlotKind::kInstanceOf) ||
2051cb0ef41Sopenharmony_ci        ((K == kLiteral || K == kRegExpLiteral || K == kTemplateObject) &&
2061cb0ef41Sopenharmony_ci         slot_kind == FeedbackSlotKind::kLiteral));
2071cb0ef41Sopenharmony_ci  }
2081cb0ef41Sopenharmony_ci
2091cb0ef41Sopenharmony_ci  T value() const { return value_; }
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ci private:
2121cb0ef41Sopenharmony_ci  T const value_;
2131cb0ef41Sopenharmony_ci};
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ciclass InstanceOfFeedback
2161cb0ef41Sopenharmony_ci    : public SingleValueFeedback<base::Optional<JSObjectRef>,
2171cb0ef41Sopenharmony_ci                                 ProcessedFeedback::kInstanceOf> {
2181cb0ef41Sopenharmony_ci  using SingleValueFeedback::SingleValueFeedback;
2191cb0ef41Sopenharmony_ci};
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_ciclass LiteralFeedback
2221cb0ef41Sopenharmony_ci    : public SingleValueFeedback<AllocationSiteRef,
2231cb0ef41Sopenharmony_ci                                 ProcessedFeedback::kLiteral> {
2241cb0ef41Sopenharmony_ci  using SingleValueFeedback::SingleValueFeedback;
2251cb0ef41Sopenharmony_ci};
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ciclass RegExpLiteralFeedback
2281cb0ef41Sopenharmony_ci    : public SingleValueFeedback<RegExpBoilerplateDescriptionRef,
2291cb0ef41Sopenharmony_ci                                 ProcessedFeedback::kRegExpLiteral> {
2301cb0ef41Sopenharmony_ci  using SingleValueFeedback::SingleValueFeedback;
2311cb0ef41Sopenharmony_ci};
2321cb0ef41Sopenharmony_ci
2331cb0ef41Sopenharmony_ciclass TemplateObjectFeedback
2341cb0ef41Sopenharmony_ci    : public SingleValueFeedback<JSArrayRef,
2351cb0ef41Sopenharmony_ci                                 ProcessedFeedback::kTemplateObject> {
2361cb0ef41Sopenharmony_ci  using SingleValueFeedback::SingleValueFeedback;
2371cb0ef41Sopenharmony_ci};
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ciclass BinaryOperationFeedback
2401cb0ef41Sopenharmony_ci    : public SingleValueFeedback<BinaryOperationHint,
2411cb0ef41Sopenharmony_ci                                 ProcessedFeedback::kBinaryOperation> {
2421cb0ef41Sopenharmony_ci  using SingleValueFeedback::SingleValueFeedback;
2431cb0ef41Sopenharmony_ci};
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ciclass CompareOperationFeedback
2461cb0ef41Sopenharmony_ci    : public SingleValueFeedback<CompareOperationHint,
2471cb0ef41Sopenharmony_ci                                 ProcessedFeedback::kCompareOperation> {
2481cb0ef41Sopenharmony_ci  using SingleValueFeedback::SingleValueFeedback;
2491cb0ef41Sopenharmony_ci};
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ciclass ForInFeedback
2521cb0ef41Sopenharmony_ci    : public SingleValueFeedback<ForInHint, ProcessedFeedback::kForIn> {
2531cb0ef41Sopenharmony_ci  using SingleValueFeedback::SingleValueFeedback;
2541cb0ef41Sopenharmony_ci};
2551cb0ef41Sopenharmony_ci
2561cb0ef41Sopenharmony_ci}  // namespace compiler
2571cb0ef41Sopenharmony_ci}  // namespace internal
2581cb0ef41Sopenharmony_ci}  // namespace v8
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci#endif  // V8_COMPILER_PROCESSED_FEEDBACK_H_
261