1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_IC_HANDLER_COMPILER_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_IC_HANDLER_COMPILER_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/access-compiler.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/ic-state.h"
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass CallOptimization;
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochenum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER };
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass PropertyHandlerCompiler : public PropertyAccessCompiler {
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> Find(Handle<Name> name, Handle<Map> map, Code::Kind kind,
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           CacheHolderFlag cache_holder, Code::StubType type);
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind,
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          Handle<HeapType> type, Handle<JSObject> holder,
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          CacheHolderFlag cache_holder)
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : PropertyAccessCompiler(isolate, kind, cache_holder),
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        type_(type),
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        holder_(holder) {}
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~PropertyHandlerCompiler() {}
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Label* miss) {
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return receiver();
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void FrontendFooter(Handle<Name> name, Label* miss) { UNREACHABLE(); }
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register Frontend(Register object_reg, Handle<Name> name);
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void NonexistentFrontendHeader(Handle<Name> name, Label* miss,
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Register scratch1, Register scratch2);
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(verwaest): Make non-static.
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateFastApiCall(MacroAssembler* masm,
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  const CallOptimization& optimization,
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Handle<Map> receiver_map, Register receiver,
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Register scratch, bool is_store, int argc,
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Register* values);
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Helper function used to check that the dictionary doesn't contain
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the property. This function may return false negatives, so miss_label
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // must always call a backup property check that is complete.
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This function is safe to call if the receiver has fast properties.
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Name must be unique and receiver must be a heap object.
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Label* miss_label,
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Register receiver,
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Handle<Name> name, Register r0,
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Register r1);
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Generate code to check that a global property cell is empty. Create
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the property cell at compilation time if no cell exists for the
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // property.
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateCheckPropertyCell(MacroAssembler* masm,
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        Handle<JSGlobalObject> global,
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        Handle<Name> name, Register scratch,
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        Label* miss);
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Generates code that verifies that the property holder has not changed
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // (checking maps of objects in the prototype chain for fast and global
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects or doing negative lookup for slow objects, ensures that the
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // property cells for global objects are still empty) and checks that the map
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of the holder has not changed. If necessary the function also generates
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code for security check in case of global object holders. Helps to make
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // sure that the current IC is still valid.
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The scratch and holder registers are always clobbered, but the object
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // register is only clobbered if it the same as the holder register. The
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // function returns a register containing the holder - either object_reg or
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // holder_reg.
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register CheckPrototypes(Register object_reg, Register holder_reg,
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           Register scratch1, Register scratch2,
85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           Handle<Name> name, Label* miss,
86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           PrototypeCheckType check = CHECK_ALL_MAPS);
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name);
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_type_for_object(Handle<Object> object);
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_holder(Handle<JSObject> holder) { holder_ = holder; }
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<HeapType> type() const { return type_; }
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSObject> holder() const { return holder_; }
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<HeapType> type_;
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSObject> holder_;
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NamedLoadHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           Handle<JSObject> holder,
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           CacheHolderFlag cache_holder)
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : PropertyHandlerCompiler(isolate, Code::LOAD_IC, type, holder,
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                cache_holder) {}
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~NamedLoadHandlerCompiler() {}
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileLoadField(Handle<Name> name, FieldIndex index);
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileLoadCallback(Handle<Name> name,
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   Handle<ExecutableAccessorInfo> callback);
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileLoadCallback(Handle<Name> name,
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   const CallOptimization& call_optimization);
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileLoadConstant(Handle<Name> name, int constant_index);
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // The LookupIterator is used to perform a lookup behind the interceptor. If
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the iterator points to a LookupIterator::PROPERTY, its access will be
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // inlined.
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileLoadInterceptor(LookupIterator* it);
124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileLoadViaGetter(Handle<Name> name,
126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Handle<JSFunction> getter);
127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileLoadGlobal(Handle<PropertyCell> cell, Handle<Name> name,
129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 bool is_configurable);
130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Static interface
132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             Handle<HeapType> type);
134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<HeapType> type,
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Register receiver,
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Handle<JSFunction> getter);
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) {
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenerateLoadViaGetter(masm, Handle<HeapType>::null(), no_reg,
141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          Handle<JSFunction>());
142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            Register receiver,
146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            Register scratch1,
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            Register scratch2,
148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            Label* miss_label);
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // These constants describe the structure of the interceptor arguments on the
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // stack. The arguments are pushed by the (platform-specific)
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // LoadWithInterceptor.
154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInterceptorArgsNameIndex = 0;
155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInterceptorArgsInfoIndex = 1;
156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInterceptorArgsThisIndex = 2;
157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInterceptorArgsHolderIndex = 3;
158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const int kInterceptorArgsLength = 4;
159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Label* miss);
163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void FrontendFooter(Handle<Name> name, Label* miss);
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileLoadNonexistent(Handle<Name> name);
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenerateLoadConstant(Handle<Object> value);
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenerateLoadCallback(Register reg,
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            Handle<ExecutableAccessorInfo> callback);
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenerateLoadCallback(const CallOptimization& call_optimization,
172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            Handle<Map> receiver_map);
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenerateLoadInterceptor(Register holder_reg);
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenerateLoadInterceptorWithFollowup(LookupIterator* it,
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           Register holder_reg);
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenerateLoadPostInterceptor(LookupIterator* it, Register reg);
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Generates prototype loading code that uses the objects from the
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // context we were in when this function was called. If the context
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // has changed, a jump to miss is performed. This ties the generated
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code to a particular context and so must not be used in cases
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // where the generated code is not allowed to have references to
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // objects from a context.
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        int index,
186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        Register prototype,
187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        Label* miss);
188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Register scratch4() { return registers_[5]; }
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Handle<JSObject> holder)
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : PropertyHandlerCompiler(isolate, Code::STORE_IC, type, holder,
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                kCacheOnReceiver) {}
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~NamedStoreHandlerCompiler() {}
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileStoreTransition(Handle<Map> transition,
204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Handle<Name> name);
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileStoreField(LookupIterator* it);
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    Handle<ExecutableAccessorInfo> callback);
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    const CallOptimization& call_optimization);
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileStoreViaSetter(Handle<JSObject> object, Handle<Name> name,
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Handle<JSFunction> setter);
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Code> CompileStoreInterceptor(Handle<Name> name);
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateStoreViaSetter(MacroAssembler* masm,
215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Handle<HeapType> type, Register receiver,
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Handle<JSFunction> setter);
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) {
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GenerateStoreViaSetter(masm, Handle<HeapType>::null(), no_reg,
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           Handle<JSFunction>());
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateSlow(MacroAssembler* masm);
224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Label* miss);
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void FrontendFooter(Handle<Name> name, Label* miss);
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenerateRestoreName(Label* label, Handle<Name> name);
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenerateStoreTransition(Handle<Map> transition, Handle<Name> name,
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Register receiver_reg, Register name_reg,
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Register value_reg, Register scratch1,
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Register scratch2, Register scratch3,
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Label* miss_label, Label* slow);
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void GenerateStoreField(LookupIterator* lookup, Register value_reg,
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          Label* miss_label);
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Builtins::Name SlowBuiltin(Code::Kind kind) {
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (kind) {
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case Code::STORE_IC:
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Builtins::kStoreIC_Slow;
246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case Code::KEYED_STORE_IC:
247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return Builtins::kKeyedStoreIC_Slow;
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      default:
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Builtins::kStoreIC_Slow;
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static Register value();
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ElementHandlerCompiler : public PropertyHandlerCompiler {
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit ElementHandlerCompiler(Isolate* isolate)
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : PropertyHandlerCompiler(isolate, Code::KEYED_LOAD_IC,
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                Handle<HeapType>::null(),
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                Handle<JSObject>::null(), kCacheOnReceiver) {}
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual ~ElementHandlerCompiler() {}
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CompileElementHandlers(MapHandleList* receiver_maps,
268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              CodeHandleList* handlers);
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static void GenerateStoreSlow(MacroAssembler* masm);
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // namespace v8::internal
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_IC_HANDLER_COMPILER_H_
276