1958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Copyright 2014 the V8 project authors. All rights reserved. 2958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Use of this source code is governed by a BSD-style license that can be 3958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// found in the LICENSE file. 4958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 5958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#if V8_TARGET_ARCH_PPC 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 7f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch#include "src/ic/handler-compiler.h" 8109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch 93b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch#include "src/api-arguments.h" 10109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/field-type.h" 11109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/ic/call-optimization.h" 12958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/ic/ic.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h" 14958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 15958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace v8 { 16958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace internal { 17958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 18958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define __ ACCESS_MASM(masm) 19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedLoadHandlerCompiler::GenerateLoadViaGetter( 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, int expected_arguments, Register scratch) { 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // ----------- S t a t e ------------- 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // -- r3 : receiver 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // -- r5 : name 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // -- lr : return address 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // ----------------------------------- 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier { 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Save context register 333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ push(cp); 343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (accessor_index >= 0) { 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!holder.is(scratch)); 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!receiver.is(scratch)); 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Call the JavaScript getter with the receiver on the stack. 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->IsJSGlobalObjectMap()) { 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Swap in the global receiver. 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(scratch, 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver = scratch; 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ push(receiver); 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadAccessor(r4, holder, accessor_index, ACCESSOR_GETTER); 473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ li(r3, Operand::Zero()); 483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Call(masm->isolate()->builtins()->CallFunction( 493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined), 503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RelocInfo::CODE_TARGET); 51958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 52958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If we generate a global code snippet for deoptimization only, remember 53958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the place to continue after deoptimization. 54958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 55958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 56958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 57958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Restore context register. 583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ pop(cp); 59958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 60958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Ret(); 61958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 62958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 63958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 64958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedStoreHandlerCompiler::GenerateStoreViaSetter( 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, int expected_arguments, Register scratch) { 67958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // ----------- S t a t e ------------- 68958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // -- lr : return address 69958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // ----------------------------------- 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier { 71958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 72958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Save context register 74958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Save value register, so we can restore it later. 753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Push(cp, value()); 76958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (accessor_index >= 0) { 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!holder.is(scratch)); 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!receiver.is(scratch)); 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!value().is(scratch)); 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Call the JavaScript setter with receiver and value on the stack. 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->IsJSGlobalObjectMap()) { 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Swap in the global receiver. 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(scratch, 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver = scratch; 87958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 88958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Push(receiver, value()); 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadAccessor(r4, holder, accessor_index, ACCESSOR_SETTER); 903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ li(r3, Operand(1)); 913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Call(masm->isolate()->builtins()->CallFunction( 923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined), 933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RelocInfo::CODE_TARGET); 94958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 95958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If we generate a global code snippet for deoptimization only, remember 96958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the place to continue after deoptimization. 97958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // We have to return the passed value, not the return value of the setter. 101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Restore context register. 1023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Pop(cp, r3); 103958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 104958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Ret(); 105958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid PropertyHandlerCompiler::PushVectorAndSlot(Register vector, 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register slot) { 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler* masm = this->masm(); 111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch STATIC_ASSERT(LoadWithVectorDescriptor::kSlot < 112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LoadWithVectorDescriptor::kVector); 113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch STATIC_ASSERT(StoreWithVectorDescriptor::kSlot < 114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch StoreWithVectorDescriptor::kVector); 115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch STATIC_ASSERT(StoreTransitionDescriptor::kSlot < 116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch StoreTransitionDescriptor::kVector); 117f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ Push(slot, vector); 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) { 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler* masm = this->masm(); 123f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ Pop(slot, vector); 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid PropertyHandlerCompiler::DiscardVectorAndSlot() { 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler* masm = this->masm(); 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Remove vector and slot. 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ addi(sp, sp, Operand(2 * kPointerSize)); 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm, Label* miss_label, Register receiver, 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Name> name, Register scratch0, Register scratch1) { 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(name->IsUniqueName()); 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!receiver.is(scratch0)); 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Counters* counters = masm->isolate()->counters(); 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label done; 143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int kInterceptorOrAccessCheckNeededMask = 145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Bail out if the receiver has a named interceptor or requires access checks. 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register map = scratch1; 149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadP(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ lbz(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); 151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ andi(r0, scratch0, Operand(kInterceptorOrAccessCheckNeededMask)); 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bne(miss_label, cr0); 153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check that receiver is a JSObject. 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ lbz(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ cmpi(scratch0, Operand(FIRST_JS_RECEIVER_TYPE)); 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ blt(miss_label); 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Load properties array. 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register properties = scratch0; 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check that the properties array is a dictionary. 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadP(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register tmp = properties; 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadRoot(tmp, Heap::kHashTableMapRootIndex); 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ cmp(map, tmp); 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bne(miss_label); 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Restore the temporarily used register. 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadP(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NameDictionaryLookupStub::GenerateNegativeLookup( 174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm, miss_label, &done, receiver, properties, name, scratch1); 175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(&done); 176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Generate code to check that a global property cell is empty. Create 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// the property cell at compilation time if no cell exists for the 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// property. 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PropertyHandlerCompiler::GenerateCheckPropertyCell( 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register scratch, Label* miss) { 185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( 186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch global, name, PropertyCellType::kInvalidated); 18713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Isolate* isolate = masm->isolate(); 18813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(cell->value()->IsTheHole(isolate)); 18913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadWeakValue(scratch, weak_cell, miss); 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ cmp(scratch, ip); 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bne(miss); 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void CompileCallLoadPropertyWithInterceptor( 199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm, Register receiver, Register holder, Register name, 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> holder_obj, Runtime::FunctionId id) { 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(NamedLoadHandlerCompiler::kInterceptorArgsLength == 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Runtime::FunctionForId(id)->nargs); 20362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 20462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 20562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1); 20662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2); 20762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3); 20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Push(name, receiver, holder); 20962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallRuntime(id); 211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier// Generate call to api function. 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid PropertyHandlerCompiler::GenerateApiAccessorCall( 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm, const CallOptimization& optimization, 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Map> receiver_map, Register receiver, Register scratch_in, 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_store, Register store_parameter, Register accessor_holder, 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index) { 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!accessor_holder.is(scratch_in)); 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!receiver.is(scratch_in)); 222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ push(receiver); 223958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Write the arguments to stack frame. 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_store) { 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!receiver.is(store_parameter)); 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!scratch_in.is(store_parameter)); 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ push(store_parameter); 228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(optimization.is_simple_api_call()); 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Abi for CallApiCallbackStub. 232958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register callee = r3; 233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register data = r7; 234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register holder = r5; 235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register api_function_address = r4; 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Put callee in place. 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadAccessor(callee, accessor_holder, accessor_index, 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_store ? ACCESSOR_SETTER : ACCESSOR_GETTER); 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Put holder in place. 242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CallOptimization::HolderLookup holder_lookup; 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int holder_depth = 0; 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch &holder_depth); 246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier switch (holder_lookup) { 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CallOptimization::kHolderIsReceiver: 248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Move(holder, receiver); 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CallOptimization::kHolderFound: 251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(holder, FieldMemOperand(receiver, HeapObject::kMapOffset)); 252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); 253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 1; i < holder_depth; i++) { 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(holder, FieldMemOperand(holder, HeapObject::kMapOffset)); 255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); 256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier case CallOptimization::kHolderNotFound: 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UNREACHABLE(); 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Isolate* isolate = masm->isolate(); 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool call_data_undefined = false; 266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Put call data in place. 26713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (api_call_info->data()->IsUndefined(isolate)) { 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier call_data_undefined = true; 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadRoot(data, Heap::kUndefinedValueRootIndex); 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 271109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (optimization.is_constant_call()) { 272109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ LoadP(data, 273109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset)); 274109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ LoadP(data, 275109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset)); 276109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ LoadP(data, 277109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset)); 278109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 279109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ LoadP(data, 280109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldMemOperand(callee, FunctionTemplateInfo::kCallCodeOffset)); 281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(data, FieldMemOperand(data, CallHandlerInfo::kDataOffset)); 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (api_call_info->fast_handler()->IsCode()) { 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Just tail call into the fast handler if present. 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Jump(handle(Code::cast(api_call_info->fast_handler())), 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::CODE_TARGET); 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Put api_function_address in place. 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Address function_address = v8::ToCData<Address>(api_call_info->callback()); 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ApiFunction fun(function_address); 295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExternalReference::Type type = ExternalReference::DIRECT_API_CALL; 296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ExternalReference ref = ExternalReference(&fun, type, masm->isolate()); 297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ mov(api_function_address, Operand(ref)); 298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Jump to stub. 3003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CallApiCallbackStub stub(isolate, is_store, call_data_undefined, 301109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch !optimization.is_constant_call()); 302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ TailCallStub(&stub); 303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef __ 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define __ ACCESS_MASM(masm()) 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Name> name) { 311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!label->is_unused()) { 312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(label); 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ mov(this->name(), Operand(name)); 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 317c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid PropertyHandlerCompiler::GenerateAccessCheck( 318c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2, 319c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label* miss, bool compare_native_contexts_only) { 320c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label done; 321c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Load current native context. 322c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ LoadP(scratch1, NativeContextMemOperand()); 323c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Load expected native context. 324c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ LoadWeakValue(scratch2, native_context_cell, miss); 325c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ cmp(scratch1, scratch2); 326c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 327c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!compare_native_contexts_only) { 328c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ beq(&done); 329c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 330c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Compare security tokens of current and expected native contexts. 331c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ LoadP(scratch1, 332c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ContextMemOperand(scratch1, Context::SECURITY_TOKEN_INDEX)); 333c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ LoadP(scratch2, 334c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ContextMemOperand(scratch2, Context::SECURITY_TOKEN_INDEX)); 335c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ cmp(scratch1, scratch2); 336c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 337c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ bne(miss); 338c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 339c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ bind(&done); 340c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRegister PropertyHandlerCompiler::CheckPrototypes( 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register object_reg, Register holder_reg, Register scratch1, 344c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Register scratch2, Handle<Name> name, Label* miss, 345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnHolder return_what) { 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> receiver_map = map(); 347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Make sure there's no overlap between holder and object registers. 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!scratch2.is(object_reg) && !scratch2.is(holder_reg) && 351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !scratch2.is(scratch1)); 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 35313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<Cell> validity_cell = 35413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); 35513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!validity_cell.is_null()) { 35613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); 35713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ mov(scratch1, Operand(validity_cell)); 35813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ LoadP(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); 35913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ CmpSmiLiteral(scratch1, Smi::FromInt(Map::kPrototypeChainValid), r0); 36013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ bne(miss); 36113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Keep track of the current object in register reg. 364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register reg = object_reg; 365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int depth = 0; 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<JSObject> current = Handle<JSObject>::null(); 368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (receiver_map->IsJSGlobalObjectMap()) { 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current = isolate()->global_object(); 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 372c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Map> current_map(receiver_map->GetPrototypeChainRootMap(isolate()), 373c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate()); 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<Map> holder_map(holder()->map()); 375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Traverse the prototype chain and check the maps in the prototype chain for 376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // fast and global objects or do negative lookup for normal objects. 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (!current_map.is_identical_to(holder_map)) { 378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ++depth; 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Only global objects and objects that do not require access 381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // checks are allowed in stubs. 382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(current_map->IsJSGlobalProxyMap() || 383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !current_map->is_access_check_needed()); 384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 38513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (current_map->IsJSGlobalObjectMap()) { 38613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 38713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch name, scratch2, miss); 38813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else if (current_map->is_dictionary_map()) { 389958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. 390c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(name->IsUniqueName()); 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(current.is_null() || 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current->property_dictionary()->FindEntry(name) == 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier NameDictionary::kNotFound); 394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 39513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (depth > 1) { 396c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<WeakCell> weak_cell = 397c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Map::GetOrCreatePrototypeWeakCell(current, isolate()); 398c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ LoadWeakValue(reg, weak_cell, miss); 399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier scratch2); 402958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg = holder_reg; // From now on the object will be in holder_reg. 405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Go to the next object in the prototype chain. 406c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch current = handle(JSObject::cast(current_map->prototype())); 407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current_map = handle(current->map()); 408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!current_map->IsJSGlobalProxyMap()); 411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Log the check depth. 413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool return_holder = return_what == RETURN_HOLDER; 41613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (return_holder && depth != 0) { 417c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<WeakCell> weak_cell = 418c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Map::GetOrCreatePrototypeWeakCell(current, isolate()); 419c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ LoadWeakValue(reg, weak_cell, miss); 420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Return the register containing the holder. 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return return_holder ? reg : no_reg; 424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!miss->is_unused()) { 429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label success; 430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ b(&success); 431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(miss); 432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IC::ICUseVector(kind())) { 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(kind() == Code::LOAD_IC); 434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopVectorAndSlot(); 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TailCallBuiltin(masm(), MissBuiltin(kind())); 437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(&success); 438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!miss->is_unused()) { 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label success; 445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ b(&success); 446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateRestoreName(miss, name); 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IC::ICUseVector(kind())) PopVectorAndSlot(); 448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TailCallBuiltin(masm(), MissBuiltin(kind())); 449958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(&success); 450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( 454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LookupIterator* it, Register holder_reg) { 455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(holder()->HasNamedInterceptor()); 45613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); 457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Compile the interceptor call, followed by inline code to load the 459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // property from further up the prototype chain if the call fails. 460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check that the maps haven't changed. 461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Preserve the receiver register explicitly whenever it is different from the 464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // holder and it is needed should the interceptor return without any result. 465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD 466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // case might cause a miss during the prototype check. 467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool must_perform_prototype_check = 468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !holder().is_identical_to(it->GetHolder<JSObject>()); 469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool must_preserve_receiver_reg = 470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier !receiver().is(holder_reg) && 471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check); 472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Save necessary data before invoking an interceptor. 474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Requires a frame to make GC aware of pushed pointers. 475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier { 476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL); 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (must_preserve_receiver_reg) { 478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Push(receiver(), holder_reg, this->name()); 479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Push(holder_reg, this->name()); 481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InterceptorVectorSlotPush(holder_reg); 483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Invoke an interceptor. Note: map checks from receiver to 484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // interceptor's holder has been compiled before (see a caller 485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // of this method.) 486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CompileCallLoadPropertyWithInterceptor( 487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier masm(), receiver(), holder_reg, this->name(), holder(), 488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Runtime::kLoadPropertyWithInterceptorOnly); 489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check if interceptor provided a value for property. If it's 491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // the case, return immediately. 492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label interceptor_failed; 493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ cmp(r3, scratch1()); 495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ beq(&interceptor_failed); 496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier frame_scope.GenerateLeaveFrame(); 497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Ret(); 498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ bind(&interceptor_failed); 500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch InterceptorVectorSlotPop(holder_reg); 501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ pop(this->name()); 502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ pop(holder_reg); 503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (must_preserve_receiver_reg) { 504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ pop(receiver()); 505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Leave the internal frame. 507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateLoadPostInterceptor(it, holder_reg); 510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { 514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Call the runtime system to load the interceptor. 515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(holder()->HasNamedInterceptor()); 51613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); 51762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 51862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 51962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1); 52062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2); 52162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3); 52262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Push(name(), receiver(), holder_reg); 52362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // See NamedLoadHandlerCompiler::InterceptorVectorSlotPop() for details. 52462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (holder_reg.is(receiver())) { 52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Push(slot(), vector()); 52662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 52762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Push(scratch3(), scratch2()); // slot, vector 52862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TailCallRuntime(Runtime::kLoadPropertyWithInterceptor); 531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid NamedStoreHandlerCompiler::ZapStackArgumentsRegisterAliases() { 534f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch STATIC_ASSERT(!StoreWithVectorDescriptor::kPassLastArgsOnStack); 535f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierHandle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback, 539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch LanguageMode language_mode) { 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register holder_reg = Frontend(name); 541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Push(receiver(), holder_reg); // receiver 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the callback cannot leak, then push the callback directly, 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // otherwise wrap it in a weak cell. 54613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (callback->data()->IsUndefined(isolate()) || callback->data()->IsSmi()) { 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(ip, Operand(callback)); 548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback); 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ mov(ip, Operand(cell)); 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ push(ip); 553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ mov(ip, Operand(name)); 554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Push(ip, value()); 555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Push(Smi::FromInt(language_mode)); 556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Do tail-call to the runtime system. 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TailCallRuntime(Runtime::kStoreCallbackProperty); 559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Return the generated code. 561bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRegister NamedStoreHandlerCompiler::value() { 566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return StoreDescriptor::ValueRegister(); 567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierHandle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label miss; 573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IC::ICUseVector(kind())) { 574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushVectorAndSlot(); 575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING); 577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Get the value from the cell. 579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register result = StoreDescriptor::ValueRegister(); 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell); 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadWeakValue(result, weak_cell, &miss); 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadP(result, FieldMemOperand(result, PropertyCell::kValueOffset)); 583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check for deleted property if property can actually be deleted. 585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (is_configurable) { 586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ cmp(result, ip); 588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ beq(&miss); 589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Counters* counters = isolate()->counters(); 592109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ IncrementCounter(counters->ic_named_load_global_stub(), 1, r4, r6); 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IC::ICUseVector(kind())) { 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DiscardVectorAndSlot(); 595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Ret(); 597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FrontendFooter(name, &miss); 599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Return the generated code. 601bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#undef __ 606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif // V8_TARGET_ARCH_ARM 610