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 #include "src/compiler/js-heap-copy-reducer.h"
6 
7 #include "src/compiler/common-operator.h"
8 #include "src/compiler/js-heap-broker.h"
9 #include "src/compiler/js-operator.h"
10 #include "src/compiler/node-properties.h"
11 #include "src/compiler/simplified-operator.h"
12 #include "src/heap/factory-inl.h"
13 #include "src/objects/map.h"
14 #include "src/objects/scope-info.h"
15 #include "src/objects/template-objects.h"
16 
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20 
21 // In the functions below, we call the ObjectRef (or subclass) constructor in
22 // order to trigger serialization if not yet done.
23 
JSHeapCopyReducer(JSHeapBroker * broker)24 JSHeapCopyReducer::JSHeapCopyReducer(JSHeapBroker* broker) : broker_(broker) {}
25 
broker()26 JSHeapBroker* JSHeapCopyReducer::broker() { return broker_; }
27 
Reduce(Node * node)28 Reduction JSHeapCopyReducer::Reduce(Node* node) {
29   switch (node->opcode()) {
30     case IrOpcode::kCheckClosure: {
31       FeedbackCellRef cell(broker(), FeedbackCellOf(node->op()));
32       FeedbackVectorRef feedback_vector = cell.value().AsFeedbackVector();
33       feedback_vector.Serialize();
34       break;
35     }
36     case IrOpcode::kHeapConstant: {
37       ObjectRef object(broker(), HeapConstantOf(node->op()));
38       if (object.IsJSFunction()) object.AsJSFunction().Serialize();
39       if (object.IsJSObject()) {
40         object.AsJSObject().SerializeObjectCreateMap();
41       }
42       if (object.IsSourceTextModule()) {
43         object.AsSourceTextModule().Serialize();
44       }
45       break;
46     }
47     case IrOpcode::kJSCreateArray: {
48       CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
49       Handle<AllocationSite> site;
50       if (p.site().ToHandle(&site)) AllocationSiteRef(broker(), site);
51       break;
52     }
53     case IrOpcode::kJSCreateArguments: {
54       Node* const frame_state = NodeProperties::GetFrameStateInput(node);
55       FrameStateInfo state_info = FrameStateInfoOf(frame_state->op());
56       SharedFunctionInfoRef shared(broker(),
57                                    state_info.shared_info().ToHandleChecked());
58       break;
59     }
60     case IrOpcode::kJSCreateBlockContext: {
61       ScopeInfoRef(broker(), ScopeInfoOf(node->op()));
62       break;
63     }
64     case IrOpcode::kJSCreateBoundFunction: {
65       CreateBoundFunctionParameters const& p =
66           CreateBoundFunctionParametersOf(node->op());
67       MapRef(broker(), p.map());
68       break;
69     }
70     case IrOpcode::kJSCreateCatchContext: {
71       ScopeInfoRef(broker(), ScopeInfoOf(node->op()));
72       break;
73     }
74     case IrOpcode::kJSCreateClosure: {
75       CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
76       SharedFunctionInfoRef(broker(), p.shared_info());
77       FeedbackCellRef(broker(), p.feedback_cell());
78       HeapObjectRef(broker(), p.code());
79       break;
80     }
81     case IrOpcode::kJSCreateEmptyLiteralArray: {
82       FeedbackParameter const& p = FeedbackParameterOf(node->op());
83       if (p.feedback().IsValid()) {
84         broker()->ProcessFeedbackForArrayOrObjectLiteral(p.feedback());
85       }
86       break;
87     }
88     case IrOpcode::kJSCreateFunctionContext: {
89       CreateFunctionContextParameters const& p =
90           CreateFunctionContextParametersOf(node->op());
91       ScopeInfoRef(broker(), p.scope_info());
92       break;
93     }
94     case IrOpcode::kJSCreateLiteralArray:
95     case IrOpcode::kJSCreateLiteralObject: {
96       CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
97       if (p.feedback().IsValid()) {
98         broker()->ProcessFeedbackForArrayOrObjectLiteral(p.feedback());
99       }
100       break;
101     }
102     case IrOpcode::kJSCreateLiteralRegExp: {
103       CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op());
104       if (p.feedback().IsValid()) {
105         broker()->ProcessFeedbackForRegExpLiteral(p.feedback());
106       }
107       break;
108     }
109     case IrOpcode::kJSGetTemplateObject: {
110       GetTemplateObjectParameters const& p =
111           GetTemplateObjectParametersOf(node->op());
112       SharedFunctionInfoRef shared(broker(), p.shared());
113       TemplateObjectDescriptionRef description(broker(), p.description());
114       shared.GetTemplateObject(description, p.feedback(),
115                                SerializationPolicy::kSerializeIfNeeded);
116       break;
117     }
118     case IrOpcode::kJSCreateWithContext: {
119       ScopeInfoRef(broker(), ScopeInfoOf(node->op()));
120       break;
121     }
122     case IrOpcode::kJSLoadNamed: {
123       NamedAccess const& p = NamedAccessOf(node->op());
124       NameRef name(broker(), p.name());
125       if (p.feedback().IsValid()) {
126         broker()->ProcessFeedbackForPropertyAccess(p.feedback(),
127                                                    AccessMode::kLoad, name);
128       }
129       break;
130     }
131     case IrOpcode::kJSStoreNamed: {
132       NamedAccess const& p = NamedAccessOf(node->op());
133       NameRef name(broker(), p.name());
134       break;
135     }
136     case IrOpcode::kStoreField:
137     case IrOpcode::kLoadField: {
138       FieldAccess access = FieldAccessOf(node->op());
139       Handle<Map> map_handle;
140       if (access.map.ToHandle(&map_handle)) {
141         MapRef(broker(), map_handle);
142       }
143       Handle<Name> name_handle;
144       if (access.name.ToHandle(&name_handle)) {
145         NameRef(broker(), name_handle);
146       }
147       break;
148     }
149     case IrOpcode::kMapGuard: {
150       ZoneHandleSet<Map> const& maps = MapGuardMapsOf(node->op());
151       for (Handle<Map> map : maps) {
152         MapRef(broker(), map);
153       }
154       break;
155     }
156     case IrOpcode::kCheckMaps: {
157       ZoneHandleSet<Map> const& maps = CheckMapsParametersOf(node->op()).maps();
158       for (Handle<Map> map : maps) {
159         MapRef(broker(), map);
160       }
161       break;
162     }
163     case IrOpcode::kCompareMaps: {
164       ZoneHandleSet<Map> const& maps = CompareMapsParametersOf(node->op());
165       for (Handle<Map> map : maps) {
166         MapRef(broker(), map);
167       }
168       break;
169     }
170     case IrOpcode::kJSLoadProperty: {
171       PropertyAccess const& p = PropertyAccessOf(node->op());
172       AccessMode access_mode = AccessMode::kLoad;
173       if (p.feedback().IsValid()) {
174         broker()->ProcessFeedbackForPropertyAccess(p.feedback(), access_mode,
175                                                    base::nullopt);
176       }
177       break;
178     }
179     default:
180       break;
181   }
182   return NoChange();
183 }
184 
185 }  // namespace compiler
186 }  // namespace internal
187 }  // namespace v8
188