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