LCOV - code coverage report
Current view: top level - src/compiler - js-heap-broker.h (source / functions) Hit Total Coverage
Test: app.info Lines: 11 12 91.7 %
Date: 2019-04-17 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // Copyright 2018 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_COMPILER_JS_HEAP_BROKER_H_
       6             : #define V8_COMPILER_JS_HEAP_BROKER_H_
       7             : 
       8             : #include "src/base/compiler-specific.h"
       9             : #include "src/base/optional.h"
      10             : #include "src/compiler/refs-map.h"
      11             : #include "src/feedback-vector.h"
      12             : #include "src/function-kind.h"
      13             : #include "src/globals.h"
      14             : #include "src/handles.h"
      15             : #include "src/objects.h"
      16             : #include "src/objects/instance-type.h"
      17             : #include "src/ostreams.h"
      18             : #include "src/zone/zone-containers.h"
      19             : 
      20             : namespace v8 {
      21             : namespace internal {
      22             : 
      23             : class BytecodeArray;
      24             : class CallHandlerInfo;
      25             : class FixedDoubleArray;
      26             : class FunctionTemplateInfo;
      27             : class HeapNumber;
      28             : class InternalizedString;
      29             : class JSBoundFunction;
      30             : class JSDataView;
      31             : class JSGlobalProxy;
      32             : class JSRegExp;
      33             : class JSTypedArray;
      34             : class NativeContext;
      35             : class ScriptContextTable;
      36             : class VectorSlotPair;
      37             : 
      38             : namespace compiler {
      39             : 
      40             : enum class OddballType : uint8_t {
      41             :   kNone,     // Not an Oddball.
      42             :   kBoolean,  // True or False.
      43             :   kUndefined,
      44             :   kNull,
      45             :   kHole,
      46             :   kUninitialized,
      47             :   kOther  // Oddball, but none of the above.
      48             : };
      49             : 
      50             : // This list is sorted such that subtypes appear before their supertypes.
      51             : // DO NOT VIOLATE THIS PROPERTY!
      52             : #define HEAP_BROKER_OBJECT_LIST(V) \
      53             :   /* Subtypes of JSObject */       \
      54             :   V(JSArray)                       \
      55             :   V(JSBoundFunction)               \
      56             :   V(JSDataView)                    \
      57             :   V(JSFunction)                    \
      58             :   V(JSGlobalProxy)                 \
      59             :   V(JSRegExp)                      \
      60             :   V(JSTypedArray)                  \
      61             :   /* Subtypes of Context */        \
      62             :   V(NativeContext)                 \
      63             :   /* Subtypes of FixedArray */     \
      64             :   V(Context)                       \
      65             :   V(ScopeInfo)                     \
      66             :   V(ScriptContextTable)            \
      67             :   /* Subtypes of FixedArrayBase */ \
      68             :   V(BytecodeArray)                 \
      69             :   V(FixedArray)                    \
      70             :   V(FixedDoubleArray)              \
      71             :   /* Subtypes of Name */           \
      72             :   V(InternalizedString)            \
      73             :   V(String)                        \
      74             :   V(Symbol)                        \
      75             :   /* Subtypes of HeapObject */     \
      76             :   V(AllocationSite)                \
      77             :   V(CallHandlerInfo)               \
      78             :   V(Cell)                          \
      79             :   V(Code)                          \
      80             :   V(DescriptorArray)               \
      81             :   V(FeedbackVector)                \
      82             :   V(FixedArrayBase)                \
      83             :   V(FunctionTemplateInfo)          \
      84             :   V(HeapNumber)                    \
      85             :   V(JSObject)                      \
      86             :   V(Map)                           \
      87             :   V(Module)                        \
      88             :   V(MutableHeapNumber)             \
      89             :   V(Name)                          \
      90             :   V(PropertyCell)                  \
      91             :   V(SharedFunctionInfo)            \
      92             :   /* Subtypes of Object */         \
      93             :   V(HeapObject)
      94             : 
      95             : class CompilationDependencies;
      96             : class JSHeapBroker;
      97             : class ObjectData;
      98             : class PerIsolateCompilerCache;
      99             : #define FORWARD_DECL(Name) class Name##Ref;
     100             : HEAP_BROKER_OBJECT_LIST(FORWARD_DECL)
     101             : #undef FORWARD_DECL
     102             : 
     103             : class V8_EXPORT_PRIVATE ObjectRef {
     104             :  public:
     105             :   ObjectRef(JSHeapBroker* broker, Handle<Object> object);
     106             :   ObjectRef(JSHeapBroker* broker, ObjectData* data)
     107      466767 :       : data_(data), broker_(broker) {
     108    86063807 :     CHECK_NOT_NULL(data_);
     109             :   }
     110             : 
     111             :   Handle<Object> object() const;
     112             : 
     113             :   bool equals(const ObjectRef& other) const;
     114             : 
     115             :   bool IsSmi() const;
     116             :   int AsSmi() const;
     117             : 
     118             : #define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
     119             :   HEAP_BROKER_OBJECT_LIST(HEAP_IS_METHOD_DECL)
     120             : #undef HEAP_IS_METHOD_DECL
     121             : 
     122             : #define HEAP_AS_METHOD_DECL(Name) Name##Ref As##Name() const;
     123             :   HEAP_BROKER_OBJECT_LIST(HEAP_AS_METHOD_DECL)
     124             : #undef HEAP_AS_METHOD_DECL
     125             : 
     126             :   bool IsNullOrUndefined() const;
     127             : 
     128             :   bool BooleanValue() const;
     129             :   Maybe<double> OddballToNumber() const;
     130             : 
     131             :   // Return the element at key {index} if {index} is known to be an own data
     132             :   // property of the object that is non-writable and non-configurable.
     133             :   base::Optional<ObjectRef> GetOwnConstantElement(uint32_t index,
     134             :                                                   bool serialize = false) const;
     135             : 
     136             :   Isolate* isolate() const;
     137             : 
     138             :  protected:
     139             :   JSHeapBroker* broker() const;
     140             :   ObjectData* data() const;
     141             :   ObjectData* data_;  // Should be used only by object() getters.
     142             : 
     143             :  private:
     144             :   friend class JSArrayData;
     145             :   friend class JSGlobalProxyRef;
     146             :   friend class JSGlobalProxyData;
     147             :   friend class JSObjectData;
     148             :   friend class StringData;
     149             : 
     150             :   friend std::ostream& operator<<(std::ostream& os, const ObjectRef& ref);
     151             : 
     152             :   JSHeapBroker* broker_;
     153             : };
     154             : 
     155             : std::ostream& operator<<(std::ostream& os, const ObjectRef& ref);
     156             : 
     157             : // Temporary class that carries information from a Map. We'd like to remove
     158             : // this class and use MapRef instead, but we can't as long as we support the
     159             : // kDisabled broker mode. That's because obtaining the MapRef via
     160             : // HeapObjectRef::map() requires a HandleScope when the broker is disabled.
     161             : // During OptimizeGraph we generally don't have a HandleScope, however. There
     162             : // are two places where we therefore use GetHeapObjectType() instead. Both that
     163             : // function and this class should eventually be removed.
     164             : class HeapObjectType {
     165             :  public:
     166             :   enum Flag : uint8_t { kUndetectable = 1 << 0, kCallable = 1 << 1 };
     167             : 
     168             :   using Flags = base::Flags<Flag>;
     169             : 
     170             :   HeapObjectType(InstanceType instance_type, Flags flags,
     171             :                  OddballType oddball_type)
     172             :       : instance_type_(instance_type),
     173             :         oddball_type_(oddball_type),
     174             :         flags_(flags) {
     175             :     DCHECK_EQ(instance_type == ODDBALL_TYPE,
     176             :               oddball_type != OddballType::kNone);
     177             :   }
     178             : 
     179             :   OddballType oddball_type() const { return oddball_type_; }
     180             :   InstanceType instance_type() const { return instance_type_; }
     181             :   Flags flags() const { return flags_; }
     182             : 
     183             :   bool is_callable() const { return flags_ & kCallable; }
     184             :   bool is_undetectable() const { return flags_ & kUndetectable; }
     185             : 
     186             :  private:
     187             :   InstanceType const instance_type_;
     188             :   OddballType const oddball_type_;
     189             :   Flags const flags_;
     190             : };
     191             : 
     192             : class HeapObjectRef : public ObjectRef {
     193             :  public:
     194    53541977 :   using ObjectRef::ObjectRef;
     195             :   Handle<HeapObject> object() const;
     196             : 
     197             :   MapRef map() const;
     198             : 
     199             :   // See the comment on the HeapObjectType class.
     200             :   HeapObjectType GetHeapObjectType() const;
     201             : };
     202             : 
     203             : class PropertyCellRef : public HeapObjectRef {
     204             :  public:
     205             :   using HeapObjectRef::HeapObjectRef;
     206             :   Handle<PropertyCell> object() const;
     207             : 
     208             :   PropertyDetails property_details() const;
     209             : 
     210             :   void Serialize();
     211             :   ObjectRef value() const;
     212             : };
     213             : 
     214             : class JSObjectRef : public HeapObjectRef {
     215             :  public:
     216             :   using HeapObjectRef::HeapObjectRef;
     217             :   Handle<JSObject> object() const;
     218             : 
     219             :   double RawFastDoublePropertyAt(FieldIndex index) const;
     220             :   ObjectRef RawFastPropertyAt(FieldIndex index) const;
     221             : 
     222             :   FixedArrayBaseRef elements() const;
     223             :   void EnsureElementsTenured();
     224             :   ElementsKind GetElementsKind() const;
     225             : 
     226             :   void SerializeObjectCreateMap();
     227             :   base::Optional<MapRef> GetObjectCreateMap() const;
     228             : };
     229             : 
     230             : class JSDataViewRef : public JSObjectRef {
     231             :  public:
     232             :   using JSObjectRef::JSObjectRef;
     233             :   Handle<JSDataView> object() const;
     234             : 
     235             :   size_t byte_length() const;
     236             :   size_t byte_offset() const;
     237             : };
     238             : 
     239             : class JSBoundFunctionRef : public JSObjectRef {
     240             :  public:
     241             :   using JSObjectRef::JSObjectRef;
     242             :   Handle<JSBoundFunction> object() const;
     243             : 
     244             :   void Serialize();
     245             : 
     246             :   // The following are available only after calling Serialize().
     247             :   ObjectRef bound_target_function() const;
     248             :   ObjectRef bound_this() const;
     249             :   FixedArrayRef bound_arguments() const;
     250             : };
     251             : 
     252             : class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef {
     253             :  public:
     254             :   using JSObjectRef::JSObjectRef;
     255             :   Handle<JSFunction> object() const;
     256             : 
     257             :   bool has_feedback_vector() const;
     258             :   bool has_initial_map() const;
     259             :   bool has_prototype() const;
     260             :   bool PrototypeRequiresRuntimeLookup() const;
     261             : 
     262             :   void Serialize();
     263             :   bool serialized() const;
     264             : 
     265             :   // The following are available only after calling Serialize().
     266             :   ObjectRef prototype() const;
     267             :   MapRef initial_map() const;
     268             :   ContextRef context() const;
     269             :   NativeContextRef native_context() const;
     270             :   SharedFunctionInfoRef shared() const;
     271             :   FeedbackVectorRef feedback_vector() const;
     272             :   int InitialMapInstanceSizeWithMinSlack() const;
     273             : 
     274             :   bool IsSerializedForCompilation() const;
     275             : };
     276             : 
     277             : class JSRegExpRef : public JSObjectRef {
     278             :  public:
     279             :   using JSObjectRef::JSObjectRef;
     280             :   Handle<JSRegExp> object() const;
     281             : 
     282             :   ObjectRef raw_properties_or_hash() const;
     283             :   ObjectRef data() const;
     284             :   ObjectRef source() const;
     285             :   ObjectRef flags() const;
     286             :   ObjectRef last_index() const;
     287             : };
     288             : 
     289             : class HeapNumberRef : public HeapObjectRef {
     290             :  public:
     291             :   using HeapObjectRef::HeapObjectRef;
     292             :   Handle<HeapNumber> object() const;
     293             : 
     294             :   double value() const;
     295             : };
     296             : 
     297             : class MutableHeapNumberRef : public HeapObjectRef {
     298             :  public:
     299             :   using HeapObjectRef::HeapObjectRef;
     300             :   Handle<MutableHeapNumber> object() const;
     301             : 
     302             :   double value() const;
     303             : };
     304             : 
     305             : class ContextRef : public HeapObjectRef {
     306             :  public:
     307             :   using HeapObjectRef::HeapObjectRef;
     308             :   Handle<Context> object() const;
     309             : 
     310             :   void SerializeContextChain();
     311             :   ContextRef previous() const;
     312             : 
     313             :   void SerializeSlot(int index);
     314             :   ObjectRef get(int index) const;
     315             : };
     316             : 
     317             : #define BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS(V)                    \
     318             :   V(JSFunction, array_function)                                       \
     319             :   V(JSFunction, boolean_function)                                     \
     320             :   V(JSFunction, bigint_function)                                      \
     321             :   V(JSFunction, number_function)                                      \
     322             :   V(JSFunction, object_function)                                      \
     323             :   V(JSFunction, promise_function)                                     \
     324             :   V(JSFunction, promise_then)                                         \
     325             :   V(JSFunction, string_function)                                      \
     326             :   V(JSFunction, symbol_function)                                      \
     327             :   V(JSGlobalProxy, global_proxy_object)                               \
     328             :   V(JSObject, promise_prototype)                                      \
     329             :   V(Map, bound_function_with_constructor_map)                         \
     330             :   V(Map, bound_function_without_constructor_map)                      \
     331             :   V(Map, fast_aliased_arguments_map)                                  \
     332             :   V(Map, initial_array_iterator_map)                                  \
     333             :   V(Map, initial_string_iterator_map)                                 \
     334             :   V(Map, iterator_result_map)                                         \
     335             :   V(Map, js_array_holey_double_elements_map)                          \
     336             :   V(Map, js_array_holey_elements_map)                                 \
     337             :   V(Map, js_array_holey_smi_elements_map)                             \
     338             :   V(Map, js_array_packed_double_elements_map)                         \
     339             :   V(Map, js_array_packed_elements_map)                                \
     340             :   V(Map, js_array_packed_smi_elements_map)                            \
     341             :   V(Map, sloppy_arguments_map)                                        \
     342             :   V(Map, slow_object_with_null_prototype_map)                         \
     343             :   V(Map, strict_arguments_map)                                        \
     344             :   V(ScriptContextTable, script_context_table)                         \
     345             :   V(SharedFunctionInfo, promise_capability_default_reject_shared_fun) \
     346             :   V(SharedFunctionInfo, promise_catch_finally_shared_fun)             \
     347             :   V(SharedFunctionInfo, promise_then_finally_shared_fun)              \
     348             :   V(SharedFunctionInfo, promise_capability_default_resolve_shared_fun)
     349             : 
     350             : // Those are set by Bootstrapper::ExportFromRuntime, which may not yet have
     351             : // happened when Turbofan is invoked via --always-opt.
     352             : #define BROKER_OPTIONAL_NATIVE_CONTEXT_FIELDS(V) \
     353             :   V(Map, async_function_object_map)              \
     354             :   V(Map, map_key_iterator_map)                   \
     355             :   V(Map, map_key_value_iterator_map)             \
     356             :   V(Map, map_value_iterator_map)                 \
     357             :   V(Map, set_key_value_iterator_map)             \
     358             :   V(Map, set_value_iterator_map)
     359             : 
     360             : #define BROKER_NATIVE_CONTEXT_FIELDS(V)      \
     361             :   BROKER_COMPULSORY_NATIVE_CONTEXT_FIELDS(V) \
     362             :   BROKER_OPTIONAL_NATIVE_CONTEXT_FIELDS(V)
     363             : 
     364             : class NativeContextRef : public ContextRef {
     365             :  public:
     366             :   using ContextRef::ContextRef;
     367             :   Handle<NativeContext> object() const;
     368             : 
     369             :   void Serialize();
     370             : 
     371             : #define DECL_ACCESSOR(type, name) type##Ref name() const;
     372             :   BROKER_NATIVE_CONTEXT_FIELDS(DECL_ACCESSOR)
     373             : #undef DECL_ACCESSOR
     374             : 
     375             :   MapRef GetFunctionMapFromIndex(int index) const;
     376             :   MapRef GetInitialJSArrayMap(ElementsKind kind) const;
     377             :   base::Optional<JSFunctionRef> GetConstructorFunction(const MapRef& map) const;
     378             : };
     379             : 
     380             : class NameRef : public HeapObjectRef {
     381             :  public:
     382             :   using HeapObjectRef::HeapObjectRef;
     383             :   Handle<Name> object() const;
     384             : 
     385             :   bool IsUniqueName() const;
     386             : };
     387             : 
     388             : class ScriptContextTableRef : public HeapObjectRef {
     389             :  public:
     390             :   using HeapObjectRef::HeapObjectRef;
     391             :   Handle<ScriptContextTable> object() const;
     392             : 
     393             :   struct LookupResult {
     394             :     ContextRef context;
     395             :     bool immutable;
     396             :     int index;
     397             :   };
     398             : 
     399             :   base::Optional<LookupResult> lookup(const NameRef& name) const;
     400             : };
     401             : 
     402             : class DescriptorArrayRef : public HeapObjectRef {
     403             :  public:
     404             :   using HeapObjectRef::HeapObjectRef;
     405             :   Handle<DescriptorArray> object() const;
     406             : };
     407             : 
     408             : class FeedbackVectorRef : public HeapObjectRef {
     409             :  public:
     410             :   using HeapObjectRef::HeapObjectRef;
     411             :   Handle<FeedbackVector> object() const;
     412             : 
     413             :   ObjectRef get(FeedbackSlot slot) const;
     414             : 
     415             :   void SerializeSlots();
     416             : };
     417             : 
     418             : class FunctionTemplateInfoRef : public HeapObjectRef {
     419             :  public:
     420             :   using HeapObjectRef::HeapObjectRef;
     421             :   Handle<FunctionTemplateInfo> object() const;
     422             : 
     423             :   void Serialize();
     424             :   ObjectRef call_code() const;
     425             : };
     426             : 
     427             : class CallHandlerInfoRef : public HeapObjectRef {
     428             :  public:
     429             :   using HeapObjectRef::HeapObjectRef;
     430             :   Handle<CallHandlerInfo> object() const;
     431             : 
     432             :   Address callback() const;
     433             : 
     434             :   void Serialize();
     435             :   ObjectRef data() const;
     436             : };
     437             : 
     438             : class AllocationSiteRef : public HeapObjectRef {
     439             :  public:
     440             :   using HeapObjectRef::HeapObjectRef;
     441             :   Handle<AllocationSite> object() const;
     442             : 
     443             :   bool PointsToLiteral() const;
     444             :   AllocationType GetAllocationType() const;
     445             :   ObjectRef nested_site() const;
     446             : 
     447             :   // {IsFastLiteral} determines whether the given array or object literal
     448             :   // boilerplate satisfies all limits to be considered for fast deep-copying
     449             :   // and computes the total size of all objects that are part of the graph.
     450             :   //
     451             :   // If PointsToLiteral() is false, then IsFastLiteral() is also false.
     452             :   bool IsFastLiteral() const;
     453             :   // We only serialize boilerplate if IsFastLiteral is true.
     454             :   base::Optional<JSObjectRef> boilerplate() const;
     455             : 
     456             :   ElementsKind GetElementsKind() const;
     457             :   bool CanInlineCall() const;
     458             : };
     459             : 
     460             : class V8_EXPORT_PRIVATE MapRef : public HeapObjectRef {
     461             :  public:
     462             :   using HeapObjectRef::HeapObjectRef;
     463             :   Handle<Map> object() const;
     464             : 
     465             :   int instance_size() const;
     466             :   InstanceType instance_type() const;
     467             :   int GetInObjectProperties() const;
     468             :   int GetInObjectPropertiesStartInWords() const;
     469             :   int NumberOfOwnDescriptors() const;
     470             :   int GetInObjectPropertyOffset(int index) const;
     471             :   int constructor_function_index() const;
     472             :   int NextFreePropertyIndex() const;
     473             :   int UnusedPropertyFields() const;
     474             :   ElementsKind elements_kind() const;
     475             :   bool is_stable() const;
     476             :   bool is_extensible() const;
     477             :   bool is_constructor() const;
     478             :   bool has_prototype_slot() const;
     479             :   bool is_access_check_needed() const;
     480             :   bool is_deprecated() const;
     481             :   bool CanBeDeprecated() const;
     482             :   bool CanTransition() const;
     483             :   bool IsInobjectSlackTrackingInProgress() const;
     484             :   bool is_dictionary_map() const;
     485             :   bool IsFixedCowArrayMap() const;
     486             :   bool IsPrimitiveMap() const;
     487             :   bool is_undetectable() const;
     488             :   bool is_callable() const;
     489             :   bool has_indexed_interceptor() const;
     490             :   bool has_hidden_prototype() const;
     491             :   bool is_migration_target() const;
     492             :   bool supports_fast_array_iteration() const;
     493             :   bool supports_fast_array_resize() const;
     494             :   bool IsMapOfCurrentGlobalProxy() const;
     495             : 
     496             :   OddballType oddball_type() const;
     497             : 
     498             : #define DEF_TESTER(Type, ...) bool Is##Type##Map() const;
     499             :   INSTANCE_TYPE_CHECKERS(DEF_TESTER)
     500             : #undef DEF_TESTER
     501             : 
     502             :   void SerializeBackPointer();
     503             :   HeapObjectRef GetBackPointer() const;
     504             : 
     505             :   void SerializePrototype();
     506             :   bool serialized_prototype() const;
     507             :   HeapObjectRef prototype() const;
     508             : 
     509             :   void SerializeForElementLoad();
     510             : 
     511             :   void SerializeForElementStore();
     512             :   bool HasOnlyStablePrototypesWithFastElements(
     513             :       ZoneVector<MapRef>* prototype_maps);
     514             : 
     515             :   // Concerning the underlying instance_descriptors:
     516             :   void SerializeOwnDescriptors();
     517             :   MapRef FindFieldOwner(int descriptor_index) const;
     518             :   PropertyDetails GetPropertyDetails(int descriptor_index) const;
     519             :   NameRef GetPropertyKey(int descriptor_index) const;
     520             :   FieldIndex GetFieldIndexFor(int descriptor_index) const;
     521             :   ObjectRef GetFieldType(int descriptor_index) const;
     522             :   bool IsUnboxedDoubleField(int descriptor_index) const;
     523             : 
     524             :   // Available after calling JSFunctionRef::Serialize on a function that has
     525             :   // this map as initial map.
     526             :   ObjectRef GetConstructor() const;
     527             :   base::Optional<MapRef> AsElementsKind(ElementsKind kind) const;
     528             : };
     529             : 
     530             : class FixedArrayBaseRef : public HeapObjectRef {
     531             :  public:
     532             :   using HeapObjectRef::HeapObjectRef;
     533             :   Handle<FixedArrayBase> object() const;
     534             : 
     535             :   int length() const;
     536             : };
     537             : 
     538             : class FixedArrayRef : public FixedArrayBaseRef {
     539             :  public:
     540             :   using FixedArrayBaseRef::FixedArrayBaseRef;
     541             :   Handle<FixedArray> object() const;
     542             : 
     543             :   ObjectRef get(int i) const;
     544             : };
     545             : 
     546             : class FixedDoubleArrayRef : public FixedArrayBaseRef {
     547             :  public:
     548             :   using FixedArrayBaseRef::FixedArrayBaseRef;
     549             :   Handle<FixedDoubleArray> object() const;
     550             : 
     551             :   double get_scalar(int i) const;
     552             :   bool is_the_hole(int i) const;
     553             : };
     554             : 
     555             : class BytecodeArrayRef : public FixedArrayBaseRef {
     556             :  public:
     557             :   using FixedArrayBaseRef::FixedArrayBaseRef;
     558             :   Handle<BytecodeArray> object() const;
     559             : 
     560             :   int register_count() const;
     561             : };
     562             : 
     563             : class JSArrayRef : public JSObjectRef {
     564             :  public:
     565             :   using JSObjectRef::JSObjectRef;
     566             :   Handle<JSArray> object() const;
     567             : 
     568             :   ObjectRef length() const;
     569             : 
     570             :   // Return the element at key {index} if the array has a copy-on-write elements
     571             :   // storage and {index} is known to be an own data property.
     572             :   base::Optional<ObjectRef> GetOwnCowElement(uint32_t index,
     573             :                                              bool serialize = false) const;
     574             : };
     575             : 
     576             : class ScopeInfoRef : public HeapObjectRef {
     577             :  public:
     578             :   using HeapObjectRef::HeapObjectRef;
     579             :   Handle<ScopeInfo> object() const;
     580             : 
     581             :   int ContextLength() const;
     582             : };
     583             : 
     584             : #define BROKER_SFI_FIELDS(V)                 \
     585             :   V(int, internal_formal_parameter_count)    \
     586             :   V(bool, has_duplicate_parameters)          \
     587             :   V(int, function_map_index)                 \
     588             :   V(FunctionKind, kind)                      \
     589             :   V(LanguageMode, language_mode)             \
     590             :   V(bool, native)                            \
     591             :   V(bool, HasBreakInfo)                      \
     592             :   V(bool, HasBuiltinId)                      \
     593             :   V(bool, construct_as_builtin)              \
     594             :   V(bool, HasBytecodeArray)                  \
     595             :   V(bool, is_safe_to_skip_arguments_adaptor) \
     596             :   V(bool, IsInlineable)
     597             : 
     598             : class V8_EXPORT_PRIVATE SharedFunctionInfoRef : public HeapObjectRef {
     599             :  public:
     600             :   using HeapObjectRef::HeapObjectRef;
     601             :   Handle<SharedFunctionInfo> object() const;
     602             : 
     603             :   int builtin_id() const;
     604             :   BytecodeArrayRef GetBytecodeArray() const;
     605             : 
     606             : #define DECL_ACCESSOR(type, name) type name() const;
     607             :   BROKER_SFI_FIELDS(DECL_ACCESSOR)
     608             : #undef DECL_ACCESSOR
     609             : 
     610             :   bool IsSerializedForCompilation(FeedbackVectorRef feedback) const;
     611             :   void SetSerializedForCompilation(FeedbackVectorRef feedback);
     612             : };
     613             : 
     614             : class StringRef : public NameRef {
     615             :  public:
     616             :   using NameRef::NameRef;
     617             :   Handle<String> object() const;
     618             : 
     619             :   int length() const;
     620             :   uint16_t GetFirstChar();
     621             :   base::Optional<double> ToNumber();
     622             :   bool IsSeqString() const;
     623             :   bool IsExternalString() const;
     624             : };
     625             : 
     626             : class SymbolRef : public NameRef {
     627             :  public:
     628             :   using NameRef::NameRef;
     629             :   Handle<Symbol> object() const;
     630             : };
     631             : 
     632             : class JSTypedArrayRef : public JSObjectRef {
     633             :  public:
     634             :   using JSObjectRef::JSObjectRef;
     635             :   Handle<JSTypedArray> object() const;
     636             : 
     637             :   bool is_on_heap() const;
     638             :   size_t length() const;
     639             :   void* elements_external_pointer() const;
     640             : 
     641             :   void Serialize();
     642             :   bool serialized() const;
     643             : 
     644             :   HeapObjectRef buffer() const;
     645             : };
     646             : 
     647             : class ModuleRef : public HeapObjectRef {
     648             :  public:
     649             :   using HeapObjectRef::HeapObjectRef;
     650             :   Handle<Module> object() const;
     651             : 
     652             :   void Serialize();
     653             : 
     654             :   CellRef GetCell(int cell_index) const;
     655             : };
     656             : 
     657             : class CellRef : public HeapObjectRef {
     658             :  public:
     659             :   using HeapObjectRef::HeapObjectRef;
     660             :   Handle<Cell> object() const;
     661             : 
     662             :   ObjectRef value() const;
     663             : };
     664             : 
     665             : class JSGlobalProxyRef : public JSObjectRef {
     666             :  public:
     667             :   using JSObjectRef::JSObjectRef;
     668             :   Handle<JSGlobalProxy> object() const;
     669             : 
     670             :   // If {serialize} is false:
     671             :   //   If the property is known to exist as a property cell (on the global
     672             :   //   object), return that property cell. Otherwise (not known to exist as a
     673             :   //   property cell or known not to exist as a property cell) return nothing.
     674             :   // If {serialize} is true:
     675             :   //   Like above but potentially access the heap and serialize the necessary
     676             :   //   information.
     677             :   base::Optional<PropertyCellRef> GetPropertyCell(NameRef const& name,
     678             :                                                   bool serialize = false) const;
     679             : };
     680             : 
     681             : class CodeRef : public HeapObjectRef {
     682             :  public:
     683             :   using HeapObjectRef::HeapObjectRef;
     684             :   Handle<Code> object() const;
     685             : };
     686             : 
     687             : class InternalizedStringRef : public StringRef {
     688             :  public:
     689             :   using StringRef::StringRef;
     690             :   Handle<InternalizedString> object() const;
     691             : };
     692             : 
     693             : class ProcessedFeedback : public ZoneObject {
     694             :  public:
     695             :   enum Kind { kElementAccess, kGlobalAccess };
     696           0 :   Kind kind() const { return kind_; }
     697             : 
     698             :  protected:
     699      218019 :   explicit ProcessedFeedback(Kind kind) : kind_(kind) {}
     700             : 
     701             :  private:
     702             :   Kind const kind_;
     703             : };
     704             : 
     705             : class GlobalAccessFeedback : public ProcessedFeedback {
     706             :  public:
     707             :   explicit GlobalAccessFeedback(PropertyCellRef cell);
     708             :   GlobalAccessFeedback(ContextRef script_context, int slot_index,
     709             :                        bool immutable);
     710             : 
     711             :   bool IsPropertyCell() const;
     712             :   PropertyCellRef property_cell() const;
     713             : 
     714      194438 :   bool IsScriptContextSlot() const { return !IsPropertyCell(); }
     715             :   ContextRef script_context() const;
     716             :   int slot_index() const;
     717             :   bool immutable() const;
     718             : 
     719             :   base::Optional<ObjectRef> GetConstantHint() const;
     720             : 
     721             :  private:
     722             :   ObjectRef const cell_or_context_;
     723             :   int const index_and_immutable_;
     724             : };
     725             : 
     726             : class ElementAccessFeedback : public ProcessedFeedback {
     727             :  public:
     728             :   explicit ElementAccessFeedback(Zone* zone);
     729             : 
     730             :   // No transition sources appear in {receiver_maps}.
     731             :   // All transition targets appear in {receiver_maps}.
     732             :   ZoneVector<Handle<Map>> receiver_maps;
     733             :   ZoneVector<std::pair<Handle<Map>, Handle<Map>>> transitions;
     734             : 
     735             :   class MapIterator {
     736             :    public:
     737             :     bool done() const;
     738             :     void advance();
     739             :     MapRef current() const;
     740             : 
     741             :    private:
     742             :     friend class ElementAccessFeedback;
     743             : 
     744             :     explicit MapIterator(ElementAccessFeedback const& processed,
     745             :                          JSHeapBroker* broker);
     746             : 
     747             :     ElementAccessFeedback const& processed_;
     748             :     JSHeapBroker* const broker_;
     749             :     size_t index_ = 0;
     750             :   };
     751             : 
     752             :   // Iterator over all maps: first {receiver_maps}, then transition sources.
     753             :   MapIterator all_maps(JSHeapBroker* broker) const;
     754             : };
     755             : 
     756             : struct FeedbackSource {
     757             :   FeedbackSource(Handle<FeedbackVector> vector_, FeedbackSlot slot_)
     758          51 :       : vector(vector_), slot(slot_) {}
     759             :   explicit FeedbackSource(FeedbackNexus const& nexus);
     760             :   explicit FeedbackSource(VectorSlotPair const& pair);
     761             : 
     762             :   Handle<FeedbackVector> const vector;
     763             :   FeedbackSlot const slot;
     764             : 
     765             :   struct Hash {
     766         219 :     size_t operator()(FeedbackSource const& source) const {
     767         219 :       return base::hash_combine(source.vector.address(), source.slot);
     768             :     }
     769             :   };
     770             : 
     771             :   struct Equal {
     772             :     bool operator()(FeedbackSource const& lhs,
     773             :                     FeedbackSource const& rhs) const {
     774         150 :       return lhs.vector.equals(rhs.vector) && lhs.slot == rhs.slot;
     775             :     }
     776             :   };
     777             : };
     778             : 
     779        7962 : class V8_EXPORT_PRIVATE JSHeapBroker : public NON_EXPORTED_BASE(ZoneObject) {
     780             :  public:
     781             :   JSHeapBroker(Isolate* isolate, Zone* broker_zone);
     782             : 
     783             :   void SetNativeContextRef();
     784             :   void SerializeStandardObjects();
     785             : 
     786             :   Isolate* isolate() const { return isolate_; }
     787             :   Zone* zone() const { return current_zone_; }
     788     2015536 :   NativeContextRef native_context() const { return native_context_.value(); }
     789             :   PerIsolateCompilerCache* compiler_cache() const { return compiler_cache_; }
     790             : 
     791             :   enum BrokerMode { kDisabled, kSerializing, kSerialized, kRetired };
     792             :   BrokerMode mode() const { return mode_; }
     793             :   void StartSerializing();
     794             :   void StopSerializing();
     795             :   void Retire();
     796             :   bool SerializingAllowed() const;
     797             : 
     798             :   // Returns nullptr iff handle unknown.
     799             :   ObjectData* GetData(Handle<Object>) const;
     800             :   // Never returns nullptr.
     801             :   ObjectData* GetOrCreateData(Handle<Object>);
     802             :   // Like the previous but wraps argument in handle first (for convenience).
     803             :   ObjectData* GetOrCreateData(Object);
     804             : 
     805             :   // Check if {object} is any native context's %ArrayPrototype% or
     806             :   // %ObjectPrototype%.
     807             :   bool IsArrayOrObjectPrototype(const JSObjectRef& object) const;
     808             : 
     809             :   bool HasFeedback(FeedbackSource const& source) const;
     810             :   // The processed {feedback} can be {nullptr}, indicating that the original
     811             :   // feedback didn't contain information relevant for Turbofan.
     812             :   void SetFeedback(FeedbackSource const& source,
     813             :                    ProcessedFeedback const* feedback);
     814             :   ProcessedFeedback const* GetFeedback(FeedbackSource const& source) const;
     815             : 
     816             :   // Convenience wrappers around GetFeedback.
     817             :   ElementAccessFeedback const* GetElementAccessFeedback(
     818             :       FeedbackSource const& source) const;
     819             :   GlobalAccessFeedback const* GetGlobalAccessFeedback(
     820             :       FeedbackSource const& source) const;
     821             : 
     822             :   // TODO(neis): Move these into serializer when we're always in the background.
     823             :   ElementAccessFeedback const* ProcessFeedbackMapsForElementAccess(
     824             :       MapHandles const& maps);
     825             :   GlobalAccessFeedback const* ProcessFeedbackForGlobalAccess(
     826             :       FeedbackSource const& source);
     827             : 
     828             :   std::ostream& Trace();
     829             :   void IncrementTracingIndentation();
     830             :   void DecrementTracingIndentation();
     831             : 
     832             :  private:
     833             :   friend class HeapObjectRef;
     834             :   friend class ObjectRef;
     835             :   friend class ObjectData;
     836             : 
     837             :   void SerializeShareableObjects();
     838             :   void CollectArrayAndObjectPrototypes();
     839             : 
     840             :   Isolate* const isolate_;
     841             :   Zone* const broker_zone_;
     842             :   Zone* current_zone_;
     843             :   base::Optional<NativeContextRef> native_context_;
     844             :   RefsMap* refs_;
     845             :   ZoneUnorderedSet<Handle<JSObject>, Handle<JSObject>::hash,
     846             :                    Handle<JSObject>::equal_to>
     847             :       array_and_object_prototypes_;
     848             :   BrokerMode mode_ = kDisabled;
     849             :   StdoutStream trace_out_;
     850             :   unsigned trace_indentation_ = 0;
     851             :   PerIsolateCompilerCache* compiler_cache_;
     852             :   ZoneUnorderedMap<FeedbackSource, ProcessedFeedback const*,
     853             :                    FeedbackSource::Hash, FeedbackSource::Equal>
     854             :       feedback_;
     855             : 
     856             :   static const size_t kMinimalRefsBucketCount = 8;     // must be power of 2
     857             :   static const size_t kInitialRefsBucketCount = 1024;  // must be power of 2
     858             : };
     859             : 
     860             : #define ASSIGN_RETURN_NO_CHANGE_IF_DATA_MISSING(something_var,             \
     861             :                                                 optionally_something)      \
     862             :   auto optionally_something_ = optionally_something;                       \
     863             :   if (!optionally_something_)                                              \
     864             :     return NoChangeBecauseOfMissingData(broker(), __FUNCTION__, __LINE__); \
     865             :   something_var = *optionally_something_;
     866             : 
     867             : class Reduction;
     868             : Reduction NoChangeBecauseOfMissingData(JSHeapBroker* broker,
     869             :                                        const char* function, int line);
     870             : 
     871             : // Miscellaneous definitions that should be moved elsewhere once concurrent
     872             : // compilation is finished.
     873             : bool CanInlineElementAccess(MapRef const& map);
     874             : 
     875             : #define TRACE_BROKER(broker, x)                                       \
     876             :   do {                                                                \
     877             :     if (FLAG_trace_heap_broker_verbose) broker->Trace() << x << '\n'; \
     878             :   } while (false)
     879             : 
     880             : #define TRACE_BROKER_MISSING(broker, x)                             \
     881             :   do {                                                              \
     882             :     if (FLAG_trace_heap_broker)                                     \
     883             :       broker->Trace() << __FUNCTION__ << ": missing " << x << '\n'; \
     884             :   } while (false)
     885             : 
     886             : }  // namespace compiler
     887             : }  // namespace internal
     888             : }  // namespace v8
     889             : 
     890             : #endif  // V8_COMPILER_JS_HEAP_BROKER_H_

Generated by: LCOV version 1.10