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