16474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
45c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
65c838251403b0be9a882540f1922577abba4c872ager@chromium.org
793a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
89dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
96474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/call-optimization.h"
106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/handler-compiler.h"
11d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org#include "src/ic/ic.h"
125c838251403b0be9a882540f1922577abba4c872ager@chromium.org
135c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 {
145c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal {
155c838251403b0be9a882540f1922577abba4c872ager@chromium.org
165c838251403b0be9a882540f1922577abba4c872ager@chromium.org#define __ ACCESS_MASM(masm)
175c838251403b0be9a882540f1922577abba4c872ager@chromium.org
185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
196474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadViaGetter(
206474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
216474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    Handle<JSFunction> getter) {
226474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // ----------- S t a t e -------------
236474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  //  -- a0    : receiver
246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  //  -- a2    : name
256474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  //  -- ra    : return address
266474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // -----------------------------------
276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  {
286474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    FrameScope scope(masm, StackFrame::INTERNAL);
29c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    if (!getter.is_null()) {
316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      // Call the JavaScript getter with the receiver on the stack.
326474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        // Swap in the global receiver.
346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        __ lw(receiver,
356474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org              FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
366474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      }
376474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      __ push(receiver);
386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      ParameterCount actual(0);
396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      ParameterCount expected(getter);
406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      __ InvokeFunction(getter, expected, actual, CALL_FUNCTION,
416474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                        NullCallWrapper());
426474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    } else {
436474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      // If we generate a global code snippet for deoptimization only, remember
446474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      // the place to continue after deoptimization.
456474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
4635814e51cffd39ade0aaeaaafb9b4612aa1d9efbfschneider@chromium.org    }
47c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    // Restore context register.
496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
506474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  }
516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  __ Ret();
526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org}
536474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
54c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
556474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateStoreViaSetter(
566474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    MacroAssembler* masm, Handle<HeapType> type, Register receiver,
576474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    Handle<JSFunction> setter) {
586474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // ----------- S t a t e -------------
596474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  //  -- ra    : return address
606474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // -----------------------------------
616474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  {
626474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    FrameScope scope(masm, StackFrame::INTERNAL);
636474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
646474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    // Save value register, so we can restore it later.
656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    __ push(value());
666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    if (!setter.is_null()) {
686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      // Call the JavaScript setter with receiver and value on the stack.
696474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      if (IC::TypeToMap(*type, masm->isolate())->IsJSGlobalObjectMap()) {
706474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        // Swap in the global receiver.
716474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        __ lw(receiver,
726474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org              FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset));
736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      }
746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      __ Push(receiver, value());
756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      ParameterCount actual(1);
766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      ParameterCount expected(setter);
776474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      __ InvokeFunction(setter, expected, actual, CALL_FUNCTION,
786474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                        NullCallWrapper());
796474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    } else {
806474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      // If we generate a global code snippet for deoptimization only, remember
816474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      // the place to continue after deoptimization.
826474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
836474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    }
846474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
856474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    // We have to return the passed value, not the return value of the setter.
866474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    __ pop(v0);
876474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
886474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    // Restore context register.
896474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
906474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  }
916474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  __ Ret();
92c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org}
93c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
94c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
95eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgvoid PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
96eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    MacroAssembler* masm, Label* miss_label, Register receiver,
97eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Handle<Name> name, Register scratch0, Register scratch1) {
98e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(name->IsUniqueName());
99e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!receiver.is(scratch0));
100394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Counters* counters = masm->isolate()->counters();
101394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
102394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
103394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
104394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Label done;
105394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
106394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  const int kInterceptorOrAccessCheckNeededMask =
1076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded);
108394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
109394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Bail out if the receiver has a named interceptor or requires access checks.
110394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Register map = scratch1;
111394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
112394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset));
113394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask));
114394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(miss_label, ne, scratch0, Operand(zero_reg));
115394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
116394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Check that receiver is a JSObject.
117394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
118394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
119394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
120394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Load properties array.
121394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Register properties = scratch0;
122394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
123394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Check that the properties array is a dictionary.
124394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(map, FieldMemOperand(properties, HeapObject::kMapOffset));
125394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Register tmp = properties;
126394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ LoadRoot(tmp, Heap::kHashTableMapRootIndex);
127394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ Branch(miss_label, ne, map, Operand(tmp));
128394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
129394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Restore the temporarily used register.
130394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ lw(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset));
131394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
132394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
1336474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  NameDictionaryLookupStub::GenerateNegativeLookup(
1346474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      masm, miss_label, &done, receiver, properties, name, scratch1);
135394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ bind(&done);
136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
137394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
138394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
139394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
140eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype(
141eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    MacroAssembler* masm, int index, Register prototype, Label* miss) {
142c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Isolate* isolate = masm->isolate();
143c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Get the global function with the given index.
144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Handle<JSFunction> function(
14546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      JSFunction::cast(isolate->native_context()->get(index)));
14657a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
14757a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  // Check we're still in the same context.
14857a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  Register scratch = prototype;
14957a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  const int offset = Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX);
15057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  __ lw(scratch, MemOperand(cp, offset));
15157a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  __ lw(scratch, FieldMemOperand(scratch, GlobalObject::kNativeContextOffset));
15257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  __ lw(scratch, MemOperand(scratch, Context::SlotOffset(index)));
15357a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  __ li(at, function);
15457a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  __ Branch(miss, ne, at, Operand(scratch));
15557a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
156c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Load its initial map. The global functions all have initial maps.
157c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ li(prototype, Handle<Map>(function->initial_map()));
158c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Load the prototype from the initial map.
159c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
1607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
1617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
163eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
164eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    MacroAssembler* masm, Register receiver, Register scratch1,
165eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Register scratch2, Label* miss_label) {
166c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
1678a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  __ Ret(USE_DELAY_SLOT);
168c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ mov(v0, scratch1);
1695c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1705c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1715c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1726474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org// Generate code to check that a global property cell is empty. Create
1736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org// the property cell at compilation time if no cell exists for the
1746474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org// property.
175eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgvoid PropertyHandlerCompiler::GenerateCheckPropertyCell(
176eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name,
177eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Register scratch, Label* miss) {
178057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  Handle<Cell> cell = JSGlobalObject::EnsurePropertyCell(global, name);
179e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(cell->value()->IsTheHole());
180e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ li(scratch, Operand(cell));
181f95d4b920abb640ab0986d138ad559a7d3b91d04danno@chromium.org  __ lw(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
182e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
183e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ Branch(miss, ne, scratch, Operand(at));
184e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
185e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
186e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
1876474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
1886474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                     Register holder, Register name,
189e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                     Handle<JSObject> holder_obj) {
190e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
191e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex == 1);
192e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 2);
193e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 3);
194e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 4);
195e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  __ push(name);
196e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Handle<InterceptorInfo> interceptor(holder_obj->GetNamedInterceptor());
197e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!masm->isolate()->heap()->InNewSpace(*interceptor));
198e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Register scratch = name;
199e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  __ li(scratch, Operand(interceptor));
200e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  __ Push(scratch, receiver, holder);
201e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
202e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
203e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
204e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgstatic void CompileCallLoadPropertyWithInterceptor(
2056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    MacroAssembler* masm, Register receiver, Register holder, Register name,
2066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    Handle<JSObject> holder_obj, IC::UtilityId id) {
207e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  PushInterceptorArguments(masm, receiver, holder, name, holder_obj);
208e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  __ CallExternalReference(ExternalReference(IC_Utility(id), masm->isolate()),
209e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                           NamedLoadHandlerCompiler::kInterceptorArgsLength);
210e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
211e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
212e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
213e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org// Generate call to api function.
214e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid PropertyHandlerCompiler::GenerateFastApiCall(
215e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    MacroAssembler* masm, const CallOptimization& optimization,
216e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    Handle<Map> receiver_map, Register receiver, Register scratch_in,
217e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    bool is_store, int argc, Register* values) {
218e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!receiver.is(scratch_in));
219e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // Preparing to push, adjust sp.
220e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  __ Subu(sp, sp, Operand((argc + 1) * kPointerSize));
221e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  __ sw(receiver, MemOperand(sp, argc * kPointerSize));  // Push receiver.
222e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // Write the arguments to stack frame.
223e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  for (int i = 0; i < argc; i++) {
2246474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    Register arg = values[argc - 1 - i];
225e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!receiver.is(arg));
226e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!scratch_in.is(arg));
2276474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    __ sw(arg, MemOperand(sp, (argc - 1 - i) * kPointerSize));  // Push arg.
228e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  }
229e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(optimization.is_simple_api_call());
230e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
231e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // Abi for CallApiFunctionStub.
232e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Register callee = a0;
233e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Register call_data = t0;
234e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Register holder = a2;
235e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Register api_function_address = a1;
236e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
237e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // Put holder in place.
238e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  CallOptimization::HolderLookup holder_lookup;
2396474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  Handle<JSObject> api_holder =
2406474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup);
241e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  switch (holder_lookup) {
242e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    case CallOptimization::kHolderIsReceiver:
243e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      __ Move(holder, receiver);
244e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      break;
245e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    case CallOptimization::kHolderFound:
246e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      __ li(holder, api_holder);
2476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      break;
248e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    case CallOptimization::kHolderNotFound:
249e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      UNREACHABLE();
250e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      break;
251e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  }
252e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
253e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Isolate* isolate = masm->isolate();
254e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Handle<JSFunction> function = optimization.constant_function();
255e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
256e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Handle<Object> call_data_obj(api_call_info->data(), isolate);
257e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
258e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // Put callee in place.
259e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  __ li(callee, function);
260e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
261e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  bool call_data_undefined = false;
262e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // Put call_data in place.
263e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (isolate->heap()->InNewSpace(*call_data_obj)) {
264e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    __ li(call_data, api_call_info);
265e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    __ lw(call_data, FieldMemOperand(call_data, CallHandlerInfo::kDataOffset));
266e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  } else if (call_data_obj->IsUndefined()) {
267e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    call_data_undefined = true;
268e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex);
269e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  } else {
270e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    __ li(call_data, call_data_obj);
271e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  }
272e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // Put api_function_address in place.
273e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  Address function_address = v8::ToCData<Address>(api_call_info->callback());
274e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  ApiFunction fun(function_address);
275e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
276e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  ExternalReference ref = ExternalReference(&fun, type, masm->isolate());
277e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  __ li(api_function_address, Operand(ref));
278e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
279e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  // Jump to stub.
280e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  CallApiFunctionStub stub(isolate, is_store, call_data_undefined, argc);
281e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  __ TailCallStub(&stub);
282e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
283e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
284e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
2856474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) {
2866474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // Push receiver, key and value for runtime call.
2879aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
2889aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org          StoreDescriptor::ValueRegister());
2896474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2906474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // The slow case calls into the runtime to complete the store without causing
2916474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // an IC miss that would otherwise cause a transition to the generic stub.
2926474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  ExternalReference ref =
2936474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      ExternalReference(IC_Utility(IC::kStoreIC_Slow), masm->isolate());
2946474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  __ TailCallExternalReference(ref, 3, 1);
2956474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org}
2966474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2976474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
2986474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgvoid ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) {
2996474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // Push receiver, key and value for runtime call.
3009aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
3019aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org          StoreDescriptor::ValueRegister());
3026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
3036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // The slow case calls into the runtime to complete the store without causing
3046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  // an IC miss that would otherwise cause a transition to the generic stub.
3056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  ExternalReference ref =
3066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      ExternalReference(IC_Utility(IC::kKeyedStoreIC_Slow), masm->isolate());
3076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  __ TailCallExternalReference(ref, 3, 1);
308e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org}
309e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
310e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
311e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#undef __
312e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org#define __ ACCESS_MASM(masm())
313e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
314e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org
315e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateRestoreName(Label* label,
316e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org                                                    Handle<Name> name) {
317e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (!label->is_unused()) {
318e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    __ bind(label);
319e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    __ li(this->name(), Operand(name));
320bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  }
321bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
322bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
323bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
324e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Generate StoreTransition code, value is passed in a0 register.
3255c838251403b0be9a882540f1922577abba4c872ager@chromium.org// After executing generated code, the receiver_reg and name_reg
3265c838251403b0be9a882540f1922577abba4c872ager@chromium.org// may be clobbered.
327eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateStoreTransition(
328e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    Handle<Map> transition, Handle<Name> name, Register receiver_reg,
329e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    Register storage_reg, Register value_reg, Register scratch1,
330e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    Register scratch2, Register scratch3, Label* miss_label, Label* slow) {
331c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // a0 : value.
332c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  Label exit;
3337028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
334f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  int descriptor = transition->LastAdded();
335f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  DescriptorArray* descriptors = transition->instance_descriptors();
336f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  PropertyDetails details = descriptors->GetDetails(descriptor);
337f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  Representation representation = details.representation();
338e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!representation.IsNone());
339f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
340fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (details.type() == CONSTANT) {
341e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    Handle<Object> constant(descriptors->GetValue(descriptor), isolate());
342057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org    __ li(scratch1, constant);
343bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    __ Branch(miss_label, ne, value_reg, Operand(scratch1));
344bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  } else if (representation.IsSmi()) {
345bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    __ JumpIfNotSmi(value_reg, miss_label);
346bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  } else if (representation.IsHeapObject()) {
3478496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    __ JumpIfSmi(value_reg, miss_label);
348731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    HeapType* field_type = descriptors->GetFieldType(descriptor);
3498496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    HeapType::Iterator<Map> it = field_type->Classes();
3508496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    Handle<Map> current;
3518496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    if (!it.Done()) {
3528496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      __ lw(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
3538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      Label do_store;
3548496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      while (true) {
3558496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        // Do the CompareMap() directly within the Branch() functions.
3568496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        current = it.Current();
3578496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        it.Advance();
3588496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        if (it.Done()) {
3598496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          __ Branch(miss_label, ne, scratch1, Operand(current));
3608496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org          break;
3618496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        }
3628496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org        __ Branch(&do_store, eq, scratch1, Operand(current));
3638496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      }
3648496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org      __ bind(&do_store);
365731474e847a8ccd6e27f74842506c9c807dae658jarin@chromium.org    }
366bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  } else if (representation.IsDouble()) {
36757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    Label do_store, heap_number;
36858a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    __ LoadRoot(scratch3, Heap::kMutableHeapNumberMapRootIndex);
36958a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    __ AllocateHeapNumber(storage_reg, scratch1, scratch2, scratch3, slow,
37058a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org                          TAG_RESULT, MUTABLE);
37157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
37257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ JumpIfNotSmi(value_reg, &heap_number);
37357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ SmiUntag(scratch1, value_reg);
37457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ mtc1(scratch1, f6);
37557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ cvt_d_w(f4, f6);
37657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ jmp(&do_store);
37757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
37857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ bind(&heap_number);
3796474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    __ CheckMap(value_reg, scratch1, Heap::kHeapNumberMapRootIndex, miss_label,
3806474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                DONT_DO_SMI_CHECK);
38157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ ldc1(f4, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
38257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
38357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ bind(&do_store);
38457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    __ sdc1(f4, FieldMemOperand(storage_reg, HeapNumber::kValueOffset));
38557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org  }
38657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org
3870ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  // Stub never generated for objects that require access checks.
388e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!transition->is_access_check_needed());
389c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
390c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Perform map transition for the receiver if necessary.
391b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  if (details.type() == FIELD &&
3920ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com      Map::cast(transition->GetBackPointer())->unused_property_fields() == 0) {
393c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    // The properties must be extended before we can store the value.
394c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    // We jump to a runtime call that extends the properties array.
395c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    __ push(receiver_reg);
3966e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com    __ li(a2, Operand(transition));
397c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    __ Push(a2, a0);
398c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    __ TailCallExternalReference(
3996474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
4006474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                          isolate()),
4016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        3, 1);
402c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    return;
403c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
404c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
405e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Update the map of the object.
406e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ li(scratch1, Operand(transition));
407e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ sw(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset));
408e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
409bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  // Update the write barrier for the map field.
4106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  __ RecordWriteField(receiver_reg, HeapObject::kMapOffset, scratch1, scratch2,
4116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                      kRAHasNotBeenSaved, kDontSaveFPRegs, OMIT_REMEMBERED_SET,
412e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                      OMIT_SMI_CHECK);
413e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
414fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  if (details.type() == CONSTANT) {
415e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(value_reg.is(a0));
416b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ Ret(USE_DELAY_SLOT);
417b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    __ mov(v0, a0);
418b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org    return;
419b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  }
420b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
421e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  int index = transition->instance_descriptors()->GetFieldIndex(
422e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      transition->LastAdded());
423e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
424e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Adjust for the number of properties stored in the object. Even in the
425e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // face of a transition we can use the old map here because the size of the
426e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // object and the number of in-object properties is not going to change.
4270ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  index -= transition->inobject_properties();
428e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
429e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // TODO(verwaest): Share this code as a code stub.
4306474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  SmiCheck smi_check =
4316474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      representation.IsTagged() ? INLINE_SMI_CHECK : OMIT_SMI_CHECK;
432e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  if (index < 0) {
433e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Set the property straight into the object.
4340ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com    int offset = transition->instance_size() + (index * kPointerSize);
435bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    if (representation.IsDouble()) {
43657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      __ sw(storage_reg, FieldMemOperand(receiver_reg, offset));
43757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    } else {
43857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      __ sw(value_reg, FieldMemOperand(receiver_reg, offset));
43957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    }
440e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
441bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    if (!representation.IsSmi()) {
442f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      // Update the write barrier for the array address.
443bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      if (!representation.IsDouble()) {
444bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        __ mov(storage_reg, value_reg);
44557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      }
4466474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      __ RecordWriteField(receiver_reg, offset, storage_reg, scratch1,
4476474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                          kRAHasNotBeenSaved, kDontSaveFPRegs,
4486474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                          EMIT_REMEMBERED_SET, smi_check);
449f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    }
450f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  } else {
451e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Write to the properties array.
452e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    int offset = index * kPointerSize + FixedArray::kHeaderSize;
453e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org    // Get the properties array
4546474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    __ lw(scratch1, FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
455bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    if (representation.IsDouble()) {
45657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      __ sw(storage_reg, FieldMemOperand(scratch1, offset));
45757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    } else {
45857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      __ sw(value_reg, FieldMemOperand(scratch1, offset));
45957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org    }
460e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
461bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org    if (!representation.IsSmi()) {
462f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      // Update the write barrier for the array address.
463bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org      if (!representation.IsDouble()) {
464bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org        __ mov(storage_reg, value_reg);
46557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org      }
4666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      __ RecordWriteField(scratch1, offset, storage_reg, receiver_reg,
4676474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                          kRAHasNotBeenSaved, kDontSaveFPRegs,
4686474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                          EMIT_REMEMBERED_SET, smi_check);
469f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    }
470e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  }
471e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
472e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Return the value (register v0).
473e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(value_reg.is(a0));
474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ bind(&exit);
4758a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  __ Ret(USE_DELAY_SLOT);
476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  __ mov(v0, a0);
477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org}
478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
479e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
480a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid NamedStoreHandlerCompiler::GenerateStoreField(LookupIterator* lookup,
4819d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                                                   Register value_reg,
4829d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                                                   Label* miss_label) {
4839d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  DCHECK(lookup->representation().IsHeapObject());
4849d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  __ JumpIfSmi(value_reg, miss_label);
4859d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  HeapType::Iterator<Map> it = lookup->GetFieldType()->Classes();
4869d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  __ lw(scratch1(), FieldMemOperand(value_reg, HeapObject::kMapOffset));
4879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Label do_store;
4889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  Handle<Map> current;
4899d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  while (true) {
4909d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    // Do the CompareMap() directly within the Branch() functions.
4919d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    current = it.Current();
4929d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    it.Advance();
4939d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    if (it.Done()) {
4949d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      __ Branch(miss_label, ne, scratch1(), Operand(current));
4959d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org      break;
496f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    }
4979d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org    __ Branch(&do_store, eq, scratch1(), Operand(current));
498c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
4999d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  __ bind(&do_store);
500c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
5019d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
5029d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org                      lookup->representation());
5039d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org  GenerateTailCall(masm(), stub.GetCode());
5045c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
5055c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5065c838251403b0be9a882540f1922577abba4c872ager@chromium.org
507eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgRegister PropertyHandlerCompiler::CheckPrototypes(
5080ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com    Register object_reg, Register holder_reg, Register scratch1,
5090ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com    Register scratch2, Handle<Name> name, Label* miss,
5100ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com    PrototypeCheckType check) {
5110ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  Handle<Map> receiver_map(IC::TypeToMap(*type(), isolate()));
512ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org
513394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Make sure there's no overlap between holder and object registers.
514e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
5156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) &&
5166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org         !scratch2.is(scratch1));
517394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
518394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Keep track of the current object in register reg.
519394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Register reg = object_reg;
520394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  int depth = 0;
521394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
522f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<JSObject> current = Handle<JSObject>::null();
5230ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  if (type()->IsConstant()) {
5240ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com    current = Handle<JSObject>::cast(type()->AsConstant()->Value());
525fa04143c1ab67009bfa167c48e1cf21fdf009796palfia@homejinni.com  }
526f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<JSObject> prototype = Handle<JSObject>::null();
527f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  Handle<Map> current_map = receiver_map;
5280ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  Handle<Map> holder_map(holder()->map());
529f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // Traverse the prototype chain and check the maps in the prototype chain for
530f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  // fast and global objects or do negative lookup for normal objects.
531f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  while (!current_map.is_identical_to(holder_map)) {
532394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    ++depth;
533394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
534394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // Only global objects and objects that do not require access
535394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // checks are allowed in stubs.
536e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(current_map->IsJSGlobalProxyMap() ||
537f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org           !current_map->is_access_check_needed());
538394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
539f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    prototype = handle(JSObject::cast(current_map->prototype()));
540f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    if (current_map->is_dictionary_map() &&
5413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        !current_map->IsJSGlobalObjectMap()) {
5423e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      DCHECK(!current_map->IsJSGlobalProxyMap());  // Proxy maps are fast.
5439faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      if (!name->IsUniqueName()) {
544e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(name->IsString());
5459faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org        name = factory()->InternalizeString(Handle<String>::cast(name));
546394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
547e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(current.is_null() ||
548f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org             current->property_dictionary()->FindEntry(name) ==
5496474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                 NameDictionary::kNotFound);
550394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
5516474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org      GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1,
5526474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                       scratch2);
553394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
554394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      __ lw(scratch1, FieldMemOperand(reg, HeapObject::kMapOffset));
555394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      reg = holder_reg;  // From now on the object will be in holder_reg.
556394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      __ lw(reg, FieldMemOperand(scratch1, Map::kPrototypeOffset));
557394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else {
5589faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      Register map_reg = scratch1;
559f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      if (depth != 1 || check == CHECK_ALL_MAPS) {
5609faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org        // CheckMap implicitly loads the map of |reg| into |map_reg|.
561a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org        __ CheckMap(reg, map_reg, current_map, miss, DONT_DO_SMI_CHECK);
5629faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      } else {
5639faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org        __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
5649faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      }
565f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
566394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // Check access rights to the global object.  This has to happen after
567394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // the map check so that we know that the object is actually a global
568394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      // object.
5693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      // This allows us to install generated handlers for accesses to the
5703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      // global proxy (as opposed to using slow ICs). See corresponding code
5713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org      // in LookupForRead().
572f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      if (current_map->IsJSGlobalProxyMap()) {
573394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        __ CheckAccessGlobalProxy(reg, scratch2, miss);
574f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org      } else if (current_map->IsJSGlobalObjectMap()) {
5756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org        GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current),
5766474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org                                  name, scratch2, miss);
577394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
578f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
579394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      reg = holder_reg;  // From now on the object will be in holder_reg.
580394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
581474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      // Two possible reasons for loading the prototype from the map:
582474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      // (1) Can't store references to new space in code.
583474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      // (2) Handler is shared for all receivers with the same prototype
584474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      //     map (but not necessarily the same prototype instance).
585474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      bool load_prototype_from_map =
586474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org          heap()->InNewSpace(*prototype) || depth == 1;
587474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org      if (load_prototype_from_map) {
5889faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org        __ lw(reg, FieldMemOperand(map_reg, Map::kPrototypeOffset));
589394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      } else {
590394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        __ li(reg, Operand(prototype));
591394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
592394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
593394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
594394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    // Go to the next object in the prototype chain.
595394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    current = prototype;
596f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    current_map = handle(current->map());
597394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
598394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
599394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Log the check depth.
60032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  LOG(isolate(), IntEvent("check-maps-depth", depth + 1));
601394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
602f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (depth != 0 || check == CHECK_ALL_MAPS) {
6039faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org    // Check the holder map.
604f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    __ CheckMap(reg, scratch1, current_map, miss, DONT_DO_SMI_CHECK);
6059faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  }
606394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
607394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Perform security check for access to the global object.
608e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(current_map->IsJSGlobalProxyMap() ||
609f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org         !current_map->is_access_check_needed());
610f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  if (current_map->IsJSGlobalProxyMap()) {
611394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    __ CheckAccessGlobalProxy(reg, scratch1, miss);
612394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
613394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
614394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Return the register containing the holder.
615394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  return reg;
616394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com}
617394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
618394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
619eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgvoid NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
6209faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  if (!miss->is_unused()) {
621b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Label success;
622b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    __ Branch(&success);
6239faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org    __ bind(miss);
6242bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org    TailCallBuiltin(masm(), MissBuiltin(kind()));
625b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    __ bind(&success);
6269faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  }
6275c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
6285c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6295c838251403b0be9a882540f1922577abba4c872ager@chromium.org
630eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgvoid NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
631bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  if (!miss->is_unused()) {
632b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    Label success;
633b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    __ Branch(&success);
634e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    GenerateRestoreName(miss, name);
635bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org    TailCallBuiltin(masm(), MissBuiltin(kind()));
636b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org    __ bind(&success);
637bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  }
638bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org}
639bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
640bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org
641eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
6424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Return the constant value.
643057bd50c2c2d15923523777a296cddee5c8ba63bverwaest@chromium.org  __ li(v0, value);
6444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ Ret();
6454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org}
6464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
6474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org
648eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadCallback(
649eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org    Register reg, Handle<ExecutableAccessorInfo> callback) {
650c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Build AccessorInfo::args_ list on the stack and push property name below
651c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // the exit frame to make GC aware of them and store pointers to them.
652fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  STATIC_ASSERT(PropertyCallbackArguments::kHolderIndex == 0);
653fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  STATIC_ASSERT(PropertyCallbackArguments::kIsolateIndex == 1);
654fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueDefaultValueIndex == 2);
655fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  STATIC_ASSERT(PropertyCallbackArguments::kReturnValueOffset == 3);
656fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  STATIC_ASSERT(PropertyCallbackArguments::kDataIndex == 4);
657fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  STATIC_ASSERT(PropertyCallbackArguments::kThisIndex == 5);
658fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
659e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!scratch2().is(reg));
660e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!scratch3().is(reg));
661e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!scratch4().is(reg));
6624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ push(receiver());
663c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  if (heap()->InNewSpace(callback->data())) {
6644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org    __ li(scratch3(), callback);
6656474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org    __ lw(scratch3(),
6666474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org          FieldMemOperand(scratch3(), ExecutableAccessorInfo::kDataOffset));
667c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  } else {
66832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    __ li(scratch3(), Handle<Object>(callback->data(), isolate()));
669c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
67079d0bf7c99ebe30751b199f72fa06fe34a5ded48palfia@homejinni.com  __ Subu(sp, sp, 6 * kPointerSize);
6714a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ sw(scratch3(), MemOperand(sp, 5 * kPointerSize));
672c118402c43ae44cf9255d36608a44886c98537c5jkummerow@chromium.org  __ LoadRoot(scratch3(), Heap::kUndefinedValueRootIndex);
6734a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ sw(scratch3(), MemOperand(sp, 4 * kPointerSize));
67479d0bf7c99ebe30751b199f72fa06fe34a5ded48palfia@homejinni.com  __ sw(scratch3(), MemOperand(sp, 3 * kPointerSize));
6756474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  __ li(scratch4(), Operand(ExternalReference::isolate_address(isolate())));
6764a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ sw(scratch4(), MemOperand(sp, 2 * kPointerSize));
6774a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  __ sw(reg, MemOperand(sp, 1 * kPointerSize));
6784a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ sw(name(), MemOperand(sp, 0 * kPointerSize));
679fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  __ Addu(scratch2(), sp, 1 * kPointerSize);
680ed49e965b5cafa35395084dbfb79f4e07930f10ferik.corry@gmail.com
6814a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  __ mov(a2, scratch2());  // Saved in case scratch2 == a1.
68257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  // Abi for CallApiGetter.
6836313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  Register getter_address_reg = ApiGetterDescriptor::function_address();
684c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
685662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  Address getter_address = v8::ToCData<Address>(callback->getter());
686c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ApiFunction fun(getter_address);
687662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
688fe578677d80b14b35f6dca0c193719331b81a81edanno@chromium.org  ExternalReference ref = ExternalReference(&fun, type, isolate());
689e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org  __ li(getter_address_reg, Operand(ref));
69057a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org
691f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org  CallApiGetterStub stub(isolate());
69257a54ace4b6b45d5d6a7ff38d88ee9990d47f5e2machenbach@chromium.org  __ TailCallStub(&stub);
6935c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
6945c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6955c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6965e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup(
6975e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    LookupIterator* it, Register holder_reg) {
698e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(holder()->HasNamedInterceptor());
699e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
700c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
7015e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // Compile the interceptor call, followed by inline code to load the
7025e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // property from further up the prototype chain if the call fails.
7035e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // Check that the maps haven't changed.
7045e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1()));
7055e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7065e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // Preserve the receiver register explicitly whenever it is different from the
7075e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // holder and it is needed should the interceptor return without any result.
7085e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD
7095e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // case might cause a miss during the prototype check.
7105e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  bool must_perform_prototype_check =
7115e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      !holder().is_identical_to(it->GetHolder<JSObject>());
7125e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  bool must_preserve_receiver_reg =
7135e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      !receiver().is(holder_reg) &&
7141af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org      (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check);
7155e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7165e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // Save necessary data before invoking an interceptor.
7175e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // Requires a frame to make GC aware of pushed pointers.
7185e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  {
7195e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    FrameScope frame_scope(masm(), StackFrame::INTERNAL);
7205e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    if (must_preserve_receiver_reg) {
7215e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      __ Push(receiver(), holder_reg, this->name());
7225e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    } else {
7235e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      __ Push(holder_reg, this->name());
724c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    }
7255e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    // Invoke an interceptor.  Note: map checks from receiver to
7265e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    // interceptor's holder has been compiled before (see a caller
7275e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    // of this method).
7285e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    CompileCallLoadPropertyWithInterceptor(
7295e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        masm(), receiver(), holder_reg, this->name(), holder(),
7305e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org        IC::kLoadPropertyWithInterceptorOnly);
7315e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7325e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    // Check if interceptor provided a value for property.  If it's
7335e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    // the case, return immediately.
7345e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    Label interceptor_failed;
7355e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
7365e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    __ Branch(&interceptor_failed, eq, v0, Operand(scratch1()));
7375e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    frame_scope.GenerateLeaveFrame();
7385e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    __ Ret();
7395e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7405e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    __ bind(&interceptor_failed);
7415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    if (must_preserve_receiver_reg) {
7425e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      __ Pop(receiver(), holder_reg, this->name());
7435e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    } else {
7445e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      __ Pop(holder_reg, this->name());
745c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
7465e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    // Leave the internal frame.
747c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
7485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  GenerateLoadPostInterceptor(it, holder_reg);
7505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org}
7515e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7525e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7535e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.orgvoid NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
7545e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  // Call the runtime system to load the interceptor.
7555e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  DCHECK(holder()->HasNamedInterceptor());
7565e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
7575e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
7585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                           holder());
7595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org
7605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  ExternalReference ref = ExternalReference(
7615e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
7625e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  __ TailCallExternalReference(
7635e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
7645c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
7655c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7665c838251403b0be9a882540f1922577abba4c872ager@chromium.org
767eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
7680ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com    Handle<JSObject> object, Handle<Name> name,
769c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org    Handle<ExecutableAccessorInfo> callback) {
7700ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  Register holder_reg = Frontend(receiver(), name);
771c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
7726f1040e5c87d24f21c8afc2e08dc26cd1bfc5d1fmachenbach@chromium.org  __ Push(receiver(), holder_reg);  // Receiver.
7736474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  __ li(at, Operand(callback));     // Callback info.
774bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  __ push(at);
775bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  __ li(at, Operand(name));
776bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org  __ Push(at, value());
777c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
778c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Do tail-call to the runtime system.
779c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  ExternalReference store_callback_property =
78032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org      ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
78143c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org  __ TailCallExternalReference(store_callback_property, 5, 1);
782c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
783c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Return the generated code.
7849af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
7857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
7867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
7877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
788eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> NamedStoreHandlerCompiler::CompileStoreInterceptor(
7890ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com    Handle<Name> name) {
7904c54a2aa3c7806f38af0c7dfde22395232ebdff7jkummerow@chromium.org  __ Push(receiver(), this->name(), value());
791c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
792c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Do tail-call to the runtime system.
793dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org  ExternalReference store_ic_property = ExternalReference(
794dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org      IC_Utility(IC::kStorePropertyWithInterceptor), isolate());
795cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org  __ TailCallExternalReference(store_ic_property, 3, 1);
796c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
797c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Return the generated code.
7989af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  return GetCode(kind(), Code::FAST, name);
7997516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
8007516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
8017516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
802fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgRegister NamedStoreHandlerCompiler::value() {
8039aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  return StoreDescriptor::ValueRegister();
804fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org}
805eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org
806eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org
807eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.orgHandle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
808e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
809b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org  Label miss;
810c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
8110ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  FrontendHeader(receiver(), name, &miss);
812c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
813c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Get the value from the cell.
8149aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register result = StoreDescriptor::ValueRegister();
8150ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  __ li(result, Operand(cell));
8160ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  __ lw(result, FieldMemOperand(result, Cell::kValueOffset));
817c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
818c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Check for deleted property if property can actually be deleted.
819e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  if (is_configurable) {
820c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org    __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
8210ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com    __ Branch(&miss, eq, result, Operand(at));
822c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  }
823c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
82432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  Counters* counters = isolate()->counters();
825c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3);
8268a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org  __ Ret(USE_DELAY_SLOT);
8270ff70cc62b77c5de20e3fb2d1443e521c519d850akos.palfi@imgtec.com  __ mov(v0, result);
828c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
829eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  FrontendFooter(name, &miss);
830a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org
831c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  // Return the generated code.
832e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  return GetCode(kind(), Code::NORMAL, name);
8335c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
8347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
8357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
83640cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org#undef __
8376db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org}
8386474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org}  // namespace v8::internal
8395c838251403b0be9a882540f1922577abba4c872ager@chromium.org
8409dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // V8_TARGET_ARCH_MIPS
841