accessor-assembler-impl.h 7.54 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_SRC_IC_ACCESSOR_ASSEMBLER_IMPL_H_
#define V8_SRC_IC_ACCESSOR_ASSEMBLER_IMPL_H_

#include "src/code-stub-assembler.h"

namespace v8 {
namespace internal {

namespace compiler {
class CodeAssemblerState;
}

using compiler::Node;

#define ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(V) \
  V(LoadIC)                                    \
  V(LoadICTrampoline)                          \
  V(KeyedLoadICTF)                             \
  V(KeyedLoadICTrampolineTF)                   \
  V(KeyedLoadICMegamorphic)                    \
  V(StoreIC)                                   \
  V(StoreICTrampoline)
27 28
// The other IC entry points need custom handling because of additional
// parameters like "typeof_mode" or "language_mode".
29 30 31 32 33 34 35 36 37 38 39

class AccessorAssemblerImpl : public CodeStubAssembler {
 public:
  explicit AccessorAssemblerImpl(compiler::CodeAssemblerState* state)
      : CodeStubAssembler(state) {}

#define DECLARE_PUBLIC_METHOD(Name) void Generate##Name();

  ACCESSOR_ASSEMBLER_PUBLIC_INTERFACE(DECLARE_PUBLIC_METHOD)
#undef DECLARE_PUBLIC_METHOD

40 41 42 43 44
  void GenerateLoadICProtoArray(bool throw_reference_error_if_nonexistent);

  void GenerateLoadGlobalIC(TypeofMode typeof_mode);
  void GenerateLoadGlobalICTrampoline(TypeofMode typeof_mode);

45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
  void GenerateKeyedStoreICTF(LanguageMode language_mode);
  void GenerateKeyedStoreICTrampolineTF(LanguageMode language_mode);

  void TryProbeStubCache(StubCache* stub_cache, Node* receiver, Node* name,
                         Label* if_handler, Variable* var_handler,
                         Label* if_miss);

  Node* StubCachePrimaryOffsetForTesting(Node* name, Node* map) {
    return StubCachePrimaryOffset(name, map);
  }
  Node* StubCacheSecondaryOffsetForTesting(Node* name, Node* map) {
    return StubCacheSecondaryOffset(name, map);
  }

 protected:
  struct LoadICParameters {
    LoadICParameters(Node* context, Node* receiver, Node* name, Node* slot,
                     Node* vector)
        : context(context),
          receiver(receiver),
          name(name),
          slot(slot),
          vector(vector) {}

    Node* context;
    Node* receiver;
    Node* name;
    Node* slot;
    Node* vector;
  };

  struct StoreICParameters : public LoadICParameters {
    StoreICParameters(Node* context, Node* receiver, Node* name, Node* value,
                      Node* slot, Node* vector)
        : LoadICParameters(context, receiver, name, slot, vector),
          value(value) {}
    Node* value;
  };

84
  enum ElementSupport { kOnlyProperties, kSupportElements };
85 86 87
  void HandleStoreICHandlerCase(
      const StoreICParameters* p, Node* handler, Label* miss,
      ElementSupport support_elements = kOnlyProperties);
88

89
 private:
90 91 92
  // Stub generation entry points.

  void LoadIC(const LoadICParameters* p);
93 94 95
  void LoadICProtoArray(const LoadICParameters* p, Node* handler,
                        bool throw_reference_error_if_nonexistent);
  void LoadGlobalIC(const LoadICParameters* p, TypeofMode typeof_mode);
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
  void KeyedLoadIC(const LoadICParameters* p);
  void KeyedLoadICGeneric(const LoadICParameters* p);
  void StoreIC(const StoreICParameters* p);
  void KeyedStoreIC(const StoreICParameters* p, LanguageMode language_mode);

  // IC dispatcher behavior.

  // Checks monomorphic case. Returns {feedback} entry of the vector.
  Node* TryMonomorphicCase(Node* slot, Node* vector, Node* receiver_map,
                           Label* if_handler, Variable* var_handler,
                           Label* if_miss);
  void HandlePolymorphicCase(Node* receiver_map, Node* feedback,
                             Label* if_handler, Variable* var_handler,
                             Label* if_miss, int unroll_count);
  void HandleKeyedStorePolymorphicCase(Node* receiver_map, Node* feedback,
                                       Label* if_handler, Variable* var_handler,
                                       Label* if_transition_handler,
                                       Variable* var_transition_map_cell,
                                       Label* if_miss);

  // LoadIC implementation.

  void HandleLoadICHandlerCase(
      const LoadICParameters* p, Node* handler, Label* miss,
      ElementSupport support_elements = kOnlyProperties);

  void HandleLoadICSmiHandlerCase(const LoadICParameters* p, Node* holder,
                                  Node* smi_handler, Label* miss,
                                  ElementSupport support_elements);

126 127 128 129 130
  void HandleLoadICProtoHandlerCase(const LoadICParameters* p, Node* handler,
                                    Variable* var_holder,
                                    Variable* var_smi_handler,
                                    Label* if_smi_handler, Label* miss,
                                    bool throw_reference_error_if_nonexistent);
131 132 133

  Node* EmitLoadICProtoArrayCheck(const LoadICParameters* p, Node* handler,
                                  Node* handler_length, Node* handler_flags,
134 135 136 137 138 139 140 141
                                  Label* miss,
                                  bool throw_reference_error_if_nonexistent);

  // LoadGlobalIC implementation.

  void HandleLoadGlobalICHandlerCase(const LoadICParameters* p, Node* handler,
                                     Label* miss,
                                     bool throw_reference_error_if_nonexistent);
142 143 144

  // StoreIC implementation.

145 146 147
  void HandleStoreICElementHandlerCase(const StoreICParameters* p,
                                       Node* handler, Label* miss);

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
  void HandleStoreICProtoHandler(const StoreICParameters* p, Node* handler,
                                 Label* miss);
  // If |transition| is nullptr then the normal field store is generated or
  // transitioning store otherwise.
  void HandleStoreICSmiHandlerCase(Node* handler_word, Node* holder,
                                   Node* value, Node* transition, Label* miss);
  // If |transition| is nullptr then the normal field store is generated or
  // transitioning store otherwise.
  void HandleStoreFieldAndReturn(Node* handler_word, Node* holder,
                                 Representation representation, Node* value,
                                 Node* transition, Label* miss);

  // Low-level helpers.

  void EmitFastElementsBoundsCheck(Node* object, Node* elements,
                                   Node* intptr_index,
                                   Node* is_jsarray_condition, Label* miss);
  void EmitElementLoad(Node* object, Node* elements, Node* elements_kind,
                       Node* key, Node* is_jsarray_condition, Label* if_hole,
                       Label* rebox_double, Variable* var_double_value,
                       Label* unimplemented_elements_kind, Label* out_of_bounds,
                       Label* miss);
  void CheckPrototype(Node* prototype_cell, Node* name, Label* miss);
  void NameDictionaryNegativeLookup(Node* object, Node* name, Label* miss);

  // Stub cache access helpers.

  // This enum is used here as a replacement for StubCache::Table to avoid
  // including stub cache header.
  enum StubCacheTable : int;

  Node* StubCachePrimaryOffset(Node* name, Node* map);
  Node* StubCacheSecondaryOffset(Node* name, Node* seed);

  void TryProbeStubCacheTable(StubCache* stub_cache, StubCacheTable table_id,
                              Node* entry_offset, Node* name, Node* map,
                              Label* if_handler, Variable* var_handler,
                              Label* if_miss);
};

}  // namespace internal
}  // namespace v8

#endif  // V8_SRC_IC_ACCESSOR_ASSEMBLER_IMPL_H_