16474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
26474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
36474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org// found in the LICENSE file.
46474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
56474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#ifndef V8_IC_HANDLER_COMPILER_H_
66474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#define V8_IC_HANDLER_COMPILER_H_
76474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
86474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/access-compiler.h"
9d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org#include "src/ic/ic-state.h"
106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgnamespace v8 {
126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgnamespace internal {
136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgclass CallOptimization;
156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgenum PrototypeCheckType { CHECK_ALL_MAPS, SKIP_RECEIVER };
176474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
186474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgclass PropertyHandlerCompiler : public PropertyAccessCompiler {
196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org public:
206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static Handle<Code> Find(Handle<Name> name, Handle<Map> map, Code::Kind kind,
216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                           CacheHolderFlag cache_holder, Code::StubType type);
226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org protected:
246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  PropertyHandlerCompiler(Isolate* isolate, Code::Kind kind,
256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                          Handle<HeapType> type, Handle<JSObject> holder,
266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                          CacheHolderFlag cache_holder)
276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      : PropertyAccessCompiler(isolate, kind, cache_holder),
286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        type_(type),
296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        holder_(holder) {}
306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual ~PropertyHandlerCompiler() {}
326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                  Label* miss) {
356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    UNREACHABLE();
366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    return receiver();
376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  }
386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual void FrontendFooter(Handle<Name> name, Label* miss) { UNREACHABLE(); }
406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Register Frontend(Register object_reg, Handle<Name> name);
426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void NonexistentFrontendHeader(Handle<Name> name, Label* miss,
436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                 Register scratch1, Register scratch2);
446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // TODO(verwaest): Make non-static.
466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateFastApiCall(MacroAssembler* masm,
476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                  const CallOptimization& optimization,
486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                  Handle<Map> receiver_map, Register receiver,
496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                  Register scratch, bool is_store, int argc,
506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                  Register* values);
516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // Helper function used to check that the dictionary doesn't contain
536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // the property. This function may return false negatives, so miss_label
546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // must always call a backup property check that is complete.
556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // This function is safe to call if the receiver has fast properties.
566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // Name must be unique and receiver must be a heap object.
576474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateDictionaryNegativeLookup(MacroAssembler* masm,
586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                               Label* miss_label,
596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                               Register receiver,
606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                               Handle<Name> name, Register r0,
616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                               Register r1);
626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // Generate code to check that a global property cell is empty. Create
646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // the property cell at compilation time if no cell exists for the
656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // property.
666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateCheckPropertyCell(MacroAssembler* masm,
676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                        Handle<JSGlobalObject> global,
686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                        Handle<Name> name, Register scratch,
696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                        Label* miss);
706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
716474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // Generates code that verifies that the property holder has not changed
726474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // (checking maps of objects in the prototype chain for fast and global
736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // objects or doing negative lookup for slow objects, ensures that the
746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // property cells for global objects are still empty) and checks that the map
756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // of the holder has not changed. If necessary the function also generates
766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // code for security check in case of global object holders. Helps to make
776474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // sure that the current IC is still valid.
786474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  //
796474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // The scratch and holder registers are always clobbered, but the object
806474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // register is only clobbered if it the same as the holder register. The
816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // function returns a register containing the holder - either object_reg or
826474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // holder_reg.
836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Register CheckPrototypes(Register object_reg, Register holder_reg,
846474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                           Register scratch1, Register scratch2,
856474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                           Handle<Name> name, Label* miss,
866474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                           PrototypeCheckType check = CHECK_ALL_MAPS);
876474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
886474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> GetCode(Code::Kind kind, Code::StubType type, Handle<Name> name);
89d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org  void set_type_for_object(Handle<Object> object);
906474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void set_holder(Handle<JSObject> holder) { holder_ = holder; }
916474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<HeapType> type() const { return type_; }
926474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<JSObject> holder() const { return holder_; }
936474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
946474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org private:
956474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<HeapType> type_;
966474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<JSObject> holder_;
976474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org};
986474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
996474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1006474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgclass NamedLoadHandlerCompiler : public PropertyHandlerCompiler {
1016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org public:
1026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  NamedLoadHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
1036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                           Handle<JSObject> holder,
1046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                           CacheHolderFlag cache_holder)
1056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      : PropertyHandlerCompiler(isolate, Code::LOAD_IC, type, holder,
1066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                cache_holder) {}
1076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual ~NamedLoadHandlerCompiler() {}
1096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileLoadField(Handle<Name> name, FieldIndex index);
1116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileLoadCallback(Handle<Name> name,
1136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                   Handle<ExecutableAccessorInfo> callback);
1146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileLoadCallback(Handle<Name> name,
1166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                   const CallOptimization& call_optimization);
1176474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1186474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileLoadConstant(Handle<Name> name, int constant_index);
1196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // The LookupIterator is used to perform a lookup behind the interceptor. If
1216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // the iterator points to a LookupIterator::PROPERTY, its access will be
1226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // inlined.
1236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileLoadInterceptor(LookupIterator* it);
1246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileLoadViaGetter(Handle<Name> name,
1266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                    Handle<JSFunction> getter);
1276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileLoadGlobal(Handle<PropertyCell> cell, Handle<Name> name,
1296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                 bool is_configurable);
1306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // Static interface
1326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static Handle<Code> ComputeLoadNonexistent(Handle<Name> name,
1336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                             Handle<HeapType> type);
1346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateLoadViaGetter(MacroAssembler* masm, Handle<HeapType> type,
1366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                    Register receiver,
1376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                    Handle<JSFunction> getter);
1386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateLoadViaGetterForDeopt(MacroAssembler* masm) {
1406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    GenerateLoadViaGetter(masm, Handle<HeapType>::null(), no_reg,
1416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                          Handle<JSFunction>());
1426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  }
1436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateLoadFunctionPrototype(MacroAssembler* masm,
1456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                            Register receiver,
1466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                            Register scratch1,
1476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                            Register scratch2,
1486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                            Label* miss_label);
1496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // These constants describe the structure of the interceptor arguments on the
1516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // stack. The arguments are pushed by the (platform-specific)
1526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // PushInterceptorArguments and read by LoadPropertyWithInterceptorOnly and
1536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // LoadWithInterceptor.
1546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static const int kInterceptorArgsNameIndex = 0;
1556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static const int kInterceptorArgsInfoIndex = 1;
1566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static const int kInterceptorArgsThisIndex = 2;
1576474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static const int kInterceptorArgsHolderIndex = 3;
1586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static const int kInterceptorArgsLength = 4;
1596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org protected:
1616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
1626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                  Label* miss);
1636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual void FrontendFooter(Handle<Name> name, Label* miss);
1656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org private:
1676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileLoadNonexistent(Handle<Name> name);
1686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void GenerateLoadConstant(Handle<Object> value);
1696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void GenerateLoadCallback(Register reg,
1706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                            Handle<ExecutableAccessorInfo> callback);
1716474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void GenerateLoadCallback(const CallOptimization& call_optimization,
1726474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                            Handle<Map> receiver_map);
1736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void GenerateLoadInterceptor(Register holder_reg);
1746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void GenerateLoadInterceptorWithFollowup(LookupIterator* it,
1756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                           Register holder_reg);
1766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void GenerateLoadPostInterceptor(LookupIterator* it, Register reg);
1776474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1786474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // Generates prototype loading code that uses the objects from the
1796474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // context we were in when this function was called. If the context
1806474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // has changed, a jump to miss is performed. This ties the generated
1816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // code to a particular context and so must not be used in cases
1826474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // where the generated code is not allowed to have references to
1836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // objects from a context.
1846474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateDirectLoadGlobalFunctionPrototype(MacroAssembler* masm,
1856474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                                        int index,
1866474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                                        Register prototype,
1876474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                                        Label* miss);
1886474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1896474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1906474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Register scratch4() { return registers_[5]; }
1916474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org};
1926474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1936474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
1946474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgclass NamedStoreHandlerCompiler : public PropertyHandlerCompiler {
1956474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org public:
1966474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  explicit NamedStoreHandlerCompiler(Isolate* isolate, Handle<HeapType> type,
1976474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                     Handle<JSObject> holder)
1986474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      : PropertyHandlerCompiler(isolate, Code::STORE_IC, type, holder,
1996474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                kCacheOnReceiver) {}
2006474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual ~NamedStoreHandlerCompiler() {}
2026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileStoreTransition(Handle<Map> transition,
2046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                      Handle<Name> name);
2056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileStoreField(LookupIterator* it);
2066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
2076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                    Handle<ExecutableAccessorInfo> callback);
2086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileStoreCallback(Handle<JSObject> object, Handle<Name> name,
2096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                    const CallOptimization& call_optimization);
2106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileStoreViaSetter(Handle<JSObject> object, Handle<Name> name,
2116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                     Handle<JSFunction> setter);
2126474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<Code> CompileStoreInterceptor(Handle<Name> name);
2136474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2146474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateStoreViaSetter(MacroAssembler* masm,
2156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                     Handle<HeapType> type, Register receiver,
2166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                     Handle<JSFunction> setter);
2176474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2186474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateStoreViaSetterForDeopt(MacroAssembler* masm) {
2196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    GenerateStoreViaSetter(masm, Handle<HeapType>::null(), no_reg,
2206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                           Handle<JSFunction>());
2216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  }
2226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateSlow(MacroAssembler* masm);
2246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org protected:
2266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual Register FrontendHeader(Register object_reg, Handle<Name> name,
2276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                  Label* miss);
2286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2296474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual void FrontendFooter(Handle<Name> name, Label* miss);
2306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void GenerateRestoreName(Label* label, Handle<Name> name);
2316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org private:
2336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void GenerateStoreTransition(Handle<Map> transition, Handle<Name> name,
2346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                               Register receiver_reg, Register name_reg,
2356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                               Register value_reg, Register scratch1,
2366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                               Register scratch2, Register scratch3,
2376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                               Label* miss_label, Label* slow);
2386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void GenerateStoreField(LookupIterator* lookup, Register value_reg,
2406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                          Label* miss_label);
2416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static Builtins::Name SlowBuiltin(Code::Kind kind) {
2436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    switch (kind) {
2446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      case Code::STORE_IC:
2456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        return Builtins::kStoreIC_Slow;
2466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      case Code::KEYED_STORE_IC:
2476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        return Builtins::kKeyedStoreIC_Slow;
2486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      default:
2496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        UNREACHABLE();
2506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    }
2516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    return Builtins::kStoreIC_Slow;
2526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  }
2536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static Register value();
2556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org};
2566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2576474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgclass ElementHandlerCompiler : public PropertyHandlerCompiler {
2596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org public:
2606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  explicit ElementHandlerCompiler(Isolate* isolate)
2616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      : PropertyHandlerCompiler(isolate, Code::KEYED_LOAD_IC,
2626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                Handle<HeapType>::null(),
2636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                Handle<JSObject>::null(), kCacheOnReceiver) {}
2646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  virtual ~ElementHandlerCompiler() {}
2666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  void CompileElementHandlers(MapHandleList* receiver_maps,
2686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                              CodeHandleList* handlers);
2696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  static void GenerateStoreSlow(MacroAssembler* masm);
2716474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org};
2726474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org}
2736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org}  // namespace v8::internal
2746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#endif  // V8_IC_HANDLER_COMPILER_H_
276