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_ARM64 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 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" 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 20958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PropertyHandlerCompiler::PushVectorAndSlot(Register vector, 21958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register slot) { 22958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm = this->masm(); 23f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch STATIC_ASSERT(LoadWithVectorDescriptor::kSlot < 24f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LoadWithVectorDescriptor::kVector); 25f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch STATIC_ASSERT(StoreWithVectorDescriptor::kSlot < 26f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch StoreWithVectorDescriptor::kVector); 27f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch STATIC_ASSERT(StoreTransitionDescriptor::kSlot < 28f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch StoreTransitionDescriptor::kVector); 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Push(slot); 30f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ Push(vector); 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) { 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm = this->masm(); 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Pop(vector); 37f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch __ Pop(slot); 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 40958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 41958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid PropertyHandlerCompiler::DiscardVectorAndSlot() { 42958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MacroAssembler* masm = this->masm(); 43958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Remove vector and slot. 44958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ Drop(2); 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 46958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, Label* miss_label, Register receiver, 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name, Register scratch0, Register scratch1) { 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(receiver, scratch0, scratch1)); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(name->IsUniqueName()); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Counters* counters = masm->isolate()->counters(); 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done; 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const int kInterceptorOrAccessCheckNeededMask = 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (1 << Map::kHasNamedInterceptor) | (1 << Map::kIsAccessCheckNeeded); 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Bail out if the receiver has a named interceptor or requires access checks. 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register map = scratch1; 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ldrb(scratch0, FieldMemOperand(map, Map::kBitFieldOffset)); 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Tst(scratch0, kInterceptorOrAccessCheckNeededMask); 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ B(ne, miss_label); 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that receiver is a JSObject. 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset)); 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Cmp(scratch0, FIRST_JS_RECEIVER_TYPE); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ B(lt, miss_label); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load properties array. 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register properties = scratch0; 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ldr(properties, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the properties array is a dictionary. 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ldr(map, FieldMemOperand(properties, HeapObject::kMapOffset)); 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ JumpIfNotRoot(map, Heap::kHashTableMapRootIndex, miss_label); 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionaryLookupStub::GenerateNegativeLookup( 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm, miss_label, &done, receiver, properties, name, scratch1); 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Bind(&done); 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ DecrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Generate code to check that a global property cell is empty. Create 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// the property cell at compilation time if no cell exists for the 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// property. 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PropertyHandlerCompiler::GenerateCheckPropertyCell( 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, Handle<JSGlobalObject> global, Handle<Name> name, 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch, Label* miss) { 92f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<PropertyCell> cell = JSGlobalObject::EnsureEmptyPropertyCell( 93f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch global, name, PropertyCellType::kInvalidated); 9413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Isolate* isolate = masm->isolate(); 9513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(cell->value()->IsTheHole(isolate)); 9613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<WeakCell> weak_cell = isolate->factory()->NewWeakCell(cell); 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadWeakValue(scratch, weak_cell, miss); 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ldr(scratch, FieldMemOperand(scratch, PropertyCell::kValueOffset)); 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ JumpIfNotRoot(scratch, Heap::kTheHoleValueRootIndex, miss); 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstatic void CompileCallLoadPropertyWithInterceptor( 10362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch MacroAssembler* masm, Register receiver, Register holder, Register name, 10462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Handle<JSObject> holder_obj, Runtime::FunctionId id) { 10562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(NamedLoadHandlerCompiler::kInterceptorArgsLength == 10662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Runtime::FunctionForId(id)->nargs); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1); 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2); 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3); 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Push(name, receiver, holder); 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ CallRuntime(id); 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Generate call to api function. 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid PropertyHandlerCompiler::GenerateApiAccessorCall( 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm, const CallOptimization& optimization, 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map, Register receiver, Register scratch, 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool is_store, Register store_parameter, Register accessor_holder, 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index) { 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!AreAliased(accessor_holder, scratch)); 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(receiver, scratch)); 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler::PushPopQueue queue(masm); 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch queue.Queue(receiver); 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Write the arguments to the stack frame. 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (is_store) { 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!receiver.is(store_parameter)); 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!scratch.is(store_parameter)); 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch queue.Queue(store_parameter); 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch queue.PushQueued(); 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(optimization.is_simple_api_call()); 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Abi for CallApiCallbackStub. 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register callee = x0; 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register data = x4; 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register holder = x2; 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register api_function_address = x1; 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Put callee in place. 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadAccessor(callee, accessor_holder, accessor_index, 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch is_store ? ACCESSOR_SETTER : ACCESSOR_GETTER); 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put holder in place. 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallOptimization::HolderLookup holder_lookup; 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int holder_depth = 0; 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch optimization.LookupHolderOfExpectedType(receiver_map, &holder_lookup, 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch &holder_depth); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (holder_lookup) { 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderIsReceiver: 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Mov(holder, receiver); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderFound: 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ldr(holder, FieldMemOperand(receiver, HeapObject::kMapOffset)); 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (int i = 1; i < holder_depth; i++) { 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ldr(holder, FieldMemOperand(holder, HeapObject::kMapOffset)); 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ldr(holder, FieldMemOperand(holder, Map::kPrototypeOffset)); 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case CallOptimization::kHolderNotFound: 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = masm->isolate(); 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool call_data_undefined = false; 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Put call data in place. 17513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (api_call_info->data()->IsUndefined(isolate)) { 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch call_data_undefined = true; 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadRoot(data, Heap::kUndefinedValueRootIndex); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 179109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (optimization.is_constant_call()) { 180109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Ldr(data, 181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldMemOperand(callee, JSFunction::kSharedFunctionInfoOffset)); 182109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Ldr(data, 183109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldMemOperand(data, SharedFunctionInfo::kFunctionDataOffset)); 184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Ldr(data, 185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldMemOperand(data, FunctionTemplateInfo::kCallCodeOffset)); 186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } else { 187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Ldr(data, 188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldMemOperand(callee, FunctionTemplateInfo::kCallCodeOffset)); 189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ldr(data, FieldMemOperand(data, CallHandlerInfo::kDataOffset)); 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (api_call_info->fast_handler()->IsCode()) { 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Just tail call into the fast handler if present. 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Jump(handle(Code::cast(api_call_info->fast_handler())), 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RelocInfo::CODE_TARGET); 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return; 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Put api_function_address in place. 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Address function_address = v8::ToCData<Address>(api_call_info->callback()); 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ApiFunction fun(function_address); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference ref = ExternalReference( 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &fun, ExternalReference::DIRECT_API_CALL, masm->isolate()); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Mov(api_function_address, ref); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Jump to stub. 2083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch CallApiCallbackStub stub(isolate, is_store, call_data_undefined, 209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch !optimization.is_constant_call()); 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ TailCallStub(&stub); 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedStoreHandlerCompiler::GenerateStoreViaSetter( 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, int expected_arguments, Register scratch) { 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------- S t a t e ------------- 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- lr : return address 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ----------------------------------- 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label miss; 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameScope scope(masm, StackFrame::INTERNAL); 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Save context register 2253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Push(cp); 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save value register, so we can restore it later. 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(value()); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (accessor_index >= 0) { 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!AreAliased(holder, scratch)); 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!AreAliased(receiver, scratch)); 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!AreAliased(value(), scratch)); 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call the JavaScript setter with receiver and value on the stack. 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->IsJSGlobalObjectMap()) { 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Swap in the global receiver. 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ldr(scratch, 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver = scratch; 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(receiver, value()); 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadAccessor(x1, holder, accessor_index, ACCESSOR_SETTER); 2423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Mov(x0, 1); 2433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Call(masm->isolate()->builtins()->CallFunction( 2443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined), 2453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RelocInfo::CODE_TARGET); 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we generate a global code snippet for deoptimization only, remember 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the place to continue after deoptimization. 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have to return the passed value, not the return value of the setter. 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Pop(x0); 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore context register. 2563b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Pop(cp); 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadViaGetter( 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch MacroAssembler* masm, Handle<Map> map, Register receiver, Register holder, 264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index, int expected_arguments, Register scratch) { 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameScope scope(masm, StackFrame::INTERNAL); 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Save context register 2693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Push(cp); 2703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (accessor_index >= 0) { 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!AreAliased(holder, scratch)); 273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!AreAliased(receiver, scratch)); 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call the JavaScript getter with the receiver on the stack. 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (map->IsJSGlobalObjectMap()) { 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Swap in the global receiver. 277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ldr(scratch, 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldMemOperand(receiver, JSGlobalObject::kGlobalProxyOffset)); 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver = scratch; 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(receiver); 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadAccessor(x1, holder, accessor_index, ACCESSOR_GETTER); 2833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Mov(x0, 0); 2843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Call(masm->isolate()->builtins()->CallFunction( 2853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch ConvertReceiverMode::kNotNullOrUndefined), 2863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch RelocInfo::CODE_TARGET); 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If we generate a global code snippet for deoptimization only, remember 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the place to continue after deoptimization. 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Restore context register. 2943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch __ Pop(cp); 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __ 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ ACCESS_MASM(masm()) 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label miss; 306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(); 308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING); 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get the value from the cell. 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result = StoreDescriptor::ValueRegister(); 313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell); 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier __ LoadWeakValue(result, weak_cell, &miss); 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Ldr(result, FieldMemOperand(result, PropertyCell::kValueOffset)); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check for deleted property if property can actually be deleted. 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_configurable) { 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ JumpIfRoot(result, Heap::kTheHoleValueRootIndex, &miss); 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Counters* counters = isolate()->counters(); 323109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ IncrementCounter(counters->ic_named_load_global_stub(), 1, x1, x3); 324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DiscardVectorAndSlot(); 326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrontendFooter(name, &miss); 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the generated code. 332bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister NamedStoreHandlerCompiler::value() { 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return StoreDescriptor::ValueRegister(); 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedStoreHandlerCompiler::GenerateRestoreName(Label* label, 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name) { 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!label->is_unused()) { 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Bind(label); 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Mov(this->name(), Operand(name)); 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 349c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid PropertyHandlerCompiler::GenerateAccessCheck( 350c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<WeakCell> native_context_cell, Register scratch1, Register scratch2, 351c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label* miss, bool compare_native_contexts_only) { 352c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Label done; 353c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Load current native context. 354c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Ldr(scratch1, NativeContextMemOperand()); 355c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Load expected native context. 356c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ LoadWeakValue(scratch2, native_context_cell, miss); 357c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Cmp(scratch1, scratch2); 358c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 359c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!compare_native_contexts_only) { 360c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ B(eq, &done); 361c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 362c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Compare security tokens of current and expected native contexts. 363c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Ldr(scratch1, 364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ContextMemOperand(scratch1, Context::SECURITY_TOKEN_INDEX)); 365c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Ldr(scratch2, 366c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ContextMemOperand(scratch2, Context::SECURITY_TOKEN_INDEX)); 367c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Cmp(scratch1, scratch2); 368c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 369c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ B(ne, miss); 370c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 371c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ bind(&done); 372c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister PropertyHandlerCompiler::CheckPrototypes( 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object_reg, Register holder_reg, Register scratch1, 376c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Register scratch2, Handle<Name> name, Label* miss, 377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnHolder return_what) { 378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> receiver_map = map(); 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object_reg and holder_reg registers can alias. 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(object_reg, scratch1, scratch2)); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(holder_reg, scratch1, scratch2)); 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 38413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Handle<Cell> validity_cell = 38513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Map::GetOrCreatePrototypeChainValidityCell(receiver_map, isolate()); 38613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (!validity_cell.is_null()) { 38713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK_EQ(Smi::FromInt(Map::kPrototypeChainValid), validity_cell->value()); 38813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Mov(scratch1, Operand(validity_cell)); 38913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch __ Ldr(scratch1, FieldMemOperand(scratch1, Cell::kValueOffset)); 390c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch // Compare scratch1 against Map::kPrototypeChainValid. 391c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch static_assert(Map::kPrototypeChainValid == 0, 392c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "Map::kPrototypeChainValid has unexpected value"); 393c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ Cbnz(scratch1, miss); 394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Keep track of the current object in register reg. 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register reg = object_reg; 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int depth = 0; 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> current = Handle<JSObject>::null(); 401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (receiver_map->IsJSGlobalObjectMap()) { 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch current = isolate()->global_object(); 403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 405c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<Map> current_map(receiver_map->GetPrototypeChainRootMap(isolate()), 406c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch isolate()); 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> holder_map(holder()->map()); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Traverse the prototype chain and check the maps in the prototype chain for 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // fast and global objects or do negative lookup for normal objects. 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!current_map.is_identical_to(holder_map)) { 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ++depth; 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (current_map->IsJSGlobalObjectMap()) { 41413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch GenerateCheckPropertyCell(masm(), Handle<JSGlobalObject>::cast(current), 41513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch name, scratch2, miss); 41613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } else if (current_map->is_dictionary_map()) { 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!current_map->IsJSGlobalProxyMap()); // Proxy maps are fast. 418c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch DCHECK(name->IsUniqueName()); 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current.is_null() || (current->property_dictionary()->FindEntry( 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name) == NameDictionary::kNotFound)); 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 42213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (depth > 1) { 423c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<WeakCell> weak_cell = 424c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Map::GetOrCreatePrototypeWeakCell(current, isolate()); 425c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ LoadWeakValue(reg, weak_cell, miss); 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateDictionaryNegativeLookup(masm(), miss, reg, name, scratch1, 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch2); 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg = holder_reg; // From now on the object will be in holder_reg. 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Go to the next object in the prototype chain. 433c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch current = handle(JSObject::cast(current_map->prototype())); 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_map = handle(current->map()); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!current_map->IsJSGlobalProxyMap()); 438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Log the check depth. 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOG(isolate(), IntEvent("check-maps-depth", depth + 1)); 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool return_holder = return_what == RETURN_HOLDER; 44313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (return_holder && depth != 0) { 444c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Handle<WeakCell> weak_cell = 445c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Map::GetOrCreatePrototypeWeakCell(current, isolate()); 446c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch __ LoadWeakValue(reg, weak_cell, miss); 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the register containing the holder. 450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return return_holder ? reg : no_reg; 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!miss->is_unused()) { 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label success; 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ B(&success); 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Bind(miss); 460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(kind() == Code::LOAD_IC); 462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PopVectorAndSlot(); 463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TailCallBuiltin(masm(), MissBuiltin(kind())); 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Bind(&success); 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!miss->is_unused()) { 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label success; 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ B(&success); 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateRestoreName(miss, name); 477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (IC::ICUseVector(kind())) PopVectorAndSlot(); 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TailCallBuiltin(masm(), MissBuiltin(kind())); 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Bind(&success); 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadInterceptorWithFollowup( 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator* it, Register holder_reg) { 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(receiver(), this->name(), scratch1(), scratch2(), 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch3())); 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder()->HasNamedInterceptor()); 48913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compile the interceptor call, followed by inline code to load the 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // property from further up the prototype chain if the call fails. 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the maps haven't changed. 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder_reg.is(receiver()) || holder_reg.is(scratch1())); 495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Preserve the receiver register explicitly whenever it is different from the 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // holder and it is needed should the interceptor return without any result. 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The ACCESSOR case needs the receiver to be passed into C++ code, the FIELD 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // case might cause a miss during the prototype check. 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool must_perform_prototype_check = 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !holder().is_identical_to(it->GetHolder<JSObject>()); 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool must_preserve_receiver_reg = 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !receiver().is(holder_reg) && 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (it->state() == LookupIterator::ACCESSOR || must_perform_prototype_check); 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Save necessary data before invoking an interceptor. 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Requires a frame to make GC aware of pushed pointers. 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameScope frame_scope(masm(), StackFrame::INTERNAL); 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (must_preserve_receiver_reg) { 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(receiver(), holder_reg, this->name()); 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(holder_reg, this->name()); 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPush(holder_reg); 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Invoke an interceptor. Note: map checks from receiver to 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // interceptor's holder has been compiled before (see a caller 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of this method.) 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CompileCallLoadPropertyWithInterceptor( 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm(), receiver(), holder_reg, this->name(), holder(), 521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Runtime::kLoadPropertyWithInterceptorOnly); 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if interceptor provided a value for property. If it's 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the case, return immediately. 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label interceptor_failed; 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ JumpIfRoot(x0, Heap::kNoInterceptorResultSentinelRootIndex, 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch &interceptor_failed); 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_scope.GenerateLeaveFrame(); 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Bind(&interceptor_failed); 532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPop(holder_reg); 533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (must_preserve_receiver_reg) { 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Pop(this->name(), holder_reg, receiver()); 535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Pop(this->name(), holder_reg); 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Leave the internal frame. 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadPostInterceptor(it, holder_reg); 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Call the runtime system to load the interceptor. 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder()->HasNamedInterceptor()); 54813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined(isolate())); 54962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 55062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 55162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1); 55262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2); 55362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3); 55462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Push(name(), receiver(), holder_reg); 55562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // See NamedLoadHandlerCompiler::InterceptorVectorSlotPop() for details. 55662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (holder_reg.is(receiver())) { 55762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Push(slot(), vector()); 55862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else { 55962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch __ Push(scratch3(), scratch2()); // slot, vector 56062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TailCallRuntime(Runtime::kLoadPropertyWithInterceptor); 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid NamedStoreHandlerCompiler::ZapStackArgumentsRegisterAliases() { 566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch STATIC_ASSERT(!StoreWithVectorDescriptor::kPassLastArgsOnStack); 567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback, 571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch LanguageMode language_mode) { 572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ASM_LOCATION("NamedStoreHandlerCompiler::CompileStoreCallback"); 573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register holder_reg = Frontend(name); 574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Stub never generated for non-global objects that require access checks. 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder()->IsJSGlobalProxy() || !holder()->IsAccessCheckNeeded()); 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // receiver() and holder_reg can alias. 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(receiver(), scratch1(), scratch2(), value())); 580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!AreAliased(holder_reg, scratch1(), scratch2(), value())); 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If the callback cannot leak, then push the callback directly, 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // otherwise wrap it in a weak cell. 58313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (callback->data()->IsUndefined(isolate()) || callback->data()->IsSmi()) { 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Mov(scratch1(), Operand(callback)); 585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback); 587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ Mov(scratch1(), Operand(cell)); 588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Mov(scratch2(), Operand(name)); 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Push(receiver(), holder_reg, scratch1(), scratch2(), value()); 591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch __ Push(Smi::FromInt(language_mode)); 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do tail-call to the runtime system. 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ TailCallRuntime(Runtime::kStoreCallbackProperty); 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Return the generated code. 597bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __ 602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_TARGET_ARCH_IA32 606