Home | History | Annotate | Download | only in compiler
      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_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
      6 #define V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
      7 
      8 #include "src/base/flags.h"
      9 #include "src/compiler/graph-reducer.h"
     10 #include "src/deoptimize-reason.h"
     11 #include "src/feedback-vector.h"
     12 
     13 namespace v8 {
     14 namespace internal {
     15 
     16 // Forward declarations.
     17 class CompilationDependencies;
     18 class Factory;
     19 
     20 namespace compiler {
     21 
     22 // Forward declarations.
     23 enum class AccessMode;
     24 class CommonOperatorBuilder;
     25 class ElementAccessInfo;
     26 class JSGraph;
     27 class JSOperatorBuilder;
     28 class MachineOperatorBuilder;
     29 class PropertyAccessInfo;
     30 class SimplifiedOperatorBuilder;
     31 class TypeCache;
     32 
     33 // Specializes a given JSGraph to a given native context, potentially constant
     34 // folding some {LoadGlobal} nodes or strength reducing some {StoreGlobal}
     35 // nodes.  And also specializes {LoadNamed} and {StoreNamed} nodes according
     36 // to type feedback (if available).
     37 class JSNativeContextSpecialization final : public AdvancedReducer {
     38  public:
     39   // Flags that control the mode of operation.
     40   enum Flag {
     41     kNoFlags = 0u,
     42     kAccessorInliningEnabled = 1u << 0,
     43     kBailoutOnUninitialized = 1u << 1,
     44     kDeoptimizationEnabled = 1u << 2,
     45   };
     46   typedef base::Flags<Flag> Flags;
     47 
     48   JSNativeContextSpecialization(Editor* editor, JSGraph* jsgraph, Flags flags,
     49                                 Handle<Context> native_context,
     50                                 CompilationDependencies* dependencies,
     51                                 Zone* zone);
     52 
     53   Reduction Reduce(Node* node) final;
     54 
     55  private:
     56   Reduction ReduceJSAdd(Node* node);
     57   Reduction ReduceJSGetSuperConstructor(Node* node);
     58   Reduction ReduceJSInstanceOf(Node* node);
     59   Reduction ReduceJSOrdinaryHasInstance(Node* node);
     60   Reduction ReduceJSLoadContext(Node* node);
     61   Reduction ReduceJSLoadGlobal(Node* node);
     62   Reduction ReduceJSStoreGlobal(Node* node);
     63   Reduction ReduceJSLoadNamed(Node* node);
     64   Reduction ReduceJSStoreNamed(Node* node);
     65   Reduction ReduceJSLoadProperty(Node* node);
     66   Reduction ReduceJSStoreProperty(Node* node);
     67   Reduction ReduceJSStoreNamedOwn(Node* node);
     68   Reduction ReduceJSStoreDataPropertyInLiteral(Node* node);
     69 
     70   Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
     71                                 MapHandleList const& receiver_maps,
     72                                 AccessMode access_mode,
     73                                 LanguageMode language_mode,
     74                                 KeyedAccessStoreMode store_mode);
     75   template <typename KeyedICNexus>
     76   Reduction ReduceKeyedAccess(Node* node, Node* index, Node* value,
     77                               KeyedICNexus const& nexus, AccessMode access_mode,
     78                               LanguageMode language_mode,
     79                               KeyedAccessStoreMode store_mode);
     80   Reduction ReduceNamedAccessFromNexus(Node* node, Node* value,
     81                                        FeedbackNexus const& nexus,
     82                                        Handle<Name> name,
     83                                        AccessMode access_mode,
     84                                        LanguageMode language_mode);
     85   Reduction ReduceNamedAccess(Node* node, Node* value,
     86                               MapHandleList const& receiver_maps,
     87                               Handle<Name> name, AccessMode access_mode,
     88                               LanguageMode language_mode,
     89                               Handle<FeedbackVector> vector, FeedbackSlot slot,
     90                               Node* index = nullptr);
     91   Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
     92                                Handle<Name> name, AccessMode access_mode,
     93                                Node* index = nullptr);
     94 
     95   Reduction ReduceSoftDeoptimize(Node* node, DeoptimizeReason reason);
     96 
     97   // A triple of nodes that represents a continuation.
     98   class ValueEffectControl final {
     99    public:
    100     ValueEffectControl(Node* value, Node* effect, Node* control)
    101         : value_(value), effect_(effect), control_(control) {}
    102 
    103     Node* value() const { return value_; }
    104     Node* effect() const { return effect_; }
    105     Node* control() const { return control_; }
    106 
    107    private:
    108     Node* const value_;
    109     Node* const effect_;
    110     Node* const control_;
    111   };
    112 
    113   // Construct the appropriate subgraph for property access.
    114   ValueEffectControl BuildPropertyAccess(
    115       Node* receiver, Node* value, Node* context, Node* frame_state,
    116       Node* effect, Node* control, Handle<Name> name,
    117       PropertyAccessInfo const& access_info, AccessMode access_mode,
    118       LanguageMode language_mode, Handle<FeedbackVector> vector,
    119       FeedbackSlot slot);
    120 
    121   // Construct the appropriate subgraph for element access.
    122   ValueEffectControl BuildElementAccess(Node* receiver, Node* index,
    123                                         Node* value, Node* effect,
    124                                         Node* control,
    125                                         ElementAccessInfo const& access_info,
    126                                         AccessMode access_mode,
    127                                         KeyedAccessStoreMode store_mode);
    128 
    129   // Construct an appropriate heap object check.
    130   Node* BuildCheckHeapObject(Node* receiver, Node** effect, Node* control);
    131 
    132   // Construct an appropriate map check.
    133   Node* BuildCheckMaps(Node* receiver, Node* effect, Node* control,
    134                        std::vector<Handle<Map>> const& maps);
    135 
    136   // Adds stability dependencies on all prototypes of every class in
    137   // {receiver_type} up to (and including) the {holder}.
    138   void AssumePrototypesStable(std::vector<Handle<Map>> const& receiver_maps,
    139                               Handle<JSObject> holder);
    140 
    141   // Checks if we can turn the hole into undefined when loading an element
    142   // from an object with one of the {receiver_maps}; sets up appropriate
    143   // code dependencies and might use the array protector cell.
    144   bool CanTreatHoleAsUndefined(std::vector<Handle<Map>> const& receiver_maps);
    145 
    146   // Extract receiver maps from {nexus} and filter based on {receiver} if
    147   // possible.
    148   bool ExtractReceiverMaps(Node* receiver, Node* effect,
    149                            FeedbackNexus const& nexus,
    150                            MapHandleList* receiver_maps);
    151 
    152   // Try to infer maps for the given {receiver} at the current {effect}.
    153   // If maps are returned then you can be sure that the {receiver} definitely
    154   // has one of the returned maps at this point in the program (identified
    155   // by {effect}).
    156   bool InferReceiverMaps(Node* receiver, Node* effect,
    157                          MapHandleList* receiver_maps);
    158   // Try to infer a root map for the {receiver} independent of the current
    159   // program location.
    160   MaybeHandle<Map> InferReceiverRootMap(Node* receiver);
    161 
    162   ValueEffectControl InlineApiCall(
    163       Node* receiver, Node* context, Node* target, Node* frame_state,
    164       Node* parameter, Node* effect, Node* control,
    165       Handle<SharedFunctionInfo> shared_info,
    166       Handle<FunctionTemplateInfo> function_template_info);
    167 
    168   // Script context lookup logic.
    169   struct ScriptContextTableLookupResult;
    170   bool LookupInScriptContextTable(Handle<Name> name,
    171                                   ScriptContextTableLookupResult* result);
    172 
    173   Graph* graph() const;
    174   JSGraph* jsgraph() const { return jsgraph_; }
    175   Isolate* isolate() const;
    176   Factory* factory() const;
    177   CommonOperatorBuilder* common() const;
    178   JSOperatorBuilder* javascript() const;
    179   SimplifiedOperatorBuilder* simplified() const;
    180   MachineOperatorBuilder* machine() const;
    181   Flags flags() const { return flags_; }
    182   Handle<JSGlobalObject> global_object() const { return global_object_; }
    183   Handle<JSGlobalProxy> global_proxy() const { return global_proxy_; }
    184   Handle<Context> native_context() const { return native_context_; }
    185   CompilationDependencies* dependencies() const { return dependencies_; }
    186   Zone* zone() const { return zone_; }
    187 
    188   JSGraph* const jsgraph_;
    189   Flags const flags_;
    190   Handle<JSGlobalObject> global_object_;
    191   Handle<JSGlobalProxy> global_proxy_;
    192   Handle<Context> native_context_;
    193   CompilationDependencies* const dependencies_;
    194   Zone* const zone_;
    195   TypeCache const& type_cache_;
    196 
    197   DISALLOW_COPY_AND_ASSIGN(JSNativeContextSpecialization);
    198 };
    199 
    200 DEFINE_OPERATORS_FOR_FLAGS(JSNativeContextSpecialization::Flags)
    201 
    202 }  // namespace compiler
    203 }  // namespace internal
    204 }  // namespace v8
    205 
    206 #endif  // V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
    207