1// Copyright 2015 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_COMPILATION_DEPENDENCIES_H_
6#define V8_COMPILER_COMPILATION_DEPENDENCIES_H_
7
8#include "src/compiler/js-heap-broker.h"
9#include "src/objects.h"
10#include "src/zone/zone-containers.h"
11
12namespace v8 {
13namespace internal {
14namespace compiler {
15
16class SlackTrackingPrediction {
17 public:
18 SlackTrackingPrediction(MapRef initial_map, int instance_size);
19
20 int inobject_property_count() const { return inobject_property_count_; }
21 int instance_size() const { return instance_size_; }
22
23 private:
24 int instance_size_;
25 int inobject_property_count_;
26};
27
28// Collects and installs dependencies of the code that is being generated.
29class V8_EXPORT_PRIVATE CompilationDependencies : public ZoneObject {
30 public:
31 CompilationDependencies(JSHeapBroker* broker, Zone* zone);
32
33 V8_WARN_UNUSED_RESULT bool Commit(Handle<Code> code);
34
35 // Return the initial map of {function} and record the assumption that it
36 // stays the initial map.
37 MapRef DependOnInitialMap(const JSFunctionRef& function);
38
39 // Return the "prototype" property of the given function and record the
40 // assumption that it doesn't change.
41 ObjectRef DependOnPrototypeProperty(const JSFunctionRef& function);
42
43 // Record the assumption that {map} stays stable.
44 void DependOnStableMap(const MapRef& map);
45
46 // Record the assumption that {target_map} can be transitioned to, i.e., that
47 // it does not become deprecated.
48 void DependOnTransition(const MapRef& target_map);
49
50 // Return the pretenure mode of {site} and record the assumption that it does
51 // not change.
52 AllocationType DependOnPretenureMode(const AllocationSiteRef& site);
53
54 // Record the assumption that the field representation of a field does not
55 // change. The field is identified by the arguments.
56 void DependOnFieldRepresentation(const MapRef& map, int descriptor);
57
58 // Record the assumption that the field type of a field does not change. The
59 // field is identified by the arguments.
60 void DependOnFieldType(const MapRef& map, int descriptor);
61
62 // Return a field's constness and, if kConst, record the assumption that it
63 // remains kConst. The field is identified by the arguments.
64 //
65 // For arrays, arguments objects and value wrappers, only consider the field
66 // kConst if the map is stable (and register stability dependency in that
67 // case). This is to ensure that fast elements kind transitions cannot be
68 // used to mutate fields without deoptimization of the dependent code.
69 PropertyConstness DependOnFieldConstness(const MapRef& map, int descriptor);
70
71 // Record the assumption that neither {cell}'s {CellType} changes, nor the
72 // {IsReadOnly()} flag of {cell}'s {PropertyDetails}.
73 void DependOnGlobalProperty(const PropertyCellRef& cell);
74
75 // Return the validity of the given protector and, if true, record the
76 // assumption that the protector remains valid.
77 bool DependOnProtector(const PropertyCellRef& cell);
78
79 // Convenience wrappers around {DependOnProtector}.
80 bool DependOnArrayBufferDetachingProtector();
81 bool DependOnArrayIteratorProtector();
82 bool DependOnArraySpeciesProtector();
83 bool DependOnNoElementsProtector();
84 bool DependOnPromiseHookProtector();
85 bool DependOnPromiseSpeciesProtector();
86 bool DependOnPromiseThenProtector();
87
88 // Record the assumption that {site}'s {ElementsKind} doesn't change.
89 void DependOnElementsKind(const AllocationSiteRef& site);
90
91 // For each given map, depend on the stability of (the maps of) all prototypes
92 // up to (and including) the {last_prototype}.
93 template <class MapContainer>
94 void DependOnStablePrototypeChains(
95 MapContainer const& receiver_maps, WhereToStart start,
96 base::Optional<JSObjectRef> last_prototype =
97 base::Optional<JSObjectRef>());
98
99 // Like DependOnElementsKind but also applies to all nested allocation sites.
100 void DependOnElementsKinds(const AllocationSiteRef& site);
101
102 // Predict the final instance size for {function}'s initial map and record
103 // the assumption that this prediction is correct. In addition, register
104 // the initial map dependency. This method returns the {function}'s the
105 // predicted minimum slack instance size count (wrapped together with
106 // the corresponding in-object property count for convenience).
107 SlackTrackingPrediction DependOnInitialMapInstanceSizePrediction(
108 const JSFunctionRef& function);
109
110 // Exposed only for testing purposes.
111 bool AreValid() const;
112
113 // Exposed only because C++.
114 class Dependency;
115
116 private:
117 Zone* const zone_;
118 JSHeapBroker* const broker_;
119 ZoneForwardList<Dependency*> dependencies_;
120};
121
122} // namespace compiler
123} // namespace internal
124} // namespace v8
125
126#endif // V8_COMPILER_COMPILATION_DEPENDENCIES_H_
127