handler-compiler.cc revision f91f0611dbaf29ca0f1d4aecb357ce243a19d2fa
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 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ic/handler-compiler.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/field-type.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/ic/call-optimization.h" 9f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/ic/handler-configuration.h" 10f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch#include "src/ic/ic-inl.h" 11109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/ic/ic.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> PropertyHandlerCompiler::Find(Handle<Name> name, 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> stub_holder, 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code::Kind kind, 20bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CacheHolderFlag cache_holder) { 21bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Code::Flags flags = Code::ComputeHandlerFlags(kind, cache_holder); 22bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Code* code = stub_holder->LookupInCodeCache(*name, flags); 23bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch if (code == nullptr) return Handle<Code>(); 24bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return handle(code); 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent( 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name, Handle<Map> receiver_map) { 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = name->GetIsolate(); 3113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (receiver_map->prototype()->IsNull(isolate)) { 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(jkummerow/verwaest): If there is no prototype and the property 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is nonexistent, introduce a builtin to handle this (fast properties 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -> return undefined, dictionary properties -> do negative lookup). 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Handle<Code>(); 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CacheHolderFlag flag; 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> stub_holder_map = 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IC::GetHandlerCacheHolder(receiver_map, false, isolate, &flag); 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If no dictionary mode objects are present in the prototype chain, the load 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // nonexistent IC stub can be shared for all names for a given map and we use 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the empty string for the map cache in that case. If there are dictionary 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // mode objects involved, we need to do negative lookups in the stub and 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // therefore the stub will be specific to the name. 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> cache_name = 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_map->is_dictionary_map() 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? name 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Handle<Name>::cast(isolate->factory()->nonexistent_symbol()); 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> current_map = stub_holder_map; 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> last(JSObject::cast(receiver_map->prototype())); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (true) { 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_map->is_dictionary_map()) cache_name = name; 5413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (current_map->prototype()->IsNull(isolate)) break; 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (name->IsPrivate()) { 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(verwaest): Use nonexistent_private_symbol. 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cache_name = name; 58109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!current_map->has_hidden_prototype()) break; 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last = handle(JSObject::cast(current_map->prototype())); 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_map = handle(last->map()); 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compile the stub that is either shared for all names or 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // name specific if there are global objects involved. 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> handler = PropertyHandlerCompiler::Find( 67bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch cache_name, stub_holder_map, Code::LOAD_IC, flag); 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!handler.is_null()) return handler; 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 70bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch TRACE_HANDLER_STATS(isolate, LoadIC_LoadNonexistent); 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag); 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handler = compiler.CompileLoadNonexistent(cache_name); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map::UpdateCodeCache(stub_holder_map, cache_name, handler); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return handler; 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind, 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name) { 80bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Code::Flags flags = Code::ComputeHandlerFlags(kind, cache_holder()); 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, name); 8213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PROFILE(isolate(), CodeCreateEvent(CodeEventListener::HANDLER_TAG, 833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AbstractCode::cast(*code), *name)); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code->VerifyEmbeddedObjects(); 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return code; 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ ACCESS_MASM(masm()) 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name, 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss, 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnHolder return_what) { 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrototypeCheckType check_type = SKIP_RECEIVER; 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int function_index = map()->IsPrimitiveMap() 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? map()->GetConstructorFunctionIndex() 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Map::kNoConstructorFunctionIndex; 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function_index != Map::kNoConstructorFunctionIndex) { 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index, 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch1(), miss); 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* function = isolate()->native_context()->get(function_index); 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* prototype = JSFunction::cast(function)->instance_prototype(); 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> map(JSObject::cast(prototype)->map()); 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_map(map); 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_reg = scratch1(); 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch check_type = CHECK_ALL_MAPS; 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the maps starting from the prototype haven't changed. 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name, 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch miss, check_type, return_what); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Frontend for store uses the name register. It has to be restored before a 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// miss. 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister NamedStoreHandlerCompiler::FrontendHeader(Register object_reg, 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name, 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss, 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnHolder return_what) { 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name, 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch miss, SKIP_RECEIVER, return_what); 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRegister PropertyHandlerCompiler::Frontend(Handle<Name> name) { 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label miss; 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(); 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = FrontendHeader(receiver(), name, &miss, RETURN_HOLDER); 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrontendFooter(name, &miss); 137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The footer consumes the vector and slot from the stack if miss occurs. 138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DiscardVectorAndSlot(); 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reg; 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name, 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* miss, 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2) { 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register holder_reg; 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> last_map; 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (holder().is_null()) { 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder_reg = receiver(); 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch last_map = map(); 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If |type| has null as its prototype, |holder()| is 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle<JSObject>::null(). 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(last_map->prototype() == isolate()->heap()->null_value()); 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_map = handle(holder()->map()); 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This condition matches the branches below. 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool need_holder = 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch last_map->is_dictionary_map() && !last_map->IsJSGlobalObjectMap(); 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch holder_reg = 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrontendHeader(receiver(), name, miss, 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch need_holder ? RETURN_HOLDER : DONT_RETURN_ANYTHING); 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last_map->is_dictionary_map()) { 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last_map->IsJSGlobalObjectMap()) { 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSGlobalObject> global = 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder().is_null() 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? Handle<JSGlobalObject>::cast(isolate()->global_object()) 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Handle<JSGlobalObject>::cast(holder()); 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateCheckPropertyCell(masm(), global, name, scratch1, miss); 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!name->IsUniqueName()) { 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(name->IsString()); 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name = factory()->InternalizeString(Handle<String>::cast(name)); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder().is_null() || 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder()->property_dictionary()->FindEntry(name) == 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionary::kNotFound); 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1, 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch2); 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name, 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldIndex field) { 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register reg = Frontend(name); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Move(receiver(), reg); 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadFieldStub stub(isolate(), field); 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateTailCall(masm(), stub.GetCode()); 195bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name, 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_index) { 201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register reg = Frontend(name); 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Move(receiver(), reg); 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadConstantStub stub(isolate(), constant_index); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateTailCall(masm(), stub.GetCode()); 205bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name) { 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label miss; 212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(kind() == Code::LOAD_IC); 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(); 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NonexistentFrontendHeader(name, &miss, scratch2(), scratch3()); 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 218958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DiscardVectorAndSlot(); 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadConstant(isolate()->factory()->undefined_value()); 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrontendFooter(name, &miss); 222bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Name> name, Handle<AccessorInfo> callback, Handle<Code> slow_stub) { 22713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (FLAG_runtime_call_stats) { 228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GenerateTailCall(masm(), slow_stub); 22913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register reg = Frontend(name); 231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GenerateLoadCallback(reg, callback); 232bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name, const CallOptimization& call_optimization, 237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int accessor_index, Handle<Code> slow_stub) { 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call_optimization.is_simple_api_call()); 23913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (FLAG_runtime_call_stats) { 240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GenerateTailCall(masm(), slow_stub); 24113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 242f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register holder = Frontend(name); 243f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(), 244f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch scratch2(), false, no_reg, holder, accessor_index); 245bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) { 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (holder_reg.is(receiver())) { 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(); 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(holder_reg.is(scratch1())); 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(scratch2(), scratch3()); 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedLoadHandlerCompiler::InterceptorVectorSlotPop(Register holder_reg, 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PopMode mode) { 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mode == DISCARD) { 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DiscardVectorAndSlot(); 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (holder_reg.is(receiver())) { 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PopVectorAndSlot(); 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(holder_reg.is(scratch1())); 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PopVectorAndSlot(scratch2(), scratch3()); 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor( 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator* it) { 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // So far the most popular follow ups for interceptor loads are DATA and 281109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // AccessorInfo, so inline only them. Other cases may be added 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // later. 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool inline_followup = false; 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (it->state()) { 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::TRANSITION: 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESS_CHECK: 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::INTERCEPTOR: 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::JSPROXY: 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::NOT_FOUND: 291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case LookupIterator::INTEGER_INDEXED_EXOTIC: 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::DATA: 294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline_followup = 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it->property_details().type() == DATA && !it->is_dictionary_holder(); 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESSOR: { 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> accessors = it->GetAccessors(); 299109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (accessors->IsAccessorInfo()) { 300109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); 301109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inline_followup = 302109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch info->getter() != NULL && 303109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map()); 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (accessors->IsAccessorPair()) { 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> property_holder(it->GetHolder<JSObject>()); 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()); 308109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!(getter->IsJSFunction() || getter->IsFunctionTemplateInfo())) { 309109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 310109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!property_holder->HasFastProperties()) break; 312109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallOptimization call_optimization(getter); 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> receiver_map = map(); 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline_followup = call_optimization.is_simple_api_call() && 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch call_optimization.IsCompatibleReceiverMap( 316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_map, property_holder); 317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label miss; 322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPush(receiver()); 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool lost_holder_register = false; 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto holder_orig = holder(); 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // non masking interceptors must check the entire chain, so temporarily reset 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the holder to be that last element for the FrontendHeader call. 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (holder()->GetNamedInterceptor()->non_masking()) { 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!inline_followup); 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject* last = *holder(); 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrototypeIterator iter(isolate(), last); 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (!iter.IsAtEnd()) { 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lost_holder_register = true; 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Casting to JSObject is fine here. The LookupIterator makes sure to 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // look behind non-masking interceptors during the original lookup, and 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // we wouldn't try to compile a handler if there was a Proxy anywhere. 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch last = iter.GetCurrent<JSObject>(); 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch iter.Advance(); 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto last_handle = handle(last); 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_holder(last_handle); 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = FrontendHeader(receiver(), it->name(), &miss, RETURN_HOLDER); 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Reset the holder so further calculations are correct. 344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_holder(holder_orig); 345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (lost_holder_register) { 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (*it->GetReceiver() == *holder()) { 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg = receiver(); 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Reload lost holder register. 350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto cell = isolate()->factory()->NewWeakCell(holder()); 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadWeakValue(reg, cell, &miss); 352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FrontendFooter(it->name(), &miss); 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPop(reg); 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inline_followup) { 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(368): Compile in the whole chain: all the interceptors in 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // prototypes and ultimate answer. 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadInterceptorWithFollowup(it, reg); 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadInterceptor(reg); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 363bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), it->name()); 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 366bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochvoid NamedLoadHandlerCompiler::GenerateLoadCallback( 367bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Register reg, Handle<AccessorInfo> callback) { 368bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch DCHECK(receiver().is(ApiGetterDescriptor::ReceiverRegister())); 369bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ Move(ApiGetterDescriptor::HolderRegister(), reg); 370bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // The callback is alive if this instruction is executed, 371bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch // so the weak cell is not cleared and points to data. 372bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback); 373bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ GetWeakValue(ApiGetterDescriptor::CallbackRegister(), cell); 374bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch 375bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch CallApiGetterStub stub(isolate()); 376bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch __ TailCallStub(&stub); 377bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch} 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator* it, Register interceptor_reg) { 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>()); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> holder_map(holder()->map()); 384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_map(holder_map); 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_holder(real_named_property_holder); 386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 387958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label miss; 388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPush(interceptor_reg); 389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrontendHeader(interceptor_reg, it->name(), &miss, RETURN_HOLDER); 391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FrontendFooter(it->name(), &miss); 392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // We discard the vector and slot now because we don't miss below this point. 393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPop(reg, DISCARD); 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (it->state()) { 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESS_CHECK: 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::INTERCEPTOR: 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::JSPROXY: 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::NOT_FOUND: 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case LookupIterator::INTEGER_INDEXED_EXOTIC: 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::TRANSITION: 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::DATA: { 404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(DATA, it->property_details().type()); 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Move(receiver(), reg); 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadFieldStub stub(isolate(), it->GetFieldIndex()); 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateTailCall(masm(), stub.GetCode()); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESSOR: 411109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (it->GetAccessors()->IsAccessorInfo()) { 412109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AccessorInfo> info = 413109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AccessorInfo>::cast(it->GetAccessors()); 414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NOT_NULL(info->getter()); 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateLoadCallback(reg, info); 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 417109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> function = handle( 418109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AccessorPair::cast(*it->GetAccessors())->getter(), isolate()); 419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallOptimization call_optimization(function); 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateApiAccessorCall(masm(), call_optimization, holder_map, 421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver(), scratch2(), false, no_reg, reg, 422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it->GetAccessorIndex()); 423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name, int accessor_index, int expected_arguments) { 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register holder = Frontend(name); 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateLoadViaGetter(masm(), map(), receiver(), holder, accessor_index, 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expected_arguments, scratch2()); 432bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(verwaest): Cleanup. holder() is actually the receiver. 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> transition, Handle<Name> name) { 439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label miss; 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushVectorAndSlot(); 442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that we are allowed to write this. 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_nonexistent = holder()->map() == transition->GetBackPointer(); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_nonexistent) { 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find the top object. 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> last; 448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrototypeIterator::WhereToEnd end = 449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch name->IsPrivate() ? PrototypeIterator::END_AT_NON_HIDDEN 450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : PrototypeIterator::END_AT_NULL; 45113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch PrototypeIterator iter(isolate(), holder(), kStartAtPrototype, end); 452109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch while (!iter.IsAtEnd()) { 453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch last = PrototypeIterator::GetCurrent<JSObject>(iter); 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iter.Advance(); 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!last.is_null()) set_holder(last); 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NonexistentFrontendHeader(name, &miss, scratch1(), scratch2()); 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING); 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder()->HasFastProperties()); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int descriptor = transition->LastAdded(); 464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<DescriptorArray> descriptors(transition->instance_descriptors()); 465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PropertyDetails details = descriptors->GetDetails(descriptor); 466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Representation representation = details.representation(); 467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!representation.IsNone()); 468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Stub is never generated for objects that require access checks. 470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!transition->is_access_check_needed()); 471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Call to respective StoreTransitionStub. 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool virtual_args = StoreTransitionHelper::HasVirtualSlotArg(); 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register map_reg = StoreTransitionHelper::MapRegister(); 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (details.type() == DATA_CONSTANT) { 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(descriptors->GetValue(descriptor)->IsJSFunction()); 478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register tmp = 479f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual_args ? StoreWithVectorDescriptor::VectorRegister() : map_reg; 480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateRestoreMap(transition, tmp, scratch2(), &miss); 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateConstantCheck(tmp, descriptor, value(), scratch2(), &miss); 482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (virtual_args) { 483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This will move the map from tmp into map_reg. 484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RearrangeVectorAndSlot(tmp, map_reg); 485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopVectorAndSlot(); 487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateRestoreName(name); 489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StoreTransitionStub stub(isolate()); 490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateTailCall(masm(), stub.GetCode()); 491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (representation.IsHeapObject()) { 494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateFieldTypeChecks(descriptors->GetFieldType(descriptor), value(), 495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier &miss); 496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StoreTransitionStub::StoreMode store_mode = 498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Map::cast(transition->GetBackPointer())->unused_property_fields() == 0 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ? StoreTransitionStub::ExtendStorageAndStoreMapAndValue 500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : StoreTransitionStub::StoreMapAndValue; 501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register tmp = 503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual_args ? StoreWithVectorDescriptor::VectorRegister() : map_reg; 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateRestoreMap(transition, tmp, scratch2(), &miss); 505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (virtual_args) { 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RearrangeVectorAndSlot(tmp, map_reg); 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopVectorAndSlot(); 509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateRestoreName(name); 511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StoreTransitionStub stub(isolate(), 512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FieldIndex::ForDescriptor(*transition, descriptor), 513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier representation, store_mode); 514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateTailCall(masm(), stub.GetCode()); 515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateRestoreName(&miss, name); 518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopVectorAndSlot(); 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TailCallBuiltin(masm(), MissBuiltin(kind())); 520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 521bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool NamedStoreHandlerCompiler::RequiresFieldTypeChecks( 525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldType* field_type) const { 526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return field_type->IsClass(); 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) { 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label miss; 532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(it->representation().IsHeapObject()); 533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldType* field_type = *it->GetFieldType(); 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool need_save_restore = false; 536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (RequiresFieldTypeChecks(field_type)) { 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch need_save_restore = IC::ICUseVector(kind()); 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (need_save_restore) PushVectorAndSlot(); 539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateFieldTypeChecks(field_type, value(), &miss); 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (need_save_restore) PopVectorAndSlot(); 541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation()); 544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateTailCall(masm(), stub.GetCode()); 545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&miss); 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (need_save_restore) PopVectorAndSlot(); 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TailCallBuiltin(masm(), MissBuiltin(kind())); 549bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), it->name()); 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( 554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> object, Handle<Name> name, int accessor_index, 555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int expected_arguments) { 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register holder = Frontend(name); 557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index, 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expected_arguments, scratch2()); 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 560bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> object, Handle<Name> name, 565f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch const CallOptimization& call_optimization, int accessor_index, 566f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Code> slow_stub) { 56713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch if (FLAG_runtime_call_stats) { 568f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GenerateTailCall(masm(), slow_stub); 56913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch } 570f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Register holder = Frontend(name); 571f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch GenerateApiAccessorCall(masm(), call_optimization, handle(object->map()), 572f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch receiver(), scratch2(), true, value(), holder, 573f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch accessor_index); 574bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch return GetCode(kind(), name); 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __ 579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// static 581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen MurdochHandle<Object> ElementHandlerCompiler::GetKeyedLoadHandler( 582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Handle<Map> receiver_map, Isolate* isolate) { 583f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_map->has_indexed_interceptor() && 584f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !receiver_map->GetIndexedInterceptor()->getter()->IsUndefined(isolate) && 585f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch !receiver_map->GetIndexedInterceptor()->non_masking()) { 586f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadIndexedInterceptorStub); 587f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return LoadIndexedInterceptorStub(isolate).GetCode(); 588f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 589f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (receiver_map->IsStringMap()) { 590f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadIndexedStringStub); 591f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return LoadIndexedStringStub(isolate).GetCode(); 592f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 593f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch InstanceType instance_type = receiver_map->instance_type(); 594f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (instance_type < FIRST_JS_RECEIVER_TYPE) { 595f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TRACE_HANDLER_STATS(isolate, KeyedLoadIC_SlowStub); 596f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return isolate->builtins()->KeyedLoadIC_Slow(); 597f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 599f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch ElementsKind elements_kind = receiver_map->elements_kind(); 600f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (IsSloppyArgumentsElements(elements_kind)) { 601f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TRACE_HANDLER_STATS(isolate, KeyedLoadIC_KeyedLoadSloppyArgumentsStub); 602f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return KeyedLoadSloppyArgumentsStub(isolate).GetCode(); 603f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 604f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (elements_kind == DICTIONARY_ELEMENTS) { 605f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadDictionaryElementStub); 606f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return LoadDictionaryElementStub(isolate).GetCode(); 607f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 608f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch DCHECK(IsFastElementsKind(elements_kind) || 609f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch IsFixedTypedArrayElementsKind(elements_kind)); 610f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool is_js_array = instance_type == JS_ARRAY_TYPE; 611f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch bool convert_hole_to_undefined = 612f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch is_js_array && elements_kind == FAST_HOLEY_ELEMENTS && 613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch *receiver_map == isolate->get_initial_js_array_map(elements_kind); 614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch if (FLAG_tf_load_ic_stub) { 615f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch int config = KeyedLoadElementsKind::encode(elements_kind) | 616f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch KeyedLoadConvertHole::encode(convert_hole_to_undefined) | 617f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch KeyedLoadIsJsArray::encode(is_js_array) | 618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch LoadHandlerTypeBit::encode(kLoadICHandlerForElements); 619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return handle(Smi::FromInt(config), isolate); 620f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } else { 621f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch TRACE_HANDLER_STATS(isolate, KeyedLoadIC_LoadFastElementStub); 622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch return LoadFastElementStub(isolate, is_js_array, elements_kind, 623f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch convert_hole_to_undefined) 624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch .GetCode(); 625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch } 626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch} 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochvoid ElementHandlerCompiler::CompileElementHandlers( 629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch MapHandleList* receiver_maps, List<Handle<Object>>* handlers) { 630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch for (int i = 0; i < receiver_maps->length(); ++i) { 631f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch handlers->Add(GetKeyedLoadHandler(receiver_maps->at(i), isolate())); 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 636