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 286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "v8.h" 29b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 30b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "ast.h" 313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#include "code-stubs.h" 32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "compiler.h" 33b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "ic.h" 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "macro-assembler.h" 35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "stub-cache.h" 366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "type-info.h" 37b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 38b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "ic-inl.h" 396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block#include "objects-inl.h" 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 456ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockTypeInfo TypeInfo::TypeFromValue(Handle<Object> value) { 466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block TypeInfo info; 476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (value->IsSmi()) { 486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block info = TypeInfo::Smi(); 496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (value->IsHeapNumber()) { 506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block info = TypeInfo::IsInt32Double(HeapNumber::cast(*value)->value()) 516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ? TypeInfo::Integer32() 526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block : TypeInfo::Double(); 536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else if (value->IsString()) { 546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block info = TypeInfo::String(); 556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } else { 566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block info = TypeInfo::Unknown(); 576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return info; 596ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochTypeFeedbackOracle::TypeFeedbackOracle(Handle<Code> code, 633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Context> global_context, 643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Isolate* isolate) { 65b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch global_context_ = global_context; 663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_ = isolate; 673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch BuildDictionary(code); 6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(reinterpret_cast<Address>(*dictionary_.location()) != kHandleZapValue); 69b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 70b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 71b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 72257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) { 73257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int entry = dictionary_->FindEntry(ast_id); 74c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch return entry != UnseededNumberDictionary::kNotFound 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block ? Handle<Object>(dictionary_->ValueAt(entry)) 763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : Handle<Object>::cast(isolate_->factory()->undefined_value()); 773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) { 813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> map_or_code = GetInfo(expr->id()); 823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map_or_code->IsMap()) return false; 833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map_or_code->IsCode()) { 843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = Handle<Code>::cast(map_or_code); 853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; 863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return false; 885d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 895d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 905d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) { 923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> map_or_code = GetInfo(expr->id()); 9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (map_or_code->IsMap()) return true; 9444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (map_or_code->IsCode()) { 95257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> code = Handle<Code>::cast(map_or_code); 96257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return code->is_keyed_load_stub() && 97257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->ic_state() == MONOMORPHIC && 983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Code::ExtractTypeFromFlags(code->flags()) == NORMAL && 993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->FindFirstMap() != NULL && 1003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !CanRetainOtherContext(code->FindFirstMap(), *global_context_); 10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return false; 103b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 104b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 105b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool TypeFeedbackOracle::LoadIsMegamorphicWithTypeInfo(Property* expr) { 1073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> map_or_code = GetInfo(expr->id()); 1083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (map_or_code->IsCode()) { 1093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Code> code = Handle<Code>::cast(map_or_code); 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Builtins* builtins = isolate_->builtins(); 1113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return code->is_keyed_load_stub() && 1123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *code != builtins->builtin(Builtins::kKeyedLoadIC_Generic) && 1133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code->ic_state() == MEGAMORPHIC; 1143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 1163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 1173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool TypeFeedbackOracle::StoreIsMonomorphicNormal(Expression* expr) { 1203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> map_or_code = GetInfo(expr->id()); 12144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (map_or_code->IsMap()) return true; 12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (map_or_code->IsCode()) { 123257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> code = Handle<Code>::cast(map_or_code); 1243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool allow_growth = 1253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::GetKeyedAccessGrowMode(code->extra_ic_state()) == 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ALLOW_JSARRAY_GROWTH; 127257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return code->is_keyed_store_stub() && 1283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !allow_growth && 1293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code->ic_state() == MONOMORPHIC && 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::ExtractTypeFromFlags(code->flags()) == NORMAL && 1313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch code->FindFirstMap() != NULL && 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !CanRetainOtherContext(code->FindFirstMap(), *global_context_); 1333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 1343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return false; 1353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 1363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 1383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool TypeFeedbackOracle::StoreIsMegamorphicWithTypeInfo(Expression* expr) { 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> map_or_code = GetInfo(expr->id()); 1403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (map_or_code->IsCode()) { 1413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Code> code = Handle<Code>::cast(map_or_code); 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Builtins* builtins = isolate_->builtins(); 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch bool allow_growth = 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code::GetKeyedAccessGrowMode(code->extra_ic_state()) == 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ALLOW_JSARRAY_GROWTH; 1463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return code->is_keyed_store_stub() && 1473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !allow_growth && 1483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic) && 1493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch *code != builtins->builtin(Builtins::kKeyedStoreIC_Generic_Strict) && 1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code->ic_state() == MEGAMORPHIC; 15144f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 15244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return false; 153b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 154b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { 157257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> value = GetInfo(expr->id()); 1583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return value->IsMap() || value->IsSmi() || value->IsJSFunction(); 1593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew* expr) { 1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> value = GetInfo(expr->id()); 1643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return value->IsJSFunction(); 1653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic( 1693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectLiteral::Property* prop) { 1703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> map_or_code = GetInfo(prop->key()->id()); 1713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return map_or_code->IsMap(); 1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool TypeFeedbackOracle::IsForInFastCase(ForInStatement* stmt) { 1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> value = GetInfo(stmt->PrepareId()); 1773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return value->IsSmi() && 1783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Smi::cast(*value)->value() == TypeFeedbackCells::kForInFastCaseMarker; 1795d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 1805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 1815d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 182b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochHandle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) { 1833fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(LoadIsMonomorphicNormal(expr)); 1843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> map_or_code = GetInfo(expr->id()); 18544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (map_or_code->IsCode()) { 186257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> code = Handle<Code>::cast(map_or_code); 187257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Map* first_map = code->FindFirstMap(); 188257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(first_map != NULL); 1893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return CanRetainOtherContext(first_map, *global_context_) 1903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? Handle<Map>::null() 1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : Handle<Map>(first_map); 19244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 193257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return Handle<Map>::cast(map_or_code); 194b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 195b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 196b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 1978b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochHandle<Map> TypeFeedbackOracle::StoreMonomorphicReceiverType(Expression* expr) { 1983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(StoreIsMonomorphicNormal(expr)); 1993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> map_or_code = GetInfo(expr->id()); 20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (map_or_code->IsCode()) { 201257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> code = Handle<Code>::cast(map_or_code); 2023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* first_map = code->FindFirstMap(); 2033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(first_map != NULL); 2043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return CanRetainOtherContext(first_map, *global_context_) 2053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? Handle<Map>::null() 2063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : Handle<Map>(first_map); 20744f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 208257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return Handle<Map>::cast(map_or_code); 209b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 210b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 211b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 21269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid TypeFeedbackOracle::LoadReceiverTypes(Property* expr, 21369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> name, 21469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SmallMapList* types) { 215b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code::Flags flags = Code::ComputeMonomorphicFlags(Code::LOAD_IC, NORMAL); 21669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CollectReceiverTypes(expr->id(), name, flags, types); 217b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 218b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 219b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 22069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr, 22169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> name, 22269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SmallMapList* types) { 223b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Code::Flags flags = Code::ComputeMonomorphicFlags(Code::STORE_IC, NORMAL); 22469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CollectReceiverTypes(expr->id(), name, flags, types); 225b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 226b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 227b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 22869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid TypeFeedbackOracle::CallReceiverTypes(Call* expr, 22969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> name, 23069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CallKind call_kind, 23169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SmallMapList* types) { 232b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch int arity = expr->arguments()->length(); 233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 234257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Note: Currently we do not take string extra ic data into account 235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // here. 236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Code::ExtraICState extra_ic_state = 237257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CallIC::Contextual::encode(call_kind == CALL_AS_FUNCTION); 238257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 239b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch Code::Flags flags = Code::ComputeMonomorphicFlags(Code::CALL_IC, 240b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch NORMAL, 241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch extra_ic_state, 242b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch OWN_MAP, 243b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch arity); 24469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch CollectReceiverTypes(expr->id(), name, flags, types); 245b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 246b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 247b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 248b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochCheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { 249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> value = GetInfo(expr->id()); 250b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch if (!value->IsSmi()) return RECEIVER_MAP_CHECK; 251b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch CheckType check = static_cast<CheckType>(Smi::cast(*value)->value()); 252b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ASSERT(check != RECEIVER_MAP_CHECK); 253b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return check; 254b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 255b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 257b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben MurdochHandle<JSObject> TypeFeedbackOracle::GetPrototypeForPrimitiveCheck( 258b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch CheckType check) { 259b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch JSFunction* function = NULL; 260b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch switch (check) { 261b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch case RECEIVER_MAP_CHECK: 262b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch UNREACHABLE(); 263b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch break; 264b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch case STRING_CHECK: 265b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch function = global_context_->string_function(); 266b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch break; 267b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch case NUMBER_CHECK: 268b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch function = global_context_->number_function(); 269b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch break; 270b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch case BOOLEAN_CHECK: 271b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch function = global_context_->boolean_function(); 272b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch break; 273b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch } 274b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch ASSERT(function != NULL); 275b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch return Handle<JSObject>(JSObject::cast(function->instance_prototype())); 276b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch} 277b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 278b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 2793ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<JSFunction> TypeFeedbackOracle::GetCallTarget(Call* expr) { 2803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Handle<JSFunction>::cast(GetInfo(expr->id())); 2813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2843ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) { 2853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Handle<JSFunction>::cast(GetInfo(expr->id())); 2863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2893ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap( 2903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ObjectLiteral::Property* prop) { 2913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(ObjectLiteralStoreIsMonomorphic(prop)); 2923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Handle<Map>::cast(GetInfo(prop->key()->id())); 2933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) { 297257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return *GetInfo(expr->id()) == 2983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->builtins()->builtin(id); 299b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 300b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 301b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 3021e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockTypeInfo TypeFeedbackOracle::CompareType(CompareOperation* expr) { 303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> object = GetInfo(expr->id()); 304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TypeInfo unknown = TypeInfo::Unknown(); 305b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!object->IsCode()) return unknown; 306b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code = Handle<Code>::cast(object); 307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!code->is_compare_ic_stub()) return unknown; 308b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 309b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); 310b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch switch (state) { 311b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::UNINITIALIZED: 312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Uninitialized means never executed. 3133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return TypeInfo::Uninitialized(); 314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::SMIS: 315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Smi(); 316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::HEAP_NUMBERS: 317b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Number(); 318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case CompareIC::SYMBOLS: 319257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case CompareIC::STRINGS: 320257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return TypeInfo::String(); 321b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::OBJECTS: 3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CompareIC::KNOWN_OBJECTS: 323b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(kasperl): We really need a type for JS objects here. 324b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::NonPrimitive(); 325b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::GENERIC: 326b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch default: 327b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return unknown; 328b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 329b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 330b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 331b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool TypeFeedbackOracle::IsSymbolCompare(CompareOperation* expr) { 333257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> object = GetInfo(expr->id()); 334257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!object->IsCode()) return false; 335257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> code = Handle<Code>::cast(object); 336257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!code->is_compare_ic_stub()) return false; 337257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); 338257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return state == CompareIC::SYMBOLS; 339257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 340257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 341257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3423ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Map> TypeFeedbackOracle::GetCompareMap(CompareOperation* expr) { 3433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Object> object = GetInfo(expr->id()); 3443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!object->IsCode()) return Handle<Map>::null(); 3453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code> code = Handle<Code>::cast(object); 3463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!code->is_compare_ic_stub()) return Handle<Map>::null(); 3473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); 3483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (state != CompareIC::KNOWN_OBJECTS) { 3493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return Handle<Map>::null(); 3503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* first_map = code->FindFirstMap(); 3523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ASSERT(first_map != NULL); 3533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return CanRetainOtherContext(first_map, *global_context_) 3543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? Handle<Map>::null() 3553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : Handle<Map>(first_map); 3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 3573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 359257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTypeInfo TypeFeedbackOracle::UnaryType(UnaryOperation* expr) { 360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> object = GetInfo(expr->id()); 361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch TypeInfo unknown = TypeInfo::Unknown(); 362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!object->IsCode()) return unknown; 363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> code = Handle<Code>::cast(object); 364257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(code->is_unary_op_stub()); 365257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UnaryOpIC::TypeInfo type = static_cast<UnaryOpIC::TypeInfo>( 366257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->unary_op_type()); 367257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch switch (type) { 368257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case UnaryOpIC::SMI: 369257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return TypeInfo::Smi(); 370257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case UnaryOpIC::HEAP_NUMBER: 371257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return TypeInfo::Double(); 372257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch default: 373257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return unknown; 374257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 375257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 376257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 377257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 3781e0659c275bb392c045087af4f6b0d7565cb3d77Steve BlockTypeInfo TypeFeedbackOracle::BinaryType(BinaryOperation* expr) { 379257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> object = GetInfo(expr->id()); 380b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TypeInfo unknown = TypeInfo::Unknown(); 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!object->IsCode()) return unknown; 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code = Handle<Code>::cast(object); 383257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (code->is_binary_op_stub()) { 384257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>( 385257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->binary_op_type()); 386257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo result_type = static_cast<BinaryOpIC::TypeInfo>( 387257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->binary_op_result_type()); 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch switch (type) { 390257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::UNINITIALIZED: 391b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Uninitialized means never executed. 3923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch return TypeInfo::Uninitialized(); 393257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::SMI: 394b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch switch (result_type) { 395257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::UNINITIALIZED: 3963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (expr->op() == Token::DIV) { 3973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return TypeInfo::Double(); 3983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 3993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return TypeInfo::Smi(); 400257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::SMI: 401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Smi(); 402257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::INT32: 403b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Integer32(); 404257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::HEAP_NUMBER: 405b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Double(); 406b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch default: 407b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return unknown; 408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 409257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::INT32: 410b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (expr->op() == Token::DIV || 411257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch result_type == BinaryOpIC::HEAP_NUMBER) { 412b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Double(); 413b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 414b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Integer32(); 415257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::HEAP_NUMBER: 416b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Double(); 417257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::BOTH_STRING: 418257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return TypeInfo::String(); 419257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::STRING: 420257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::GENERIC: 421b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return unknown; 422b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch default: 423b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return unknown; 424b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 425b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return unknown; 427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 429b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch 430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben MurdochTypeInfo TypeFeedbackOracle::SwitchType(CaseClause* clause) { 431257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> object = GetInfo(clause->CompareId()); 432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch TypeInfo unknown = TypeInfo::Unknown(); 433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!object->IsCode()) return unknown; 434b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch Handle<Code> code = Handle<Code>::cast(object); 435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (!code->is_compare_ic_stub()) return unknown; 436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch CompareIC::State state = static_cast<CompareIC::State>(code->compare_state()); 438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch switch (state) { 439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::UNINITIALIZED: 440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Uninitialized means never executed. 441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(fschneider): Introduce a separate value for never-executed ICs. 442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return unknown; 443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::SMIS: 444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Smi(); 4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CompareIC::STRINGS: 4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return TypeInfo::String(); 4473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CompareIC::SYMBOLS: 4483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return TypeInfo::Symbol(); 449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::HEAP_NUMBERS: 450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::Number(); 451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::OBJECTS: 4523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case CompareIC::KNOWN_OBJECTS: 453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(kasperl): We really need a type for JS objects here. 454b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return TypeInfo::NonPrimitive(); 455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch case CompareIC::GENERIC: 456b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch default: 457b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return unknown; 458b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 462257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochTypeInfo TypeFeedbackOracle::IncrementType(CountOperation* expr) { 463257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> object = GetInfo(expr->CountId()); 464257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch TypeInfo unknown = TypeInfo::Unknown(); 465257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!object->IsCode()) return unknown; 466257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Code> code = Handle<Code>::cast(object); 467257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!code->is_binary_op_stub()) return unknown; 468257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 469257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch BinaryOpIC::TypeInfo type = static_cast<BinaryOpIC::TypeInfo>( 470257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch code->binary_op_type()); 471257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch switch (type) { 472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::UNINITIALIZED: 473257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::SMI: 474257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return TypeInfo::Smi(); 475257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::INT32: 476257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return TypeInfo::Integer32(); 477257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::HEAP_NUMBER: 478257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return TypeInfo::Double(); 479257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::BOTH_STRING: 480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::STRING: 481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch case BinaryOpIC::GENERIC: 482257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return unknown; 483257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch default: 484257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return unknown; 485257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 486257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch UNREACHABLE(); 487257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return unknown; 488257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 489257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 490257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 49169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid TypeFeedbackOracle::CollectReceiverTypes(unsigned ast_id, 49269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<String> name, 49369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Code::Flags flags, 49469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SmallMapList* types) { 495257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> object = GetInfo(ast_id); 49669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch if (object->IsUndefined() || object->IsSmi()) return; 497b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 4983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (*object == 4993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->builtins()->builtin(Builtins::kStoreIC_GlobalProxy)) { 500b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // TODO(fschneider): We could collect the maps and signal that 501b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // we need a generic store (or load) here. 502b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC); 503b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } else if (object->IsMap()) { 504b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch types->Add(Handle<Map>::cast(object)); 5053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (FLAG_collect_megamorphic_maps_from_stub_cache && 5063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<Code>::cast(object)->ic_state() == MEGAMORPHIC) { 50769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch types->Reserve(4); 508b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch ASSERT(object->IsCode()); 5093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch isolate_->stub_cache()->CollectMatchingMaps(types, 5103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *name, 5113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch flags, 5123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch global_context_); 5133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Check if a map originates from a given global context. We use this 5183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// information to filter out maps from different context to avoid 5193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// retaining objects from different tabs in Chrome via optimized code. 5203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool TypeFeedbackOracle::CanRetainOtherContext(Map* map, 5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Context* global_context) { 5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* constructor = NULL; 5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch while (!map->prototype()->IsNull()) { 5243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch constructor = map->constructor(); 5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!constructor->IsNull()) { 5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // If the constructor is not null or a JSFunction, we have to 5273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // conservatively assume that it may retain a global context. 5283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!constructor->IsJSFunction()) return true; 5293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Check if the constructor directly references a foreign context. 5303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (CanRetainOtherContext(JSFunction::cast(constructor), 5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch global_context)) { 5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return true; 5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch map = HeapObject::cast(map->prototype())->map(); 536592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch } 5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch constructor = map->constructor(); 5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (constructor->IsNull()) return false; 5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch JSFunction* function = JSFunction::cast(constructor); 5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return CanRetainOtherContext(function, global_context); 5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool TypeFeedbackOracle::CanRetainOtherContext(JSFunction* function, 5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Context* global_context) { 5463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch return function->context()->global() != global_context->global() 5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch && function->context()->global() != global_context->builtins(); 5483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 5493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 5513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochstatic void AddMapIfMissing(Handle<Map> map, SmallMapList* list) { 5523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < list->length(); ++i) { 5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (list->at(i).is_identical_to(map)) return; 5543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch list->Add(map); 556592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch} 557592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 558592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 55969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid TypeFeedbackOracle::CollectKeyedReceiverTypes(unsigned ast_id, 56069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch SmallMapList* types) { 5613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Object> object = GetInfo(ast_id); 5623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (!object->IsCode()) return; 5633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Handle<Code> code = Handle<Code>::cast(object); 5643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (code->kind() == Code::KEYED_LOAD_IC || 5653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch code->kind() == Code::KEYED_STORE_IC) { 5668b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch AssertNoAllocation no_allocation; 5673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 5683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (RelocIterator it(*code, mask); !it.done(); it.next()) { 5693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch RelocInfo* info = it.rinfo(); 5703fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* object = info->target_object(); 5713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch if (object->IsMap()) { 5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Map* map = Map::cast(object); 5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!CanRetainOtherContext(map, *global_context_)) { 5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch AddMapIfMissing(Handle<Map>(map), types); 5753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 576b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 5793fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 5803fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 5813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 58269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochbyte TypeFeedbackOracle::ToBooleanTypes(unsigned ast_id) { 58369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch Handle<Object> object = GetInfo(ast_id); 58469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch return object->IsCode() ? Handle<Code>::cast(object)->to_boolean_state() : 0; 58569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch} 58669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 58769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch 5883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// Things are a bit tricky here: The iterator for the RelocInfos and the infos 5893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// themselves are not GC-safe, so we first get all infos, then we create the 5903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// dictionary (possibly triggering GC), and finally we relocate the collected 5913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch// infos before we process them. 5923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid TypeFeedbackOracle::BuildDictionary(Handle<Code> code) { 5933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch AssertNoAllocation no_allocation; 5943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneList<RelocInfo> infos(16); 5953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch HandleScope scope; 5963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch GetRelocInfos(code, &infos); 5973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch CreateDictionary(code, &infos); 5983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ProcessRelocInfos(&infos); 5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ProcessTypeFeedbackCells(code); 60044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Allocate handle in the parent scope. 60144f0eee88ff00398ff7f715fab053374d808c90dSteve Block dictionary_ = scope.CloseAndEscape(dictionary_); 602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid TypeFeedbackOracle::GetRelocInfos(Handle<Code> code, 6063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneList<RelocInfo>* infos) { 607257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET_WITH_ID); 6083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (RelocIterator it(*code, mask); !it.done(); it.next()) { 6093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch infos->Add(*it.rinfo()); 6103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 6123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid TypeFeedbackOracle::CreateDictionary(Handle<Code> code, 6153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ZoneList<RelocInfo>* infos) { 6163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch DisableAssertNoAllocation allocation_allowed; 6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int cell_count = code->type_feedback_info()->IsTypeFeedbackInfo() 6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch ? TypeFeedbackInfo::cast(code->type_feedback_info())-> 6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch type_feedback_cells()->CellCount() 6203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch : 0; 6213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int length = infos->length() + cell_count; 6223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch byte* old_start = code->instruction_start(); 6233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch dictionary_ = FACTORY->NewUnseededNumberDictionary(length); 6243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch byte* new_start = code->instruction_start(); 6253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch RelocateRelocInfos(infos, old_start, new_start); 6263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 6273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid TypeFeedbackOracle::RelocateRelocInfos(ZoneList<RelocInfo>* infos, 6303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch byte* old_start, 6313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch byte* new_start) { 6323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < infos->length(); i++) { 6333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch RelocInfo* info = &(*infos)[i]; 6343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch info->set_pc(new_start + (info->pc() - old_start)); 6353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch } 6363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 6373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) { 6403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch for (int i = 0; i < infos->length(); i++) { 6413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch RelocInfo reloc_entry = (*infos)[i]; 6423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Address target_address = reloc_entry.target_address(); 6433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch unsigned ast_id = static_cast<unsigned>((*infos)[i].data()); 6443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Code* target = Code::GetCodeFromTargetAddress(target_address); 6453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch switch (target->kind()) { 6463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::LOAD_IC: 6473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::STORE_IC: 6483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::CALL_IC: 6493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::KEYED_CALL_IC: 6503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (target->ic_state() == MONOMORPHIC) { 6513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (target->kind() == Code::CALL_IC && 6523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target->check_type() != RECEIVER_MAP_CHECK) { 6533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetInfo(ast_id, Smi::FromInt(target->check_type())); 6543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else { 6553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* map = target->FindFirstMap(); 6563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (map == NULL) { 6573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetInfo(ast_id, static_cast<Object*>(target)); 6583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } else if (!CanRetainOtherContext(Map::cast(map), 6593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *global_context_)) { 6603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetInfo(ast_id, map); 6613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 66385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } else { 6643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetInfo(ast_id, target); 66585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch } 6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 6673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::KEYED_LOAD_IC: 6693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::KEYED_STORE_IC: 6703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (target->ic_state() == MONOMORPHIC || 6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch target->ic_state() == MEGAMORPHIC) { 6723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetInfo(ast_id, target); 6733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 675592a9fc1d8ea420377a2e7efd0600e20b058be2bBen Murdoch 6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::UNARY_OP_IC: 6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::BINARY_OP_IC: 6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::COMPARE_IC: 6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch case Code::TO_BOOLEAN_IC: 68085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch SetInfo(ast_id, target); 6813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 6833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch default: 6843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch break; 6853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 6873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 6883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 6893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 6903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> code) { 6913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* raw_info = code->type_feedback_info(); 6923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (!raw_info->IsTypeFeedbackInfo()) return; 6933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Handle<TypeFeedbackCells> cache( 6943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch TypeFeedbackInfo::cast(raw_info)->type_feedback_cells()); 6953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < cache->CellCount(); i++) { 6963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch unsigned ast_id = cache->AstId(i)->value(); 6973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Object* value = cache->Cell(i)->value(); 6983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (value->IsSmi() || 6993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (value->IsJSFunction() && 7003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch !CanRetainOtherContext(JSFunction::cast(value), 7013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch *global_context_))) { 7023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch SetInfo(ast_id, value); 7033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 7045d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch } 7055d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 7065d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 7075d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 7083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid TypeFeedbackOracle::SetInfo(unsigned ast_id, Object* target) { 709c7cc028aaeedbbfa11c11d0b7b243b3d9e837ed9Ben Murdoch ASSERT(dictionary_->FindEntry(ast_id) == UnseededNumberDictionary::kNotFound); 7103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch MaybeObject* maybe_result = dictionary_->AtNumberPut(ast_id, target); 7113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch USE(maybe_result); 7123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#ifdef DEBUG 7133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Object* result = NULL; 7143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch // Dictionary has been allocated with sufficient size for all elements. 7153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(maybe_result->ToObject(&result)); 7163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch ASSERT(*dictionary_ == result); 7173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch#endif 7183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch} 7193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch 7206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} } // namespace v8::internal 721