handler-compiler.cc revision 3b9bc31999c9787eb726ecdbfd5796bfdec32a18
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" 9f2e3994fa5148cc3d9946666f0b0596290192b0eBen Murdoch#include "src/ic/ic-inl.h" 10109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#include "src/ic/ic.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/isolate-inl.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/profiler/cpu-profiler.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> PropertyHandlerCompiler::Find(Handle<Name> name, 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> stub_holder, 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code::Kind kind, 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CacheHolderFlag cache_holder, 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code::StubType type) { 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder); 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* probe = stub_holder->FindInCodeCache(*name, flags); 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (probe->IsCode()) return handle(Code::cast(probe)); 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Handle<Code>::null(); 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::ComputeLoadNonexistent( 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name, Handle<Map> receiver_map) { 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate = name->GetIsolate(); 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (receiver_map->prototype()->IsNull()) { 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(jkummerow/verwaest): If there is no prototype and the property 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // is nonexistent, introduce a builtin to handle this (fast properties 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -> return undefined, dictionary properties -> do negative lookup). 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Handle<Code>(); 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CacheHolderFlag flag; 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> stub_holder_map = 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch IC::GetHandlerCacheHolder(receiver_map, false, isolate, &flag); 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If no dictionary mode objects are present in the prototype chain, the load 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // nonexistent IC stub can be shared for all names for a given map and we use 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the empty string for the map cache in that case. If there are dictionary 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // mode objects involved, we need to do negative lookups in the stub and 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // therefore the stub will be specific to the name. 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> cache_name = 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch receiver_map->is_dictionary_map() 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? name 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Handle<Name>::cast(isolate->factory()->nonexistent_symbol()); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> current_map = stub_holder_map; 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> last(JSObject::cast(receiver_map->prototype())); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (true) { 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_map->is_dictionary_map()) cache_name = name; 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_map->prototype()->IsNull()) break; 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (name->IsPrivate()) { 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // TODO(verwaest): Use nonexistent_private_symbol. 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cache_name = name; 60109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!current_map->has_hidden_prototype()) break; 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last = handle(JSObject::cast(current_map->prototype())); 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_map = handle(last->map()); 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compile the stub that is either shared for all names or 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // name specific if there are global objects involved. 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> handler = PropertyHandlerCompiler::Find( 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cache_name, stub_holder_map, Code::LOAD_IC, flag, Code::FAST); 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!handler.is_null()) return handler; 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NamedLoadHandlerCompiler compiler(isolate, receiver_map, last, flag); 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handler = compiler.CompileLoadNonexistent(cache_name); 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Map::UpdateCodeCache(stub_holder_map, cache_name, handler); 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return handler; 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> PropertyHandlerCompiler::GetCode(Code::Kind kind, 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code::StubType type, 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name) { 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Code::Flags flags = Code::ComputeHandlerFlags(kind, type, cache_holder()); 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, name); 843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch PROFILE(isolate(), CodeCreateEvent(Logger::HANDLER_TAG, 853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch AbstractCode::cast(*code), *name)); 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch code->VerifyEmbeddedObjects(); 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return code; 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define __ ACCESS_MASM(masm()) 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister NamedLoadHandlerCompiler::FrontendHeader(Register object_reg, 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name, 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss, 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnHolder return_what) { 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrototypeCheckType check_type = SKIP_RECEIVER; 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int function_index = map()->IsPrimitiveMap() 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? map()->GetConstructorFunctionIndex() 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : Map::kNoConstructorFunctionIndex; 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (function_index != Map::kNoConstructorFunctionIndex) { 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateDirectLoadGlobalFunctionPrototype(masm(), function_index, 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch1(), miss); 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* function = isolate()->native_context()->get(function_index); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Object* prototype = JSFunction::cast(function)->instance_prototype(); 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> map(JSObject::cast(prototype)->map()); 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_map(map); 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch object_reg = scratch1(); 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch check_type = CHECK_ALL_MAPS; 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that the maps starting from the prototype haven't changed. 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CheckPrototypes(object_reg, scratch1(), scratch2(), scratch3(), name, 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch miss, check_type, return_what); 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Frontend for store uses the name register. It has to be restored before a 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// miss. 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegister NamedStoreHandlerCompiler::FrontendHeader(Register object_reg, 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name, 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Label* miss, 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ReturnHolder return_what) { 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return CheckPrototypes(object_reg, this->name(), scratch1(), scratch2(), name, 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch miss, SKIP_RECEIVER, return_what); 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRegister PropertyHandlerCompiler::Frontend(Handle<Name> name) { 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label miss; 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(); 136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = FrontendHeader(receiver(), name, &miss, RETURN_HOLDER); 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrontendFooter(name, &miss); 139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // The footer consumes the vector and slot from the stack if miss occurs. 140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DiscardVectorAndSlot(); 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return reg; 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid PropertyHandlerCompiler::NonexistentFrontendHeader(Handle<Name> name, 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* miss, 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch1, 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register scratch2) { 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register holder_reg; 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> last_map; 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (holder().is_null()) { 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder_reg = receiver(); 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch last_map = map(); 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If |type| has null as its prototype, |holder()| is 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle<JSObject>::null(). 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(last_map->prototype() == isolate()->heap()->null_value()); 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_map = handle(holder()->map()); 161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This condition matches the branches below. 162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool need_holder = 163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch last_map->is_dictionary_map() && !last_map->IsJSGlobalObjectMap(); 164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch holder_reg = 165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrontendHeader(receiver(), name, miss, 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch need_holder ? RETURN_HOLDER : DONT_RETURN_ANYTHING); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last_map->is_dictionary_map()) { 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (last_map->IsJSGlobalObjectMap()) { 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSGlobalObject> global = 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder().is_null() 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ? Handle<JSGlobalObject>::cast(isolate()->global_object()) 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : Handle<JSGlobalObject>::cast(holder()); 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateCheckPropertyCell(masm(), global, name, scratch1, miss); 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!name->IsUniqueName()) { 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(name->IsString()); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch name = factory()->InternalizeString(Handle<String>::cast(name)); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder().is_null() || 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch holder()->property_dictionary()->FindEntry(name) == 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NameDictionary::kNotFound); 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateDictionaryNegativeLookup(masm(), miss, holder_reg, name, scratch1, 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scratch2); 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadField(Handle<Name> name, 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FieldIndex field) { 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register reg = Frontend(name); 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Move(receiver(), reg); 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadFieldStub stub(isolate(), field); 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateTailCall(masm(), stub.GetCode()); 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, name); 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadConstant(Handle<Name> name, 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int constant_index) { 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register reg = Frontend(name); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Move(receiver(), reg); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadConstantStub stub(isolate(), constant_index); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateTailCall(masm(), stub.GetCode()); 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, name); 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadNonexistent( 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Name> name) { 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label miss; 214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(kind() == Code::LOAD_IC); 216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(); 217958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NonexistentFrontendHeader(name, &miss, scratch2(), scratch3()); 219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DiscardVectorAndSlot(); 221958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadConstant(isolate()->factory()->undefined_value()); 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrontendFooter(name, &miss); 224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, name); 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Name> name, Handle<AccessorInfo> callback) { 230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Register reg = Frontend(name); 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadCallback(reg, callback); 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, name); 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadCallback( 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name, const CallOptimization& call_optimization, 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int accessor_index) { 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(call_optimization.is_simple_api_call()); 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register holder = Frontend(name); 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateApiAccessorCall(masm(), call_optimization, map(), receiver(), 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch scratch2(), false, no_reg, holder, accessor_index); 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, name); 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedLoadHandlerCompiler::InterceptorVectorSlotPush(Register holder_reg) { 248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (holder_reg.is(receiver())) { 250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(); 251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(holder_reg.is(scratch1())); 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PushVectorAndSlot(scratch2(), scratch3()); 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid NamedLoadHandlerCompiler::InterceptorVectorSlotPop(Register holder_reg, 260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PopMode mode) { 261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (IC::ICUseVector(kind())) { 262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (mode == DISCARD) { 263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DiscardVectorAndSlot(); 264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (holder_reg.is(receiver())) { 266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PopVectorAndSlot(); 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(holder_reg.is(scratch1())); 269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PopVectorAndSlot(scratch2(), scratch3()); 270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadInterceptor( 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator* it) { 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // So far the most popular follow ups for interceptor loads are DATA and 279109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch // AccessorInfo, so inline only them. Other cases may be added 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // later. 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool inline_followup = false; 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (it->state()) { 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::TRANSITION: 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESS_CHECK: 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::INTERCEPTOR: 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::JSPROXY: 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::NOT_FOUND: 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case LookupIterator::INTEGER_INDEXED_EXOTIC: 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::DATA: 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inline_followup = 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it->property_details().type() == DATA && !it->is_dictionary_holder(); 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESSOR: { 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> accessors = it->GetAccessors(); 297109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (accessors->IsAccessorInfo()) { 298109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(accessors); 299109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch inline_followup = 300109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch info->getter() != NULL && 301109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AccessorInfo::IsCompatibleReceiverMap(isolate(), info, map()); 302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else if (accessors->IsAccessorPair()) { 303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> property_holder(it->GetHolder<JSObject>()); 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch isolate()); 306109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (!(getter->IsJSFunction() || getter->IsFunctionTemplateInfo())) { 307109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch break; 308109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch } 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!property_holder->HasFastProperties()) break; 310109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch CallOptimization call_optimization(getter); 311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> receiver_map = map(); 312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch inline_followup = call_optimization.is_simple_api_call() && 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch call_optimization.IsCompatibleReceiverMap( 314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver_map, property_holder); 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label miss; 320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPush(receiver()); 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool lost_holder_register = false; 322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto holder_orig = holder(); 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // non masking interceptors must check the entire chain, so temporarily reset 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // the holder to be that last element for the FrontendHeader call. 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (holder()->GetNamedInterceptor()->non_masking()) { 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(!inline_followup); 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSObject* last = *holder(); 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrototypeIterator iter(isolate(), last); 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch while (!iter.IsAtEnd()) { 330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch lost_holder_register = true; 331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Casting to JSObject is fine here. The LookupIterator makes sure to 332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // look behind non-masking interceptors during the original lookup, and 333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // we wouldn't try to compile a handler if there was a Proxy anywhere. 334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch last = iter.GetCurrent<JSObject>(); 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch iter.Advance(); 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto last_handle = handle(last); 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_holder(last_handle); 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = FrontendHeader(receiver(), it->name(), &miss, RETURN_HOLDER); 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Reset the holder so further calculations are correct. 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_holder(holder_orig); 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (lost_holder_register) { 344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (*it->GetReceiver() == *holder()) { 345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch reg = receiver(); 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Reload lost holder register. 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch auto cell = isolate()->factory()->NewWeakCell(holder()); 349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch __ LoadWeakValue(reg, cell, &miss); 350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FrontendFooter(it->name(), &miss); 353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPop(reg); 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (inline_followup) { 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(368): Compile in the whole chain: all the interceptors in 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // prototypes and ultimate answer. 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadInterceptorWithFollowup(it, reg); 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadInterceptor(reg); 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, it->name()); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid NamedLoadHandlerCompiler::GenerateLoadPostInterceptor( 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LookupIterator* it, Register interceptor_reg) { 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> real_named_property_holder(it->GetHolder<JSObject>()); 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Map> holder_map(holder()->map()); 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch set_map(holder_map); 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch set_holder(real_named_property_holder); 372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label miss; 374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPush(interceptor_reg); 375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register reg = 376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrontendHeader(interceptor_reg, it->name(), &miss, RETURN_HOLDER); 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FrontendFooter(it->name(), &miss); 378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // We discard the vector and slot now because we don't miss below this point. 379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InterceptorVectorSlotPop(reg, DISCARD); 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (it->state()) { 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESS_CHECK: 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::INTERCEPTOR: 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::JSPROXY: 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::NOT_FOUND: 386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch case LookupIterator::INTEGER_INDEXED_EXOTIC: 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::TRANSITION: 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::DATA: { 390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_EQ(DATA, it->property_details().type()); 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Move(receiver(), reg); 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LoadFieldStub stub(isolate(), it->GetFieldIndex()); 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateTailCall(masm(), stub.GetCode()); 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case LookupIterator::ACCESSOR: 397109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch if (it->GetAccessors()->IsAccessorInfo()) { 398109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AccessorInfo> info = 399109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<AccessorInfo>::cast(it->GetAccessors()); 400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NOT_NULL(info->getter()); 401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateLoadCallback(reg, info); 402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 403109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch Handle<Object> function = handle( 404109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch AccessorPair::cast(*it->GetAccessors())->getter(), isolate()); 405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallOptimization call_optimization(function); 406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateApiAccessorCall(masm(), call_optimization, holder_map, 407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver(), scratch2(), false, no_reg, reg, 408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch it->GetAccessorIndex()); 409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedLoadHandlerCompiler::CompileLoadViaGetter( 415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<Name> name, int accessor_index, int expected_arguments) { 416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register holder = Frontend(name); 417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateLoadViaGetter(masm(), map(), receiver(), holder, accessor_index, 418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expected_arguments, scratch2()); 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, name); 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(verwaest): Cleanup. holder() is actually the receiver. 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> transition, Handle<Name> name) { 426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Label miss; 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PushVectorAndSlot(); 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that we are allowed to write this. 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_nonexistent = holder()->map() == transition->GetBackPointer(); 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_nonexistent) { 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find the top object. 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> last; 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PrototypeIterator::WhereToEnd end = 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch name->IsPrivate() ? PrototypeIterator::END_AT_NON_HIDDEN 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch : PrototypeIterator::END_AT_NULL; 438109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PrototypeIterator iter(isolate(), holder(), 439109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch PrototypeIterator::START_AT_PROTOTYPE, end); 440109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch while (!iter.IsAtEnd()) { 441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch last = PrototypeIterator::GetCurrent<JSObject>(iter); 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iter.Advance(); 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!last.is_null()) set_holder(last); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NonexistentFrontendHeader(name, &miss, scratch1(), scratch2()); 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING); 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(holder()->HasFastProperties()); 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int descriptor = transition->LastAdded(); 452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Handle<DescriptorArray> descriptors(transition->instance_descriptors()); 453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PropertyDetails details = descriptors->GetDetails(descriptor); 454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Representation representation = details.representation(); 455958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!representation.IsNone()); 456958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 457958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Stub is never generated for objects that require access checks. 458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!transition->is_access_check_needed()); 459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Call to respective StoreTransitionStub. 461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool virtual_args = StoreTransitionHelper::HasVirtualSlotArg(); 462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register map_reg = StoreTransitionHelper::MapRegister(); 463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (details.type() == DATA_CONSTANT) { 465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(descriptors->GetValue(descriptor)->IsJSFunction()); 466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register tmp = 467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual_args ? VectorStoreICDescriptor::VectorRegister() : map_reg; 468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateRestoreMap(transition, tmp, scratch2(), &miss); 469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateConstantCheck(tmp, descriptor, value(), scratch2(), &miss); 470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (virtual_args) { 471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // This will move the map from tmp into map_reg. 472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RearrangeVectorAndSlot(tmp, map_reg); 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopVectorAndSlot(); 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateRestoreName(name); 477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StoreTransitionStub stub(isolate()); 478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateTailCall(masm(), stub.GetCode()); 479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (representation.IsHeapObject()) { 482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateFieldTypeChecks(descriptors->GetFieldType(descriptor), value(), 483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier &miss); 484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StoreTransitionStub::StoreMode store_mode = 486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Map::cast(transition->GetBackPointer())->unused_property_fields() == 0 487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ? StoreTransitionStub::ExtendStorageAndStoreMapAndValue 488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : StoreTransitionStub::StoreMapAndValue; 489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register tmp = 491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch virtual_args ? VectorStoreICDescriptor::VectorRegister() : map_reg; 492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateRestoreMap(transition, tmp, scratch2(), &miss); 493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (virtual_args) { 494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch RearrangeVectorAndSlot(tmp, map_reg); 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } else { 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopVectorAndSlot(); 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateRestoreName(name); 499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StoreTransitionStub stub(isolate(), 500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FieldIndex::ForDescriptor(*transition, descriptor), 501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier representation, store_mode); 502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateTailCall(masm(), stub.GetCode()); 503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateRestoreName(&miss, name); 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch PopVectorAndSlot(); 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TailCallBuiltin(masm(), MissBuiltin(kind())); 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, name); 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool NamedStoreHandlerCompiler::RequiresFieldTypeChecks( 513109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldType* field_type) const { 514109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch return field_type->IsClass(); 515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) { 519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label miss; 520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(it->representation().IsHeapObject()); 521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch FieldType* field_type = *it->GetFieldType(); 523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool need_save_restore = false; 524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (RequiresFieldTypeChecks(field_type)) { 525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch need_save_restore = IC::ICUseVector(kind()); 526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (need_save_restore) PushVectorAndSlot(); 527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateFieldTypeChecks(field_type, value(), &miss); 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (need_save_restore) PopVectorAndSlot(); 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation()); 532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GenerateTailCall(masm(), stub.GetCode()); 533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ bind(&miss); 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (need_save_restore) PopVectorAndSlot(); 536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TailCallBuiltin(masm(), MissBuiltin(kind())); 537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, it->name()); 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreViaSetter( 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Handle<JSObject> object, Handle<Name> name, int accessor_index, 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int expected_arguments) { 544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register holder = Frontend(name); 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateStoreViaSetter(masm(), map(), receiver(), holder, accessor_index, 546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch expected_arguments, scratch2()); 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, name); 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<JSObject> object, Handle<Name> name, 554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const CallOptimization& call_optimization, int accessor_index) { 555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Register holder = Frontend(name); 556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GenerateApiAccessorCall(masm(), call_optimization, handle(object->map()), 557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch receiver(), scratch2(), true, value(), holder, 558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch accessor_index); 559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetCode(kind(), Code::FAST, name); 560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __ 564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ElementHandlerCompiler::CompileElementHandlers( 566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch MapHandleList* receiver_maps, CodeHandleList* handlers) { 567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < receiver_maps->length(); ++i) { 568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Map> receiver_map = receiver_maps->at(i); 569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Code> cached_stub; 570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (receiver_map->IsStringMap()) { 572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cached_stub = LoadIndexedStringStub(isolate()).GetCode(); 573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (receiver_map->instance_type() < FIRST_JS_RECEIVER_TYPE) { 574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch cached_stub = isolate()->builtins()->KeyedLoadIC_Slow(); 575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind = receiver_map->elements_kind(); 578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // No need to check for an elements-free prototype chain here, the 580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // generated stub code needs to check that dynamically anyway. 581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool convert_hole_to_undefined = 582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch (is_js_array && elements_kind == FAST_HOLEY_ELEMENTS && 583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch *receiver_map == isolate()->get_initial_js_array_map(elements_kind)); 584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 5853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch if (receiver_map->has_indexed_interceptor() && 5863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch !receiver_map->GetIndexedInterceptor()->getter()->IsUndefined() && 5873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch !receiver_map->GetIndexedInterceptor()->non_masking()) { 588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cached_stub = LoadIndexedInterceptorStub(isolate()).GetCode(); 589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (IsSloppyArgumentsElements(elements_kind)) { 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cached_stub = KeyedLoadSloppyArgumentsStub(isolate()).GetCode(); 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (IsFastElementsKind(elements_kind) || 592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IsFixedTypedArrayElementsKind(elements_kind)) { 593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cached_stub = LoadFastElementStub(isolate(), is_js_array, elements_kind, 594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch convert_hole_to_undefined).GetCode(); 595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(elements_kind == DICTIONARY_ELEMENTS); 597109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch LoadICState state = LoadICState(kNoExtraICState); 598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch cached_stub = LoadDictionaryElementStub(isolate(), state).GetCode(); 599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch handlers->Add(cached_stub); 603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 607