1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_MIPS64 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/handler-compiler.h" 8342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch 91b268ca467c924004286c97bac133db489cf43d0Ben Murdoch#include "src/api-arguments.h" 10342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/field-type.h" 11342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch#include "src/ic/call-optimization.h" 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/ic.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h" 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ ACCESS_MASM(masm) 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadViaGetter( 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, int expected_arguments, Register scratch) { 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------- S t a t e ------------- 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- a0 : receiver 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- a2 : name 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- ra : return address 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------------------------------- 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameScope scope(masm, StackFrame::INTERNAL); 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // Save context register 331b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ push(cp); 341b268ca467c924004286c97bac133db489cf43d0Ben Murdoch 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (accessor_index >= 0) { 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!holder.is(scratch)); 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!receiver.is(scratch)); 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call the JavaScript getter with the receiver on the stack. 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->IsJSGlobalObjectMap()) { 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Swap in the global receiver. 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(scratch, 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver = scratch; 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ push(receiver); 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadAccessor(a1, holder, accessor_index, ACCESSOR_GETTER); 471b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ li(a0, Operand(V8_INT64_C(0))); 481b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Call(masm->isolate()->builtins()->CallFunction( 491b268ca467c924004286c97bac133db489cf43d0Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined), 501b268ca467c924004286c97bac133db489cf43d0Ben Murdoch RelocInfo::CODE_TARGET); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we generate a global code snippet for deoptimization only, remember 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the place to continue after deoptimization. 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore context register. 581b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ pop(cp); 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedStoreHandlerCompiler::GenerateStoreViaSetter( 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, int expected_arguments, Register scratch) { 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------- S t a t e ------------- 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- ra : return address 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------------------------------- 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameScope scope(masm, StackFrame::INTERNAL); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 731b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // Save context and value registers, so we can restore them later. 741b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Push(cp, value()); 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (accessor_index >= 0) { 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!holder.is(scratch)); 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!receiver.is(scratch)); 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!value().is(scratch)); 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call the JavaScript setter with receiver and value on the stack. 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->IsJSGlobalObjectMap()) { 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Swap in the global receiver. 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(scratch, 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver = scratch; 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(receiver, value()); 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadAccessor(a1, holder, accessor_index, ACCESSOR_SETTER); 891b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ li(a0, Operand(1)); 901b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Call(masm->isolate()->builtins()->CallFunction( 911b268ca467c924004286c97bac133db489cf43d0Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined), 921b268ca467c924004286c97bac133db489cf43d0Ben Murdoch RelocInfo::CODE_TARGET); 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we generate a global code snippet for deoptimization only, remember 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the place to continue after deoptimization. 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to return the passed value, not the return value of the setter. 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore context register. 1011b268ca467c924004286c97bac133db489cf43d0Ben Murdoch __ Pop(cp, v0); 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PropertyHandlerCompiler::PushVectorAndSlot(Register vector, 108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register slot) { 109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm = this->masm(); 110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Push(vector, slot); 111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) { 115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm = this->masm(); 116958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Pop(vector, slot); 117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PropertyHandlerCompiler::DiscardVectorAndSlot() { 121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm = this->masm(); 122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Remove vector and slot. 123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Daddu(sp, sp, Operand(2 * kPointerSize)); 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, Label* miss_label, Register receiver, 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name, Register scratch0, Register scratch1) { 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(name->IsUniqueName()); 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!receiver.is(scratch0)); 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Counters* counters = masm->isolate()->counters(); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kInterceptorOrAccessCheckNeededMask = 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bail out if the receiver has a named interceptor or requires access checks. 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map = scratch1; 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ And(scratch0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(miss_label, ne, scratch0, Operand(zero_reg)); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that receiver is a JSObject. 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Branch(miss_label, lt, scratch0, Operand(FIRST_JS_RECEIVER_TYPE)); 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load properties array. 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register properties = scratch0; 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the properties array is a dictionary. 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register tmp = properties; 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(miss_label, ne, map, Operand(tmp)); 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore the temporarily used register. 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ld(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionaryLookupStub::GenerateNegativeLookup( 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm, miss_label, &done, receiver, properties, name, scratch1); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&done); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateDirectLoadGlobalFunctionPrototype( 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm, int index, Register result, Label* miss) { 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadNativeContextSlot(index, result); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load its initial map. The global functions all have initial maps. 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ ld(result, 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FieldMemOperand(result, JSFunction::kPrototypeOrInitialMapOffset)); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the prototype from the initial map. 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ ld(result, FieldMemOperand(result, Map::kPrototypeOffset)); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, Register receiver, Register scratch1, 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2, Label* miss_label) { 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(USE_DELAY_SLOT); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(v0, scratch1); 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Generate code to check that a global property cell is empty. Create 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the property cell at compilation time if no cell exists for the 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// property. 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PropertyHandlerCompiler::GenerateCheckPropertyCell( 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, Label* miss) { 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<PropertyCell> cell = JSGlobalObject::EnsurePropertyCell(global, name); 19921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Isolate* isolate = masm->isolate(); 20021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(cell->value()->IsTheHole(isolate)); 20121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadWeakValue(scratch, weak_cell, miss); 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(miss, ne, scratch, Operand(at)); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void PushInterceptorArguments(MacroAssembler* masm, Register receiver, 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register holder, Register name, 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> holder_obj) { 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1); 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2); 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3); 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Push(name, receiver, holder); 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void CompileCallLoadPropertyWithInterceptor( 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, Register receiver, Register holder, Register name, 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> holder_obj, Runtime::FunctionId id) { 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(NamedLoadHandlerCompiler::kInterceptorArgsLength == 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Runtime::FunctionForId(id)->nargs); 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushInterceptorArguments(masm, receiver, holder, name, holder_obj); 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallRuntime(id); 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Generate call to api function. 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid PropertyHandlerCompiler::GenerateApiAccessorCall( 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, const CallOptimization& optimization, 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, Register receiver, Register scratch_in, 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_store, Register store_parameter, Register accessor_holder, 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index) { 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!accessor_holder.is(scratch_in)); 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!receiver.is(scratch_in)); 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(receiver); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Write the arguments to stack frame. 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_store) { 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!receiver.is(store_parameter)); 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!scratch_in.is(store_parameter)); 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(store_parameter); 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(optimization.is_simple_api_call()); 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2471b268ca467c924004286c97bac133db489cf43d0Ben Murdoch // Abi for CallApiCallbackStub. 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register callee = a0; 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register data = a4; 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register holder = a2; 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register api_function_address = a1; 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Put callee in place. 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadAccessor(callee, accessor_holder, accessor_index, 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_store ? ACCESSOR_SETTER : ACCESSOR_GETTER); 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put holder in place. 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization::HolderLookup holder_lookup; 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int holder_depth = 0; 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch &holder_depth); 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (holder_lookup) { 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderIsReceiver: 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Move(holder, receiver); 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderFound: 267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(holder, FieldMemOperand(receiver, HeapObject::kMapOffset)); 268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 1; i < holder_depth; i++) { 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(holder, FieldMemOperand(holder, HeapObject::kMapOffset)); 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderNotFound: 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = masm->isolate(); 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool call_data_undefined = false; 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Put call data in place. 28321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (api_call_info->data()->IsUndefined(isolate)) { 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_data_undefined = true; 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadRoot(data, Heap::kUndefinedValueRootIndex); 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 287342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (optimization.is_constant_call()) { 288342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch __ ld(data, 289342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset)); 290342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch __ ld(data, 291342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset)); 292342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch __ ld(data, FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset)); 293342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } else { 294342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch __ ld(data, 295342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch FieldMemOperand(callee, FunctionTemplateInfo::kCallCodeOffset)); 296342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch } 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(data, FieldMemOperand(data, CallHandlerInfo::kDataOffset)); 298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (api_call_info->fast_handler()->IsCode()) { 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Just tail call into the fast handler if present. 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Jump(handle(Code::cast(api_call_info->fast_handler())), 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::CODE_TARGET); 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put api_function_address in place. 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address function_address = v8::ToCData<Address>(api_call_info->callback()); 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ApiFunction fun(function_address); 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(api_function_address, Operand(ref)); 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump to stub. 3141b268ca467c924004286c97bac133db489cf43d0Ben Murdoch CallApiCallbackStub stub(isolate, is_store, call_data_undefined, 315342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch !optimization.is_constant_call()); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ TailCallStub(&stub); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstatic void StoreIC_PushArgs(MacroAssembler* masm) { 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(), 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StoreDescriptor::ValueRegister(), 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorStoreICDescriptor::SlotRegister(), 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch VectorStoreICDescriptor::VectorRegister()); 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid NamedStoreHandlerCompiler::GenerateSlow(MacroAssembler* masm) { 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StoreIC_PushArgs(masm); 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The slow case calls into the runtime to complete the store without causing 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // an IC miss that would otherwise cause a transition to the generic stub. 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TailCallRuntime(Runtime::kStoreIC_Slow); 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ElementHandlerCompiler::GenerateStoreSlow(MacroAssembler* masm) { 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StoreIC_PushArgs(masm); 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The slow case calls into the runtime to complete the store without causing 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // an IC miss that would otherwise cause a transition to the generic stub. 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __ 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ ACCESS_MASM(masm()) 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name) { 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!label->is_unused()) { 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(label); 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(this->name(), Operand(name)); 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedStoreHandlerCompiler::GenerateRestoreName(Handle<Name> name) { 360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ li(this->name(), Operand(name)); 361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid NamedStoreHandlerCompiler::RearrangeVectorAndSlot( 365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register current_map, Register destination_map) { 366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(false); // Not implemented. 367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedStoreHandlerCompiler::GenerateRestoreMap(Handle<Map> transition, 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register map_reg, 372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register scratch, 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label* miss) { 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<WeakCell> cell = Map::WeakCellForMap(transition); 375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!map_reg.is(scratch)); 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadWeakValue(map_reg, cell, miss); 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (transition->CanBeDeprecated()) { 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ lwu(scratch, FieldMemOperand(map_reg, Map::kBitField3Offset)); 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ And(at, scratch, Operand(Map::Deprecated::kMask)); 380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Branch(miss, ne, at, Operand(zero_reg)); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedStoreHandlerCompiler::GenerateConstantCheck(Register map_reg, 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int descriptor, 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register value_reg, 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register scratch, 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label* miss_label) { 390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!map_reg.is(scratch)); 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!map_reg.is(value_reg)); 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!value_reg.is(scratch)); 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadInstanceDescriptors(map_reg, scratch); 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ ld(scratch, 395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FieldMemOperand(scratch, DescriptorArray::GetValueOffset(descriptor))); 396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Branch(miss_label, ne, value_reg, Operand(scratch)); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 399342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdochvoid NamedStoreHandlerCompiler::GenerateFieldTypeChecks(FieldType* field_type, 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register value_reg, 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label* miss_label) { 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register map_reg = scratch1(); 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch = scratch2(); 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!value_reg.is(map_reg)); 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!value_reg.is(scratch)); 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ JumpIfSmi(value_reg, miss_label); 407342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch if (field_type->IsClass()) { 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(map_reg, FieldMemOperand(value_reg, HeapObject::kMapOffset)); 409342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch // Compare map directly within the Branch() functions. 410342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch __ GetWeakValue(scratch, Map::WeakCellForMap(field_type->AsClass())); 411342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch __ Branch(miss_label, ne, map_reg, Operand(scratch)); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister PropertyHandlerCompiler::CheckPrototypes( 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object_reg, Register holder_reg, Register scratch1, 418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register scratch2, Handle<Name> name, Label* miss, PrototypeCheckType check, 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnHolder return_what) { 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> receiver_map = map(); 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure there's no overlap between holder and object registers. 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !scratch2.is(scratch1)); 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Handle<Cell> validity_cell = 42821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); 42921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (!validity_cell.is_null()) { 43021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); 43121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ li(scratch1, Operand(validity_cell)); 43221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ ld(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); 43321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Branch(miss, ne, scratch1, 43421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Operand(Smi::FromInt(Map::kPrototypeChainValid))); 43521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 43721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // The prototype chain of primitives (and their JSValue wrappers) depends 43821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // on the native context, which can't be guarded by validity cells. 43921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // |object_reg| holds the native context specific prototype in this case; 44021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // we need to check its map. 44121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (check == CHECK_ALL_MAPS) { 44221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ ld(scratch1, FieldMemOperand(object_reg, HeapObject::kMapOffset)); 44321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); 44421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ GetWeakValue(scratch2, cell); 44521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch __ Branch(miss, ne, scratch1, Operand(scratch2)); 446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep track of the current object in register reg. 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg = object_reg; 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int depth = 0; 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> current = Handle<JSObject>::null(); 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (receiver_map->IsJSGlobalObjectMap()) { 454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current = isolate()->global_object(); 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check access rights to the global object. This has to happen after 458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the map check so that we know that the object is actually a global 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // object. 460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This allows us to install generated handlers for accesses to the 461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // global proxy (as opposed to using slow ICs). See corresponding code 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // in LookupForRead(). 463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (receiver_map->IsJSGlobalProxyMap()) { 464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CheckAccessGlobalProxy(reg, scratch2, miss); 465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> prototype = Handle<JSObject>::null(); 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> current_map = receiver_map; 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> holder_map(holder()->map()); 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Traverse the prototype chain and check the maps in the prototype chain for 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // fast and global objects or do negative lookup for normal objects. 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!current_map.is_identical_to(holder_map)) { 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++depth; 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Only global objects and objects that do not require access 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // checks are allowed in stubs. 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current_map->IsJSGlobalProxyMap() || 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !current_map->is_access_check_needed()); 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prototype = handle(JSObject::cast(current_map->prototype())); 48121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (current_map->IsJSGlobalObjectMap()) { 48221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 48321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch name, scratch2, miss); 48421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } else if (current_map->is_dictionary_map()) { 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!name->IsUniqueName()) { 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(name->IsString()); 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name = factory()->InternalizeString(Handle<String>::cast(name)); 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current.is_null() || 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->property_dictionary()->FindEntry(name) == 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionary::kNotFound); 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 49421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (depth > 1) { 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(jkummerow): Cache and re-use weak cell. 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss); 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch2); 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg = holder_reg; // From now on the object will be in holder_reg. 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Go to the next object in the prototype chain. 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = prototype; 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_map = handle(current->map()); 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!current_map->IsJSGlobalProxyMap()); 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Log the check depth. 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool return_holder = return_what == RETURN_HOLDER; 51421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (return_holder && depth != 0) { 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadWeakValue(reg, isolate()->factory()->NewWeakCell(current), miss); 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the register containing the holder. 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return return_holder ? reg : no_reg; 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!miss->is_unused()) { 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label success; 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&success); 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(miss); 528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(kind() == Code::LOAD_IC); 530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PopVectorAndSlot(); 531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TailCallBuiltin(masm(), MissBuiltin(kind())); 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&success); 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!miss->is_unused()) { 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label success; 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&success); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateRestoreName(miss, name); 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IC::ICUseVector(kind())) PopVectorAndSlot(); 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TailCallBuiltin(masm(), MissBuiltin(kind())); 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&success); 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the constant value. 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(v0, value); 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( 558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator* it, Register holder_reg) { 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder()->HasNamedInterceptor()); 56021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compile the interceptor call, followed by inline code to load the 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // property from further up the prototype chain if the call fails. 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the maps haven't changed. 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Preserve the receiver register explicitly whenever it is different from the 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // holder and it is needed should the interceptor return without any result. 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // case might cause a miss during the prototype check. 571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool must_perform_prototype_check = 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !holder().is_identical_to(it->GetHolder<JSObject>()); 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool must_preserve_receiver_reg = 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !receiver().is(holder_reg) && 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check); 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save necessary data before invoking an interceptor. 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Requires a frame to make GC aware of pushed pointers. 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameScope frame_scope(masm(), StackFrame::INTERNAL); 581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (must_preserve_receiver_reg) { 582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(receiver(), holder_reg, this->name()); 583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(holder_reg, this->name()); 585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPush(holder_reg); 587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Invoke an interceptor. Note: map checks from receiver to 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // interceptor's holder has been compiled before (see a caller 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of this method). 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileCallLoadPropertyWithInterceptor( 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm(), receiver(), holder_reg, this->name(), holder(), 592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Runtime::kLoadPropertyWithInterceptorOnly); 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if interceptor provided a value for property. If it's 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the case, return immediately. 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label interceptor_failed; 597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&interceptor_failed, eq, v0, Operand(scratch1())); 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_scope.GenerateLeaveFrame(); 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&interceptor_failed); 603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPop(holder_reg); 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (must_preserve_receiver_reg) { 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Pop(receiver(), holder_reg, this->name()); 606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Pop(holder_reg, this->name()); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Leave the internal frame. 610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadPostInterceptor(it, holder_reg); 613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call the runtime system to load the interceptor. 618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder()->HasNamedInterceptor()); 61921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); 620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), 621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder()); 622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TailCallRuntime(Runtime::kLoadPropertyWithInterceptor); 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 628342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback, 629342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch LanguageMode language_mode) { 630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register holder_reg = Frontend(name); 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(receiver(), holder_reg); // Receiver. 633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the callback cannot leak, then push the callback directly, 634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // otherwise wrap it in a weak cell. 63521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (callback->data()->IsUndefined(isolate()) || callback->data()->IsSmi()) { 636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(at, Operand(callback)); 637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback); 639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ li(at, Operand(cell)); 640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ push(at); 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ li(at, Operand(name)); 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(at, value()); 644342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch __ Push(Smi::FromInt(language_mode)); 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do tail-call to the runtime system. 647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TailCallRuntime(Runtime::kStoreCallbackProperty); 648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the generated code. 650537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch return GetCode(kind(), name); 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister NamedStoreHandlerCompiler::value() { 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return StoreDescriptor::ValueRegister(); 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label miss; 662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(); 664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING); 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the value from the cell. 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result = StoreDescriptor::ValueRegister(); 670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell); 671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadWeakValue(result, weak_cell, &miss); 672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ ld(result, FieldMemOperand(result, PropertyCell::kValueOffset)); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for deleted property if property can actually be deleted. 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_configurable) { 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Branch(&miss, eq, result, Operand(at)); 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Counters* counters = isolate()->counters(); 681342c50ce1624b485728b9a4fc41d8bbf37eb46cfBen Murdoch __ IncrementCounter(counters->ic_named_load_global_stub(), 1, a1, a3); 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DiscardVectorAndSlot(); 684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(USE_DELAY_SLOT); 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(v0, result); 687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrontendFooter(name, &miss); 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the generated code. 691537ba893e2530051ec7f296e769fdd37bb4ae4a0Ben Murdoch return GetCode(kind(), name); 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __ 696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_TARGET_ARCH_MIPS64 700