1014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved.
2014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// found in the LICENSE file.
4014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
7014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/flags.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/graph-reducer.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace v8 {
12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace internal {
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations.
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CompilationDependencies;
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Factory;
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FeedbackNexus;
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TypeCache;
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace compiler {
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations.
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum class AccessMode;
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CommonOperatorBuilder;
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass JSGraph;
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass JSOperatorBuilder;
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass MachineOperatorBuilder;
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SimplifiedOperatorBuilder;
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Specializes a given JSGraph to a given native context, potentially constant
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// folding some {LoadGlobal} nodes or strength reducing some {StoreGlobal}
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// nodes.  And also specializes {LoadNamed} and {StoreNamed} nodes according
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// to type feedback (if available).
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass JSNativeContextSpecialization final : public AdvancedReducer {
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Flags that control the mode of operation.
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Flag {
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kNoFlags = 0u,
41342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    kBailoutOnUninitialized = 1u << 0,
42342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch    kDeoptimizationEnabled = 1u << 1,
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef base::Flags<Flag> Flags;
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSNativeContextSpecialization(Editor* editor, JSGraph* jsgraph, Flags flags,
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                MaybeHandle<Context> native_context,
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                CompilationDependencies* dependencies,
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                Zone* zone);
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Reduction Reduce(Node* node) final;
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
54342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  Reduction ReduceJSLoadContext(Node* node);
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Reduction ReduceJSLoadNamed(Node* node);
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Reduction ReduceJSStoreNamed(Node* node);
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Reduction ReduceJSLoadProperty(Node* node);
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Reduction ReduceJSStoreProperty(Node* node);
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                MapHandleList const& receiver_maps,
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                AccessMode access_mode,
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                LanguageMode language_mode,
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                KeyedAccessStoreMode store_mode);
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Reduction ReduceKeyedAccess(Node* node, Node* index, Node* value,
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              FeedbackNexus const& nexus,
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              AccessMode access_mode,
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              LanguageMode language_mode,
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              KeyedAccessStoreMode store_mode);
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Reduction ReduceNamedAccess(Node* node, Node* value,
71342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                              FeedbackNexus const& nexus, Handle<Name> name,
72342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                              AccessMode access_mode,
73342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch                              LanguageMode language_mode);
74342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  Reduction ReduceNamedAccess(Node* node, Node* value,
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              MapHandleList const& receiver_maps,
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              Handle<Name> name, AccessMode access_mode,
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              LanguageMode language_mode,
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              Node* index = nullptr);
79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
80342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch  Reduction ReduceSoftDeoptimize(Node* node);
81342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Adds stability dependencies on all prototypes of every class in
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // {receiver_type} up to (and including) the {holder}.
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssumePrototypesStable(Type* receiver_type,
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              Handle<Context> native_context,
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              Handle<JSObject> holder);
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
88537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  // Extract receiver maps from {nexus} and filter based on {receiver} if
89537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  // possible.
90537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  bool ExtractReceiverMaps(Node* receiver, Node* effect,
91537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch                           FeedbackNexus const& nexus,
92537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch                           MapHandleList* receiver_maps);
93537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch
94537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  // Try to infer a map for the given {receiver} at the current {effect}.
95537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  // If a map is returned then you can be sure that the {receiver} definitely
96537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  // has the returned map at this point in the program (identified by {effect}).
97537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  MaybeHandle<Map> InferReceiverMap(Node* receiver, Node* effect);
98537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  // Try to infer a root map for the {receiver} independent of the current
99537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  // program location.
100537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch  MaybeHandle<Map> InferReceiverRootMap(Node* receiver);
101537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Retrieve the native context from the given {node} if known.
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaybeHandle<Context> GetNativeContext(Node* node);
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Graph* graph() const;
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSGraph* jsgraph() const { return jsgraph_; }
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Isolate* isolate() const;
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Factory* factory() const;
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CommonOperatorBuilder* common() const;
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSOperatorBuilder* javascript() const;
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SimplifiedOperatorBuilder* simplified() const;
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineOperatorBuilder* machine() const;
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Flags flags() const { return flags_; }
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaybeHandle<Context> native_context() const { return native_context_; }
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CompilationDependencies* dependencies() const { return dependencies_; }
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone* zone() const { return zone_; }
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  JSGraph* const jsgraph_;
119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Flags const flags_;
120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MaybeHandle<Context> native_context_;
121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CompilationDependencies* const dependencies_;
122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone* const zone_;
123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TypeCache const& type_cache_;
124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(JSNativeContextSpecialization);
126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_OPERATORS_FOR_FLAGS(JSNativeContextSpecialization::Flags)
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace compiler
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
135