13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without 3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are 4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met: 5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions of source code must retain the above copyright 7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// notice, this list of conditions and the following disclaimer. 8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Redistributions in binary form must reproduce the above 9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// copyright notice, this list of conditions and the following 10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// disclaimer in the documentation and/or other materials provided 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with the distribution. 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// * Neither the name of Google Inc. nor the names of its 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// contributors may be used to endorse or promote products derived 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// from this software without specific prior written permission. 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h" 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arguments.h" 3269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch#include "ast.h" 333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "code-stubs.h" 34b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch#include "gdb-jit.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ic-inl.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "stub-cache.h" 37b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------- 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// StubCache implementation. 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockStubCache::StubCache(Isolate* isolate) : isolate_(isolate) { 4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate == Isolate::Current()); 4844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid StubCache::Initialize() { 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsPowerOf2(kPrimaryTableSize)); 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(IsPowerOf2(kSecondaryTableSize)); 543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Clear(); 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockCode* StubCache::Set(String* name, Map* map, Code* code) { 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Get the flags from the code. 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = Code::RemoveTypeFromFlags(code->flags()); 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Validate that the name does not move on scavenge, and that we 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // can use identity checks instead of string equality checks. 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!heap()->InNewSpace(name)); 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(name->IsSymbol()); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The state bits are not important to the hash function because 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the stub cache only contains monomorphic stubs. Make sure that 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the bits are the least significant so they will be the ones 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // masked out. 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Code::ExtractICStateFromFlags(flags) == MONOMORPHIC); 72589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch STATIC_ASSERT((Code::ICStateField::kMask & 1) == 1); 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure that the code type is not included in the hash. 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Code::ExtractTypeFromFlags(flags) == 0); 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the primary entry. 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int primary_offset = PrimaryOffset(name, flags, map); 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Entry* primary = entry(primary_, primary_offset); 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* old_code = primary->value; 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the primary entry has useful data in it, we retire it to the 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // secondary cache before overwriting it. 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (old_code != isolate_->builtins()->builtin(Builtins::kIllegal)) { 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* old_map = primary->map; 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags old_flags = Code::RemoveTypeFromFlags(old_code->flags()); 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int seed = PrimaryOffset(primary->key, old_flags, old_map); 883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int secondary_offset = SecondaryOffset(primary->key, old_flags, seed); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Entry* secondary = entry(secondary_, secondary_offset); 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *secondary = *primary; 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update primary cache. 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block primary->key = name; 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block primary->value = code; 963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch primary->map = map; 973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->counters()->megamorphic_stub_cache_updates()->Increment(); 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code; 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1023ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadNonexistent(Handle<String> name, 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver) { 1048defd9ff6930b4e24729971a61cf7469daf119beSteve Block ASSERT(receiver->IsGlobalObject() || receiver->HasFastProperties()); 1056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // If no global objects are present in the prototype chain, the load 1066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // nonexistent IC stub can be shared for all names for a given map 1076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // and we use the empty string for the map cache in that case. If 1086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // there are global objects involved, we need to check global 1096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // property cells in the stub and therefore the stub will be 1106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // specific to the name. 1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> cache_name = factory()->empty_string(); 1126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (receiver->IsGlobalObject()) cache_name = name; 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> last = receiver; 11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block while (last->GetPrototype() != heap()->null_value()) { 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch last = Handle<JSObject>(JSObject::cast(last->GetPrototype())); 1166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (last->IsGlobalObject()) cache_name = name; 1176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 1186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Compile the stub that is either shared for all names or 1196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // name specific if there are global objects involved. 1206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Code::Flags flags = 1216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Code::ComputeMonomorphicFlags(Code::LOAD_IC, NONEXISTENT); 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*cache_name, flags)); 1233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadStubCompiler compiler(isolate_); 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 1273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileLoadNonexistent(cache_name, receiver, last); 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *cache_name)); 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *cache_name, *code)); 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, cache_name, code); 1319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 1326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 1336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadField(Handle<String> name, 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder, 1385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck int field_index) { 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, FIELD); 1413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadStubCompiler compiler(isolate_); 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileLoadField(receiver, holder, field_index, name); 1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 1483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 1493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 1509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadCallback(Handle<String> name, 1553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 1563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder, 1573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<AccessorInfo> callback) { 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(v8::ToCData<Address>(callback->getter()) != 0); 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, CALLBACKS); 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadStubCompiler compiler(isolate_); 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileLoadCallback(name, receiver, holder, callback); 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 1709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadConstant(Handle<String> name, 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder, 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> value) { 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeMonomorphicFlags(Code::LOAD_IC, CONSTANT_FUNCTION); 1813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 1823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 1833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadStubCompiler compiler(isolate_); 1853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 1863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileLoadConstant(receiver, holder, value, name); 1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 1909dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadInterceptor(Handle<String> name, 1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 1963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder) { 1973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, INTERCEPTOR); 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 2013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadStubCompiler compiler(isolate_); 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileLoadInterceptor(receiver, holder, name); 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 2073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 2089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2123ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadNormal() { 2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return isolate_->builtins()->LoadIC_Normal(); 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2173ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeLoadGlobal(Handle<String> name, 2183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 2193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<GlobalObject> holder, 2203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSGlobalPropertyCell> cell, 2215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck bool is_dont_delete) { 2223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); 2243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 2253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 2263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch LoadStubCompiler compiler(isolate_); 2283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileLoadGlobal(receiver, holder, cell, name, is_dont_delete); 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 2339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2373ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadField(Handle<String> name, 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder, 2405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck int field_index) { 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, FIELD); 2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedLoadStubCompiler compiler(isolate_); 2473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileLoadField(name, receiver, holder, field_index); 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code; 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadConstant(Handle<String> name, 2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder, 2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> value) { 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CONSTANT_FUNCTION); 2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedLoadStubCompiler compiler(isolate_); 2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 2683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileLoadConstant(name, receiver, holder, value); 2693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 2703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 2713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code; 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2763ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadInterceptor(Handle<String> name, 2773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 2783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder) { 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, INTERCEPTOR); 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedLoadStubCompiler compiler(isolate_); 2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileLoadInterceptor(receiver, holder, name); 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code; 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadCallback( 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 2963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 2973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder, 2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<AccessorInfo> callback) { 2993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(IC::GetCodeCacheForObject(*receiver, *holder) == OWN_MAP); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 3023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 3033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 3043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedLoadStubCompiler compiler(isolate_); 3063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 3073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileLoadCallback(name, receiver, holder, callback); 3083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 3093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 3103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code; 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3153ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadArrayLength(Handle<String> name, 3163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSArray> receiver) { 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 3213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedLoadStubCompiler compiler(isolate_); 3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileLoadArrayLength(name); 3243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 3253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 3263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code; 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3313ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadStringLength(Handle<String> name, 3323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> receiver) { 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 3353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> map(receiver->map()); 3363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(map->FindInCodeCache(*name, flags)); 3373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 3383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedLoadStubCompiler compiler(isolate_); 3403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileLoadStringLength(name); 3413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map::UpdateCodeCache(map, name, code); 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code; 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadFunctionPrototype( 3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> receiver) { 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::ComputeMonomorphicFlags(Code::KEYED_LOAD_IC, CALLBACKS); 3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedLoadStubCompiler compiler(isolate_); 3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileLoadFunctionPrototype(name); 3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 3593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::KEYED_LOAD_IC, *name, *code)); 3603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code; 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3653ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreField(Handle<String> name, 3663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 3675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck int field_index, 3683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> transition, 369e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode) { 3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION; 3711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code::Flags flags = Code::ComputeMonomorphicFlags( 372e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Code::STORE_IC, type, strict_mode); 3733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 3743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 3753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StoreStubCompiler compiler(isolate_, strict_mode); 3773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileStoreField(receiver, field_index, transition, name); 3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 3829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3863ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedLoadOrStoreElement( 3873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 3883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedIC::StubKind stub_kind, 389257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch StrictModeFlag strict_mode) { 3903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedAccessGrowMode grow_mode = 3913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedIC::GetGrowModeFromStubKind(stub_kind); 3923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state = 3933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeExtraICState(grow_mode, strict_mode); 394257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::Flags flags = 395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::ComputeMonomorphicFlags( 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch stub_kind == KeyedIC::LOAD ? Code::KEYED_LOAD_IC 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : Code::KEYED_STORE_IC, 398257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch NORMAL, 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch extra_state); 4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name; 4013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (stub_kind) { 4023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case KeyedIC::LOAD: 4033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch name = isolate()->factory()->KeyedLoadElementMonomorphic_symbol(); 4043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case KeyedIC::STORE_NO_TRANSITION: 4063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch name = isolate()->factory()->KeyedStoreElementMonomorphic_symbol(); 4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case KeyedIC::STORE_AND_GROW_NO_TRANSITION: 4093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch name = isolate()->factory()->KeyedStoreAndGrowElementMonomorphic_symbol(); 4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> receiver_map(receiver->map()); 4163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver_map->FindInCodeCache(*name, flags)); 4173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 4183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code; 4203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (stub_kind) { 4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case KeyedIC::LOAD: { 4223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedLoadStubCompiler compiler(isolate_); 4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code = compiler.CompileLoadElement(receiver_map); 4243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case KeyedIC::STORE_AND_GROW_NO_TRANSITION: { 4273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedStoreStubCompiler compiler(isolate_, strict_mode, 4283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ALLOW_JSARRAY_GROWTH); 4293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code = compiler.CompileStoreElement(receiver_map); 4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case KeyedIC::STORE_NO_TRANSITION: { 4333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedStoreStubCompiler compiler(isolate_, strict_mode, 4343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DO_NOT_ALLOW_JSARRAY_GROWTH); 4353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code = compiler.CompileStoreElement(receiver_map); 4363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 4373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 4383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 4393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UNREACHABLE(); 4403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 441257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 4423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(!code.is_null()); 4443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (stub_kind == KeyedIC::LOAD) { 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, 0)); 447257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } else { 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, 0)); 4491e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block } 4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 4511e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block return code; 4521e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block} 4531e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4541e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block 4553ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreNormal(StrictModeFlag strict_mode) { 4563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (strict_mode == kStrictMode) 4573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? isolate_->builtins()->Builtins::StoreIC_Normal_Strict() 4583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : isolate_->builtins()->Builtins::StoreIC_Normal(); 4598defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 4608defd9ff6930b4e24729971a61cf7469daf119beSteve Block 4618defd9ff6930b4e24729971a61cf7469daf119beSteve Block 4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreGlobal(Handle<String> name, 4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<GlobalObject> receiver, 4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSGlobalPropertyCell> cell, 465e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode) { 4661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code::Flags flags = Code::ComputeMonomorphicFlags( 467e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Code::STORE_IC, NORMAL, strict_mode); 4683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 4693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 4703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StoreStubCompiler compiler(isolate_, strict_mode); 4723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileStoreGlobal(receiver, cell, name); 4733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 4743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 4753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 4769dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4803ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreCallback(Handle<String> name, 4813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 4823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<AccessorInfo> callback, 4833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode) { 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(v8::ToCData<Address>(callback->setter()) != 0); 4851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code::Flags flags = Code::ComputeMonomorphicFlags( 486e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Code::STORE_IC, CALLBACKS, strict_mode); 4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 4893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 4903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StoreStubCompiler compiler(isolate_, strict_mode); 4913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileStoreCallback(receiver, callback, name); 4923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 4933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 4943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 4959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeStoreInterceptor(Handle<String> name, 5003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 5013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StrictModeFlag strict_mode) { 5021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block Code::Flags flags = Code::ComputeMonomorphicFlags( 503e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Code::STORE_IC, INTERCEPTOR, strict_mode); 5043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StoreStubCompiler compiler(isolate_, strict_mode); 5083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileStoreInterceptor(receiver, name); 5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 5129dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeKeyedStoreField(Handle<String> name, 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 5175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck int field_index, 5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Map> transition, 519e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch StrictModeFlag strict_mode) { 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PropertyType type = (transition.is_null()) ? FIELD : MAP_TRANSITION; 521e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Code::Flags flags = Code::ComputeMonomorphicFlags( 522e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch Code::KEYED_STORE_IC, type, strict_mode); 5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(receiver->map()->FindInCodeCache(*name, flags)); 5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch KeyedStoreStubCompiler compiler(isolate(), strict_mode, 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DO_NOT_ALLOW_JSARRAY_GROWTH); 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileStoreField(receiver, field_index, transition, name); 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); 5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(receiver, name, code); 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return code; 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#define CALL_LOGGER_TAG(kind, type) \ 5387f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallConstant(int argc, 5415913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Code::Kind kind, 5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state, 5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> object, 5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder, 5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> function) { 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the check type and the map. 5488defd9ff6930b4e24729971a61cf7469daf119beSteve Block InlineCacheHolderFlag cache_holder = 5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IC::GetCodeCacheForObject(*object, *holder); 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute check type based on receiver/holder. 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CheckType check = RECEIVER_MAP_CHECK; 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsString()) { 555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch check = STRING_CHECK; 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (object->IsNumber()) { 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch check = NUMBER_CHECK; 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (object->IsBoolean()) { 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch check = BOOLEAN_CHECK; 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 5633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeMonomorphicFlags(kind, CONSTANT_FUNCTION, extra_state, 5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cache_holder, argc); 5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags)); 5663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 5673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileCallConstant(object, holder, function, name, check); 5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->set_check_type(check); 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(flags, code->flags()); 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 5763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(map_holder, name, code); 5779dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5813ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallField(int argc, 5825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Code::Kind kind, 5833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state, 5843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 5853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> object, 5863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder, 5875913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck int index) { 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the check type and the map. 5898defd9ff6930b4e24729971a61cf7469daf119beSteve Block InlineCacheHolderFlag cache_holder = 5903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IC::GetCodeCacheForObject(*object, *holder); 5913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // TODO(1233596): We cannot do receiver map check for non-JS objects 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // because they may be represented as immediates without a 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // map. Instead, we check against the map in the holder. 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block object = holder; 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 6013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeMonomorphicFlags(kind, FIELD, extra_state, 6023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cache_holder, argc); 6033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags)); 6043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 6053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStubCompiler compiler(isolate_, argc, kind, extra_state, cache_holder); 6073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 6083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileCallField(Handle<JSObject>::cast(object), 6093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch holder, index, name); 6103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(flags, code->flags()); 6113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate_, 6123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 6133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 6143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(map_holder, name, code); 6159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallInterceptor(int argc, 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Kind kind, 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state, 6223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> object, 6243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder) { 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Compute the check type and the map. 6268defd9ff6930b4e24729971a61cf7469daf119beSteve Block InlineCacheHolderFlag cache_holder = 6273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IC::GetCodeCacheForObject(*object, *holder); 6283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*object, cache_holder)); 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // TODO(1233596): We cannot do receiver map check for non-JS objects 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // because they may be represented as immediates without a 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // map. Instead, we check against the map in the holder. 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsNumber() || object->IsBoolean() || object->IsString()) { 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block object = holder; 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 6383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeMonomorphicFlags(kind, INTERCEPTOR, extra_state, 6393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cache_holder, argc); 6403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags)); 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileCallInterceptor(Handle<JSObject>::cast(object), 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch holder, name); 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(flags, code->flags()); 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate(), 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(map_holder, name, code); 6529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallGlobal(int argc, 6575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Code::Kind kind, 6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state, 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> receiver, 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<GlobalObject> holder, 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSGlobalPropertyCell> cell, 6633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> function) { 6648defd9ff6930b4e24729971a61cf7469daf119beSteve Block InlineCacheHolderFlag cache_holder = 6653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IC::GetCodeCacheForObject(*receiver, *holder); 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> map_holder(IC::GetCodeCacheHolder(*receiver, cache_holder)); 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeMonomorphicFlags(kind, NORMAL, extra_state, 6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cache_holder, argc); 6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> probe(map_holder->map()->FindInCodeCache(*name, flags)); 6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (probe->IsCode()) return Handle<Code>::cast(probe); 6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallStubCompiler compiler(isolate(), argc, kind, extra_state, cache_holder); 6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = 6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch compiler.CompileCallGlobal(receiver, holder, cell, function, name); 6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT_EQ(flags, code->flags()); 6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate(), 6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), *code, *name)); 6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_IC, *name, *code)); 6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSObject::UpdateMapCodeCache(map_holder, name, code); 6819dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return code; 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void FillCache(Isolate* isolate, Handle<Code> code) { 6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<UnseededNumberDictionary> dictionary = 6873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UnseededNumberDictionary::Set(isolate->factory()->non_monomorphic_cache(), 6883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->flags(), 6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code); 6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate->heap()->public_set_non_monomorphic_cache(*dictionary); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6947f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen MurdochCode* StubCache::FindCallInitialize(int argc, 695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode mode, 6967f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Code::Kind kind) { 697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::ExtraICState extra_state = 698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | 699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); 7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc); 7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Use raw_unchecked... so we don't get assert failures during GC. 7043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch UnseededNumberDictionary* dictionary = 7053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate()->heap()->raw_unchecked_non_monomorphic_cache(); 7063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = dictionary->FindEntry(isolate(), flags); 7073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(entry != -1); 7083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* code = dictionary->ValueAt(entry); 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This might be called during the marking phase of the collector 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // hence the unchecked cast. 7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return reinterpret_cast<Code*>(code); 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7153ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallInitialize(int argc, 716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch RelocInfo::Mode mode, 7175913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Code::Kind kind) { 718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::ExtraICState extra_state = 719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CallICBase::StringStubState::encode(DEFAULT_STRING_STUB) | 720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CallICBase::Contextual::encode(mode == RelocInfo::CODE_TARGET_CONTEXT); 7213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 7223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(kind, UNINITIALIZED, extra_state, NORMAL, argc); 7233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<UnseededNumberDictionary> cache = 7243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->factory()->non_monomorphic_cache(); 7253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = cache->FindEntry(isolate_, flags); 7263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubCompiler compiler(isolate_); 7293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileCallInitialize(flags); 7303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillCache(isolate_, code); 7313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7353ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallInitialize(int argc, RelocInfo::Mode mode) { 7363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ComputeCallInitialize(argc, mode, Code::CALL_IC); 7378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 7388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 7398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 740589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochHandle<Code> StubCache::ComputeKeyedCallInitialize(int argc) { 7413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return ComputeCallInitialize(argc, RelocInfo::CODE_TARGET, 7423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::KEYED_CALL_IC); 7438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang} 7448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 7458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang 7463ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallPreMonomorphic( 747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int argc, 748257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::Kind kind, 7493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state) { 7503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 7513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(kind, PREMONOMORPHIC, extra_state, NORMAL, argc); 7523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<UnseededNumberDictionary> cache = 7533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->factory()->non_monomorphic_cache(); 7543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = cache->FindEntry(isolate_, flags); 7553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 7563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubCompiler compiler(isolate_); 7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileCallPreMonomorphic(flags); 7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillCache(isolate_, code); 7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7643ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallNormal(int argc, 765257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::Kind kind, 7663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state) { 7673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 7683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(kind, MONOMORPHIC, extra_state, NORMAL, argc); 7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<UnseededNumberDictionary> cache = 7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->factory()->non_monomorphic_cache(); 7713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = cache->FindEntry(isolate_, flags); 7723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubCompiler compiler(isolate_); 7753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileCallNormal(flags); 7763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillCache(isolate_, code); 7773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7813ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallArguments(int argc, Code::Kind kind) { 7823fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(kind == Code::KEYED_CALL_IC); 7833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 7843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(kind, MEGAMORPHIC, Code::kNoExtraICState, 7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NORMAL, argc); 7863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<UnseededNumberDictionary> cache = 7873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->factory()->non_monomorphic_cache(); 7883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = cache->FindEntry(isolate_, flags); 7893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 7903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 7913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubCompiler compiler(isolate_); 7923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileCallArguments(flags); 7933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillCache(isolate_, code); 7943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 7953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 7963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7983ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallMegamorphic( 799257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int argc, 800257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::Kind kind, 8013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state) { 8023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 8033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(kind, MEGAMORPHIC, extra_state, 8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NORMAL, argc); 8053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<UnseededNumberDictionary> cache = 8063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->factory()->non_monomorphic_cache(); 8073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = cache->FindEntry(isolate_, flags); 8083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubCompiler compiler(isolate_); 8113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileCallMegamorphic(flags); 8123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillCache(isolate_, code); 8133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8173ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallMiss(int argc, 818257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::Kind kind, 8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state) { 8207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs 8217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // and monomorphic stubs are not mixed up together in the stub cache. 8223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(kind, MONOMORPHIC_PROTOTYPE_FAILURE, extra_state, 8243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NORMAL, argc, OWN_MAP); 8253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<UnseededNumberDictionary> cache = 8263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->factory()->non_monomorphic_cache(); 8273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = cache->FindEntry(isolate_, flags); 8283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 8293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubCompiler compiler(isolate_); 8313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileCallMiss(flags); 8323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillCache(isolate_, code); 8333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 8383ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallDebugBreak(int argc, 8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Kind kind) { 840257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Extra IC state is irrelevant for debug break ICs. They jump to 841257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // the actual call ic to carry out the work. 8423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 8433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(kind, DEBUG_BREAK, Code::kNoExtraICState, 8443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NORMAL, argc); 8453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<UnseededNumberDictionary> cache = 8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->factory()->non_monomorphic_cache(); 8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = cache->FindEntry(isolate_, flags); 8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubCompiler compiler(isolate_); 8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileCallDebugBreak(flags); 8523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillCache(isolate_, code); 8533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8573ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCache::ComputeCallDebugPrepareStepIn(int argc, 8583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Kind kind) { 859257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Extra IC state is irrelevant for debug break ICs. They jump to 860257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // the actual call ic to carry out the work. 8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags = 8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(kind, DEBUG_PREPARE_STEP_IN, Code::kNoExtraICState, 8633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch NORMAL, argc); 8643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<UnseededNumberDictionary> cache = 8653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->factory()->non_monomorphic_cache(); 8663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int entry = cache->FindEntry(isolate_, flags); 8673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry != -1) return Handle<Code>(Code::cast(cache->ValueAt(entry))); 8683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 8693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch StubCompiler compiler(isolate_); 8703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = compiler.CompileCallDebugPrepareStepIn(flags); 8713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FillCache(isolate_, code); 8723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StubCache::Clear() { 8783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* empty = isolate_->builtins()->builtin(Builtins::kIllegal); 879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int i = 0; i < kPrimaryTableSize; i++) { 88044f0eee88ff00398ff7f715fab053374d808c90dSteve Block primary_[i].key = heap()->empty_string(); 8813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch primary_[i].value = empty; 882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block for (int j = 0; j < kSecondaryTableSize; j++) { 88444f0eee88ff00398ff7f715fab053374d808c90dSteve Block secondary_[j].key = heap()->empty_string(); 8853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch secondary_[j].value = empty; 886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid StubCache::CollectMatchingMaps(SmallMapList* types, 891b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch String* name, 8923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::Flags flags, 8933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Context> global_context) { 894b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < kPrimaryTableSize; i++) { 895b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (primary_[i].key == name) { 896b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Map* map = primary_[i].value->FindFirstMap(); 897b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Map can be NULL, if the stub is constant function call 898b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // with a primitive receiver. 899b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (map == NULL) continue; 900b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 901b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset = PrimaryOffset(name, flags, map); 9023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry(primary_, offset) == &primary_[i] && 9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !TypeFeedbackOracle::CanRetainOtherContext(map, *global_context)) { 904b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch types->Add(Handle<Map>(map)); 905b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 906b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 907b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 908b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 909b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch for (int i = 0; i < kSecondaryTableSize; i++) { 910b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (secondary_[i].key == name) { 911b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Map* map = secondary_[i].value->FindFirstMap(); 912b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Map can be NULL, if the stub is constant function call 913b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // with a primitive receiver. 914b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (map == NULL) continue; 915b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 916b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Lookup in primary table and skip duplicates. 917b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int primary_offset = PrimaryOffset(name, flags, map); 918b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Entry* primary_entry = entry(primary_, primary_offset); 919b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (primary_entry->key == name) { 920b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Map* primary_map = primary_entry->value->FindFirstMap(); 921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (map == primary_map) continue; 922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 924b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Lookup in secondary table and add matches. 925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int offset = SecondaryOffset(name, flags, primary_offset); 9263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (entry(secondary_, offset) == &secondary_[i] && 9273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !TypeFeedbackOracle::CanRetainOtherContext(map, *global_context)) { 928b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch types->Add(Handle<Map>(map)); 929b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 930b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 931b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 932b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 933b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 934b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ------------------------------------------------------------------------ 936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// StubCompiler implementation. 937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9398b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, LoadCallbackProperty) { 940d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(args[0]->IsJSObject()); 941d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block ASSERT(args[1]->IsJSObject()); 9428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang AccessorInfo* callback = AccessorInfo::cast(args[3]); 943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address getter_address = v8::ToCData<Address>(callback->getter()); 944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::AccessorGetter fun = FUNCTION_CAST<v8::AccessorGetter>(getter_address); 945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(fun != NULL); 9468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang v8::AccessorInfo info(&args[0]); 94744f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate); 948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> result; 949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Leaving JavaScript. 95144f0eee88ff00398ff7f715fab053374d808c90dSteve Block VMState state(isolate, EXTERNAL); 95244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalCallbackScope call_scope(isolate, getter_address); 953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = fun(v8::Utils::ToLocal(args.at<String>(4)), info); 954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 95544f0eee88ff00398ff7f715fab053374d808c90dSteve Block RETURN_IF_SCHEDULED_EXCEPTION(isolate); 95644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (result.IsEmpty()) return HEAP->undefined_value(); 957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *v8::Utils::OpenHandle(*result); 958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9618b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, StoreCallbackProperty) { 962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* recv = JSObject::cast(args[0]); 963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block AccessorInfo* callback = AccessorInfo::cast(args[1]); 964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address setter_address = v8::ToCData<Address>(callback->setter()); 965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address); 966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(fun != NULL); 967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name = args.at<String>(2); 968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> value = args.at<Object>(3); 96944f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate); 97044f0eee88ff00398ff7f715fab053374d808c90dSteve Block LOG(isolate, ApiNamedPropertyAccess("store", recv, *name)); 97144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CustomArguments custom_args(isolate, callback->data(), recv, recv); 972a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::AccessorInfo info(custom_args.end()); 973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Leaving JavaScript. 97544f0eee88ff00398ff7f715fab053374d808c90dSteve Block VMState state(isolate, EXTERNAL); 97644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalCallbackScope call_scope(isolate, setter_address); 977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block fun(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), info); 978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 97944f0eee88ff00398ff7f715fab053374d808c90dSteve Block RETURN_IF_SCHEDULED_EXCEPTION(isolate); 980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *value; 981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 9836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 9846ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockstatic const int kAccessorInfoOffsetInInterceptorArgs = 2; 9856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 9866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/** 988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Attempts to load a property with an interceptor (which must be present), 989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * but doesn't search the prototype chain. 990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * 991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't 992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * provide any value for the given name. 993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 9948b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorOnly) { 9956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> name_handle = args.at<String>(0); 9966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>(1); 9976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); 9986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(args[2]->IsJSObject()); // Receiver. 9996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(args[3]->IsJSObject()); // Holder. 10006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(args.length() == 5); // Last arg is data object. 1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); 1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::NamedPropertyGetter getter = 1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address); 1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(getter != NULL); 1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use the interceptor getter. 10096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::AccessorInfo info(args.arguments() - 10106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kAccessorInfoOffsetInInterceptorArgs); 101144f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate); 1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> r; 1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 1014a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Leaving JavaScript. 101544f0eee88ff00398ff7f715fab053374d808c90dSteve Block VMState state(isolate, EXTERNAL); 1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block r = getter(v8::Utils::ToLocal(name_handle), info); 1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 101844f0eee88ff00398ff7f715fab053374d808c90dSteve Block RETURN_IF_SCHEDULED_EXCEPTION(isolate); 1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!r.IsEmpty()) { 1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *v8::Utils::OpenHandle(*r); 1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->heap()->no_interceptor_result_sentinel(); 1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckstatic MaybeObject* ThrowReferenceError(String* name) { 1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the load is non-contextual, just return the undefined result. 1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Note that both keyed and non-keyed loads may end up here, so we 1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // can't use either LoadIC or KeyedLoadIC constructors. 103244f0eee88ff00398ff7f715fab053374d808c90dSteve Block IC ic(IC::NO_EXTRA_FRAME, Isolate::Current()); 1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(ic.target()->is_load_stub() || ic.target()->is_keyed_load_stub()); 103444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (!ic.SlowIsContextual()) return HEAP->undefined_value(); 1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Throw a reference error. 1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> name_handle(name); 1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> error = 104044f0eee88ff00398ff7f715fab053374d808c90dSteve Block FACTORY->NewReferenceError("not_defined", 1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleVector(&name_handle, 1)); 104244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current()->Throw(*error); 1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckstatic MaybeObject* LoadWithInterceptor(Arguments* args, 10475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck PropertyAttributes* attrs) { 10486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<String> name_handle = args->at<String>(0); 10496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<InterceptorInfo> interceptor_info = args->at<InterceptorInfo>(1); 10506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(kAccessorInfoOffsetInInterceptorArgs == 2); 10516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSObject> receiver_handle = args->at<JSObject>(2); 10526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Handle<JSObject> holder_handle = args->at<JSObject>(3); 10536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(args->length() == 5); // Last arg is data object. 1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 105544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = receiver_handle->GetIsolate(); 105644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); 1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::NamedPropertyGetter getter = 1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address); 1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(getter != NULL); 1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Use the interceptor getter. 10646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::AccessorInfo info(args->arguments() - 10656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block kAccessorInfoOffsetInInterceptorArgs); 106644f0eee88ff00398ff7f715fab053374d808c90dSteve Block HandleScope scope(isolate); 1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::Value> r; 1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Leaving JavaScript. 107044f0eee88ff00398ff7f715fab053374d808c90dSteve Block VMState state(isolate, EXTERNAL); 1071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block r = getter(v8::Utils::ToLocal(name_handle), info); 1072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 107344f0eee88ff00398ff7f715fab053374d808c90dSteve Block RETURN_IF_SCHEDULED_EXCEPTION(isolate); 1074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!r.IsEmpty()) { 1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *attrs = NONE; 1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return *v8::Utils::OpenHandle(*r); 1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 10805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* result = holder_handle->GetPropertyPostInterceptor( 1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *receiver_handle, 1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *name_handle, 1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block attrs); 108444f0eee88ff00398ff7f715fab053374d808c90dSteve Block RETURN_IF_SCHEDULED_EXCEPTION(isolate); 1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/** 1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Loads a property with an interceptor performing post interceptor 1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * lookup if interceptor failed. 1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */ 10938b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForLoad) { 1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PropertyAttributes attr = NONE; 10955913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Object* result; 10965913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck { MaybeObject* maybe_result = LoadWithInterceptor(&args, &attr); 10975913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!maybe_result->ToObject(&result)) return maybe_result; 10985913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the property is present, return it. 1101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (attr != ABSENT) return result; 11026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return ThrowReferenceError(String::cast(args[0])); 1103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11068b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) { 1107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PropertyAttributes attr; 11085913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* result = LoadWithInterceptor(&args, &attr); 110944f0eee88ff00398ff7f715fab053374d808c90dSteve Block RETURN_IF_SCHEDULED_EXCEPTION(isolate); 1110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This is call IC. In this case, we simply return the undefined result which 1111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // will lead to an exception when trying to invoke the result as a 1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // function. 1113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11178b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { 1118e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch ASSERT(args.length() == 4); 1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSObject* recv = JSObject::cast(args[0]); 1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block String* name = String::cast(args[1]); 1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* value = args[2]; 11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode); 11233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3)); 1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(recv->HasNamedInterceptor()); 1125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block PropertyAttributes attr = NONE; 1126e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch MaybeObject* result = recv->SetPropertyWithInterceptor( 1127e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch name, value, attr, strict_mode); 1128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 1129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11328b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochRUNTIME_FUNCTION(MaybeObject*, KeyedLoadPropertyWithInterceptor) { 1133402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu JSObject* receiver = JSObject::cast(args[0]); 11343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(args.smi_at(1) >= 0); 11353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch uint32_t index = args.smi_at(1); 1136402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu return receiver->GetElementWithInterceptor(receiver, index); 1137402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu} 1138402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 1139402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 11403ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallInitialize(Code::Flags flags) { 1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc = Code::ExtractArgumentsCountFromFlags(flags); 11427f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Code::Kind kind = Code::ExtractKindFromFlags(flags); 11433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); 11447f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (kind == Code::CALL_IC) { 11453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallIC::GenerateInitialize(masm(), argc, extra_state); 11467f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 11477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch KeyedCallIC::GenerateInitialize(masm(), argc); 11487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 11493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, "CompileCallInitialize"); 115044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->counters()->call_initialize_stubs()->Increment(); 115144f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate(), 115244f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_INITIALIZE_TAG), 11533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *code, code->arguments_count())); 11543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_INITIALIZE, *code)); 11553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11593ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallPreMonomorphic(Code::Flags flags) { 1160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc = Code::ExtractArgumentsCountFromFlags(flags); 1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The code of the PreMonomorphic stub is the same as the code 1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // of the Initialized stub. They just differ on the code object flags. 11637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Code::Kind kind = Code::ExtractKindFromFlags(flags); 11643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); 11657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (kind == Code::CALL_IC) { 11663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallIC::GenerateInitialize(masm(), argc, extra_state); 11677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 11687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch KeyedCallIC::GenerateInitialize(masm(), argc); 11697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 11703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, "CompileCallPreMonomorphic"); 117144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->counters()->call_premonomorphic_stubs()->Increment(); 117244f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate(), 117344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_PRE_MONOMORPHIC_TAG), 11743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *code, code->arguments_count())); 11753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_PRE_MONOMORPHIC, *code)); 11763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 11803ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallNormal(Code::Flags flags) { 1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc = Code::ExtractArgumentsCountFromFlags(flags); 11827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Code::Kind kind = Code::ExtractKindFromFlags(flags); 11837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (kind == Code::CALL_IC) { 1184257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Call normal is always with a explict receiver. 1185257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(!CallIC::Contextual::decode( 1186257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::ExtractExtraICStateFromFlags(flags))); 11877f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CallIC::GenerateNormal(masm(), argc); 11887f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 11897f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch KeyedCallIC::GenerateNormal(masm(), argc); 11907f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 11913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, "CompileCallNormal"); 119244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->counters()->call_normal_stubs()->Increment(); 119344f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate(), 119444f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_NORMAL_TAG), 11953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *code, code->arguments_count())); 11963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_NORMAL, *code)); 11973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12013ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallMegamorphic(Code::Flags flags) { 1202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc = Code::ExtractArgumentsCountFromFlags(flags); 12037f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Code::Kind kind = Code::ExtractKindFromFlags(flags); 12043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); 12057f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (kind == Code::CALL_IC) { 12063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallIC::GenerateMegamorphic(masm(), argc, extra_state); 12077f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 12087f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch KeyedCallIC::GenerateMegamorphic(masm(), argc); 12097f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 12103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMegamorphic"); 121144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->counters()->call_megamorphic_stubs()->Increment(); 121244f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate(), 121344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), 12143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *code, code->arguments_count())); 12153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code)); 12163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12203ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallArguments(Code::Flags flags) { 12213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int argc = Code::ExtractArgumentsCountFromFlags(flags); 12223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch KeyedCallIC::GenerateNonStrictArguments(masm(), argc); 12233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, "CompileCallArguments"); 12243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch PROFILE(isolate(), 12253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags), 12263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CALL_MEGAMORPHIC_TAG), 12273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *code, code->arguments_count())); 12283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_MEGAMORPHIC, *code)); 12293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 12303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 12313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 12333ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallMiss(Code::Flags flags) { 1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc = Code::ExtractArgumentsCountFromFlags(flags); 12357f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Code::Kind kind = Code::ExtractKindFromFlags(flags); 12363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state = Code::ExtractExtraICStateFromFlags(flags); 12377f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (kind == Code::CALL_IC) { 12383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CallIC::GenerateMiss(masm(), argc, extra_state); 12397f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 12407f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch KeyedCallIC::GenerateMiss(masm(), argc); 12417f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 12423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, "CompileCallMiss"); 124344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate()->counters()->call_megamorphic_stubs()->Increment(); 124444f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate(), 124544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MISS_TAG), 12463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *code, code->arguments_count())); 12473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::CALL_MISS, *code)); 12483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 12533ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallDebugBreak(Code::Flags flags) { 1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debug::GenerateCallICDebugBreak(masm()); 12553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugBreak"); 125644f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate(), 12573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CodeCreateEvent(CALL_LOGGER_TAG(Code::ExtractKindFromFlags(flags), 12583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CALL_DEBUG_BREAK_TAG), 12593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *code, code->arguments_count())); 12603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { 12653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Use the same code for the the step in preparations as we do for the 12663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // miss case. 1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc = Code::ExtractArgumentsCountFromFlags(flags); 12687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Code::Kind kind = Code::ExtractKindFromFlags(flags); 12697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch if (kind == Code::CALL_IC) { 1270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // For the debugger extra ic state is irrelevant. 1271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CallIC::GenerateMiss(masm(), argc, Code::kNoExtraICState); 12727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } else { 12737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch KeyedCallIC::GenerateMiss(masm(), argc); 12747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 12753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); 127644f0eee88ff00398ff7f715fab053374d808c90dSteve Block PROFILE(isolate(), 127744f0eee88ff00398ff7f715fab053374d808c90dSteve Block CodeCreateEvent( 127844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CALL_LOGGER_TAG(kind, CALL_DEBUG_PREPARE_STEP_IN_TAG), 12793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *code, 128044f0eee88ff00398ff7f715fab053374d808c90dSteve Block code->arguments_count())); 12813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 12833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#endif // ENABLE_DEBUGGER_SUPPORT 1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch#undef CALL_LOGGER_TAG 1286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 128785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 12883ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, 12893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch const char* name) { 1290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Create code object in the heap. 1291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block CodeDesc desc; 1292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block masm_.GetCode(&desc); 12933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject()); 1294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DISASSEMBLER 12953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_print_code_stubs) code->Disassemble(name); 1296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 12973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13013ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags, 13023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name) { 13033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return (FLAG_print_code_stubs && !name.is_null()) 13043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? GetCodeWithFlags(flags, *name->ToCString()) 13053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : GetCodeWithFlags(flags, reinterpret_cast<char*>(NULL)); 1306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1308402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu 13093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid StubCompiler::LookupPostInterceptor(Handle<JSObject> holder, 13103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 13114515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke LookupResult* lookup) { 13123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch holder->LocalLookupRealNamedProperty(*name, lookup); 13133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (lookup->IsProperty()) return; 13144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke 13153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch lookup->NotFound(); 13163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (holder->GetPrototype()->IsNull()) return; 1317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch holder->GetPrototype()->Lookup(*name, lookup); 13193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 132085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 13213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 13223ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> LoadStubCompiler::GetCode(PropertyType type, Handle<String> name) { 1323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, type); 13243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, name); 13253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate(), CodeCreateEvent(Logger::LOAD_IC_TAG, *code, *name)); 13263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 13273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13313ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> KeyedLoadStubCompiler::GetCode(PropertyType type, 13323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 1333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InlineCacheState state) { 1334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::Flags flags = Code::ComputeFlags( 1335589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Code::KEYED_LOAD_IC, state, Code::kNoExtraICState, type); 13363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, name); 13373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, *code, *name)); 13383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::LOAD_IC, *name, *code)); 13393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13433ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> StoreStubCompiler::GetCode(PropertyType type, 13443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name) { 1345589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Code::Flags flags = 1346589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Code::ComputeMonomorphicFlags(Code::STORE_IC, type, strict_mode_); 13473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, name); 13483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate(), CodeCreateEvent(Logger::STORE_IC_TAG, *code, *name)); 13493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::STORE_IC, *name, *code)); 13503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13543ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> KeyedStoreStubCompiler::GetCode(PropertyType type, 13553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> name, 1356257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch InlineCacheState state) { 13573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state = 13583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeExtraICState(grow_mode_, strict_mode_); 1359589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch Code::Flags flags = 13603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ComputeFlags(Code::KEYED_STORE_IC, state, extra_state, type); 13613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, name); 13623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate(), CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, *code, *name)); 13633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::KEYED_STORE_IC, *name, *code)); 13643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 13683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid KeyedStoreStubCompiler::GenerateStoreDictionaryElement( 13693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MacroAssembler* masm) { 13703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch KeyedStoreIC::GenerateSlow(masm); 13713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 13723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 13733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 13743ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCallStubCompiler::CallStubCompiler(Isolate* isolate, 13753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int argc, 13768defd9ff6930b4e24729971a61cf7469daf119beSteve Block Code::Kind kind, 13773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtraICState extra_state, 13788defd9ff6930b4e24729971a61cf7469daf119beSteve Block InlineCacheHolderFlag cache_holder) 13793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : StubCompiler(isolate), 13803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch arguments_(argc), 1381b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch kind_(kind), 13823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch extra_state_(extra_state), 1383b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch cache_holder_(cache_holder) { 13848defd9ff6930b4e24729971a61cf7469daf119beSteve Block} 13858defd9ff6930b4e24729971a61cf7469daf119beSteve Block 13868defd9ff6930b4e24729971a61cf7469daf119beSteve Block 13873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool CallStubCompiler::HasCustomCallGenerator(Handle<JSFunction> function) { 13883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (function->shared()->HasBuiltinFunctionId()) { 13893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BuiltinFunctionId id = function->shared()->builtin_function_id(); 1390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#define CALL_GENERATOR_CASE(name) if (id == k##name) return true; 139144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) 1392b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#undef CALL_GENERATOR_CASE 139344f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 13943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 139544f0eee88ff00398ff7f715fab053374d808c90dSteve Block CallOptimization optimization(function); 13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return optimization.is_simple_api_call(); 1397b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 1398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1399b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 14003ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> CallStubCompiler::CompileCustomCall( 14013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> object, 14023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder, 14033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSGlobalPropertyCell> cell, 14043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSFunction> function, 14053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> fname) { 140644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(HasCustomCallGenerator(function)); 140744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 14083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (function->shared()->HasBuiltinFunctionId()) { 14093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch BuiltinFunctionId id = function->shared()->builtin_function_id(); 14103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define CALL_GENERATOR_CASE(name) \ 14113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (id == k##name) { \ 14123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return CallStubCompiler::Compile##name##Call(object, \ 14133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch holder, \ 14143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch cell, \ 14153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function, \ 14163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch fname); \ 141744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 141844f0eee88ff00398ff7f715fab053374d808c90dSteve Block CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) 141925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen#undef CALL_GENERATOR_CASE 142044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 142144f0eee88ff00398ff7f715fab053374d808c90dSteve Block CallOptimization optimization(function); 142244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(optimization.is_simple_api_call()); 142344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return CompileFastApiCall(optimization, 142444f0eee88ff00398ff7f715fab053374d808c90dSteve Block object, 142544f0eee88ff00398ff7f715fab053374d808c90dSteve Block holder, 142644f0eee88ff00398ff7f715fab053374d808c90dSteve Block cell, 142744f0eee88ff00398ff7f715fab053374d808c90dSteve Block function, 142844f0eee88ff00398ff7f715fab053374d808c90dSteve Block fname); 142925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen} 143025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 143125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 14323ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> CallStubCompiler::GetCode(PropertyType type, Handle<String> name) { 1433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc = arguments_.immediate(); 14347f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, 1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block type, 14363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch extra_state_, 14378defd9ff6930b4e24729971a61cf7469daf119beSteve Block cache_holder_, 1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block argc); 1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return GetCodeWithFlags(flags, name); 1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14433ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> CallStubCompiler::GetCode(Handle<JSFunction> function) { 14443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<String> function_name; 144525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen if (function->shared()->name()->IsString()) { 14463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch function_name = Handle<String>(String::cast(function->shared()->name())); 144725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen } 144825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen return GetCode(CONSTANT_FUNCTION, function_name); 144925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen} 145025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 145125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen 14523ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Code> ConstructStubCompiler::GetCode() { 1453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Code::Flags flags = Code::ComputeFlags(Code::STUB); 14543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = GetCodeWithFlags(flags, "ConstructStub"); 14553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch PROFILE(isolate(), CodeCreateEvent(Logger::STUB_TAG, *code, "ConstructStub")); 14563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch GDBJIT(AddCode(GDBJITInterface::STUB, "ConstructStub", *code)); 14573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code; 1458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 1459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14616ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockCallOptimization::CallOptimization(LookupResult* lookup) { 14623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (lookup->IsFound() && 14633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch lookup->IsCacheable() && 14643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch lookup->type() == CONSTANT_FUNCTION) { 146585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch // We only optimize constant function calls. 14663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Initialize(Handle<JSFunction>(lookup->GetConstantFunction())); 14673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 14683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Initialize(Handle<JSFunction>::null()); 14696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 14706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 14716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14723ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochCallOptimization::CallOptimization(Handle<JSFunction> function) { 14736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block Initialize(function); 14746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 14756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochint CallOptimization::GetPrototypeDepthOfExpectedType( 14783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> object, 14793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<JSObject> holder) const { 14803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(is_simple_api_call()); 14813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expected_receiver_type_.is_null()) return 0; 14826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block int depth = 0; 14833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!object.is_identical_to(holder)) { 14843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (object->IsInstanceOf(*expected_receiver_type_)) return depth; 14853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch object = Handle<JSObject>(JSObject::cast(object->GetPrototype())); 14866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ++depth; 14876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 14883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (holder->IsInstanceOf(*expected_receiver_type_)) return depth; 14896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return kInvalidProtoDepth; 14906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 14916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14926ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid CallOptimization::Initialize(Handle<JSFunction> function) { 14943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch constant_function_ = Handle<JSFunction>::null(); 14956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block is_simple_api_call_ = false; 14963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch expected_receiver_type_ = Handle<FunctionTemplateInfo>::null(); 14973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch api_call_info_ = Handle<CallHandlerInfo>::null(); 14986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 14993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (function.is_null() || !function->is_compiled()) return; 15006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block constant_function_ = function; 15026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block AnalyzePossibleApiFunction(function); 15036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 15046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid CallOptimization::AnalyzePossibleApiFunction(Handle<JSFunction> function) { 15073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!function->shared()->IsApiFunction()) return; 15083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FunctionTemplateInfo> info(function->shared()->get_api_func_data()); 15096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Require a C++ callback. 15116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (info->call_code()->IsUndefined()) return; 15123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch api_call_info_ = 15133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<CallHandlerInfo>(CallHandlerInfo::cast(info->call_code())); 15146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // Accept signatures that either have no restrictions at all or 15166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // only have restrictions on the receiver. 15176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!info->signature()->IsUndefined()) { 15183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<SignatureInfo> signature = 15193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<SignatureInfo>(SignatureInfo::cast(info->signature())); 15206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!signature->args()->IsUndefined()) return; 15216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!signature->receiver()->IsUndefined()) { 15226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block expected_receiver_type_ = 15233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<FunctionTemplateInfo>( 15243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch FunctionTemplateInfo::cast(signature->receiver())); 15256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 15266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 15276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block is_simple_api_call_ = true; 15296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 15306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 15316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 1533