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_MAP_INFERENCE_H_
61cb0ef41Sopenharmony_ci#define V8_COMPILER_MAP_INFERENCE_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "include/v8config.h"
91cb0ef41Sopenharmony_ci#include "src/compiler/graph-reducer.h"
101cb0ef41Sopenharmony_ci#include "src/objects/instance-type.h"
111cb0ef41Sopenharmony_ci#include "src/objects/map.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace internal {
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cinamespace compiler {
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_ciclass CompilationDependencies;
201cb0ef41Sopenharmony_cistruct FeedbackSource;
211cb0ef41Sopenharmony_ciclass JSGraph;
221cb0ef41Sopenharmony_ciclass JSHeapBroker;
231cb0ef41Sopenharmony_ciclass Node;
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci// The MapInference class provides access to the "inferred" maps of an
261cb0ef41Sopenharmony_ci// {object}. This information can be either "reliable", meaning that the object
271cb0ef41Sopenharmony_ci// is guaranteed to have one of these maps at runtime, or "unreliable", meaning
281cb0ef41Sopenharmony_ci// that the object is guaranteed to have HAD one of these maps.
291cb0ef41Sopenharmony_ci//
301cb0ef41Sopenharmony_ci// The MapInference class does not expose whether or not the information is
311cb0ef41Sopenharmony_ci// reliable. A client is expected to eventually make the information reliable by
321cb0ef41Sopenharmony_ci// calling one of several methods that will either insert map checks, or record
331cb0ef41Sopenharmony_ci// stability dependencies (or do nothing if the information was already
341cb0ef41Sopenharmony_ci// reliable).
351cb0ef41Sopenharmony_ciclass MapInference {
361cb0ef41Sopenharmony_ci public:
371cb0ef41Sopenharmony_ci  MapInference(JSHeapBroker* broker, Node* object, Effect effect);
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  // The destructor checks that the information has been made reliable (if
401cb0ef41Sopenharmony_ci  // necessary) and force-crashes if not.
411cb0ef41Sopenharmony_ci  ~MapInference();
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  // Is there any information at all?
441cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool HaveMaps() const;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  // These queries don't require a guard.
471cb0ef41Sopenharmony_ci  //
481cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool AllOfInstanceTypesAreJSReceiver() const;
491cb0ef41Sopenharmony_ci  // Here, {type} must not be a String type.
501cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool AllOfInstanceTypesAre(InstanceType type) const;
511cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool AnyOfInstanceTypesAre(InstanceType type) const;
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci  // These queries require a guard. (Even instance types are generally not
541cb0ef41Sopenharmony_ci  // reliable because of how the representation of a string can change.)
551cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT ZoneVector<MapRef> const& GetMaps();
561cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool AllOfInstanceTypes(
571cb0ef41Sopenharmony_ci      std::function<bool(InstanceType)> f);
581cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool Is(const MapRef& expected_map);
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  // These methods provide a guard.
611cb0ef41Sopenharmony_ci  //
621cb0ef41Sopenharmony_ci  // Returns true iff maps were already reliable or stability dependencies were
631cb0ef41Sopenharmony_ci  // successfully recorded.
641cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool RelyOnMapsViaStability(
651cb0ef41Sopenharmony_ci      CompilationDependencies* dependencies);
661cb0ef41Sopenharmony_ci  // Records stability dependencies if possible, otherwise it inserts map
671cb0ef41Sopenharmony_ci  // checks. Does nothing if maps were already reliable. Returns true iff
681cb0ef41Sopenharmony_ci  // dependencies were taken.
691cb0ef41Sopenharmony_ci  bool RelyOnMapsPreferStability(CompilationDependencies* dependencies,
701cb0ef41Sopenharmony_ci                                 JSGraph* jsgraph, Effect* effect,
711cb0ef41Sopenharmony_ci                                 Control control,
721cb0ef41Sopenharmony_ci                                 const FeedbackSource& feedback);
731cb0ef41Sopenharmony_ci  // Inserts map checks even if maps were already reliable.
741cb0ef41Sopenharmony_ci  void InsertMapChecks(JSGraph* jsgraph, Effect* effect, Control control,
751cb0ef41Sopenharmony_ci                       const FeedbackSource& feedback);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci  // Internally marks the maps as reliable (thus bypassing the safety check) and
781cb0ef41Sopenharmony_ci  // returns the NoChange reduction. USE THIS ONLY WHEN RETURNING, e.g.:
791cb0ef41Sopenharmony_ci  //   if (foo) return inference.NoChange();
801cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT Reduction NoChange();
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_ci private:
831cb0ef41Sopenharmony_ci  JSHeapBroker* const broker_;
841cb0ef41Sopenharmony_ci  Node* const object_;
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ci  ZoneVector<MapRef> maps_;
871cb0ef41Sopenharmony_ci  enum {
881cb0ef41Sopenharmony_ci    kReliableOrGuarded,
891cb0ef41Sopenharmony_ci    kUnreliableDontNeedGuard,
901cb0ef41Sopenharmony_ci    kUnreliableNeedGuard
911cb0ef41Sopenharmony_ci  } maps_state_;
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci  bool Safe() const;
941cb0ef41Sopenharmony_ci  void SetNeedGuardIfUnreliable();
951cb0ef41Sopenharmony_ci  void SetGuarded();
961cb0ef41Sopenharmony_ci
971cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool AllOfInstanceTypesUnsafe(
981cb0ef41Sopenharmony_ci      std::function<bool(InstanceType)> f) const;
991cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool AnyOfInstanceTypesUnsafe(
1001cb0ef41Sopenharmony_ci      std::function<bool(InstanceType)> f) const;
1011cb0ef41Sopenharmony_ci  V8_WARN_UNUSED_RESULT bool RelyOnMapsHelper(
1021cb0ef41Sopenharmony_ci      CompilationDependencies* dependencies, JSGraph* jsgraph, Effect* effect,
1031cb0ef41Sopenharmony_ci      Control control, const FeedbackSource& feedback);
1041cb0ef41Sopenharmony_ci};
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci}  // namespace compiler
1071cb0ef41Sopenharmony_ci}  // namespace internal
1081cb0ef41Sopenharmony_ci}  // namespace v8
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci#endif  // V8_COMPILER_MAP_INFERENCE_H_
111