12efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "accessors.h" 3143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "api.h" 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "arguments.h" 33a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org#include "codegen.h" 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "execution.h" 3543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "ic-inl.h" 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "runtime.h" 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "stub-cache.h" 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 4071affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifdef DEBUG 4364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgchar IC::TransitionMarkFromState(IC::State state) { 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (state) { 4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case UNINITIALIZED: return '0'; 4659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case PREMONOMORPHIC: return '.'; 4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case MONOMORPHIC: return '1'; 4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case MONOMORPHIC_PROTOTYPE_FAILURE: return '^'; 4959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case POLYMORPHIC: return 'P'; 5046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org case MEGAMORPHIC: return 'N'; 5146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org case GENERIC: return 'G'; 5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We never see the debugger states here, because the state is 5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // computed from the original code - not the patched code. Let 5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // these cases fall through to the unreachable code below. 569768bf12a67dd4585cf1a62928708883161f64c3yangguo@chromium.org case DEBUG_STUB: break; 5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 62750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 63750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgconst char* GetTransitionMarkModifier(KeyedAccessStoreMode mode) { 64750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (mode == STORE_NO_TRANSITION_HANDLE_COW) return ".COW"; 65750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 66750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return ".IGNORE_OOB"; 67750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 68750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (IsGrowStoreMode(mode)) return ".GROW"; 69750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return ""; 70750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 71750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 72750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid IC::TraceIC(const char* type, 74d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> name) { 7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_trace_ic) { 76d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Code* new_target = raw_target(); 77fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org State new_state = new_target->ic_state(); 78d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type); 79fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org StackFrameIterator it(isolate()); 80ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org while (it.frame()->fp() != this->fp()) it.Advance(); 81ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org StackFrame* raw_frame = it.frame(); 82ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org if (raw_frame->is_internal()) { 83fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Code* apply_builtin = isolate()->builtins()->builtin( 84ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Builtins::kFunctionApply); 85ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org if (raw_frame->unchecked_code() == apply_builtin) { 86ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org PrintF("apply from "); 87ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org it.Advance(); 88ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org raw_frame = it.frame(); 89ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 90ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 91fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 92cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExtraICState extra_state = new_target->extra_ic_state(); 93750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org const char* modifier = 94cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org GetTransitionMarkModifier( 95cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org KeyedStoreIC::GetKeyedAccessStoreMode(extra_state)); 9665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org PrintF(" (%c->%c%s)", 97fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org TransitionMarkFromState(state()), 9865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org TransitionMarkFromState(new_state), 99750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org modifier); 10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen name->Print(); 10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PrintF("]\n"); 10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 104394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 105c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org#define TRACE_GENERIC_IC(isolate, type, reason) \ 10664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org do { \ 10764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (FLAG_trace_ic) { \ 10864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org PrintF("[%s patching generic stub in ", type); \ 109c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org JavaScriptFrame::PrintTop(isolate, stdout, false, true); \ 11064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org PrintF(" (%s)]\n", reason); \ 11164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } \ 11264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } while (false) 11364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org 11464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#else 115c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org#define TRACE_GENERIC_IC(isolate, type, reason) 11664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org#endif // DEBUG 117394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 118d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org#define TRACE_IC(type, name) \ 119d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT((TraceIC(type, name), true)) 12043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 121c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgIC::IC(FrameDepth depth, Isolate* isolate) 122c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org : isolate_(isolate), 123c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org target_set_(false) { 124e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // To improve the performance of the (much used) IC code, we unfold a few 125e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // levels of the stack frame iteration code. This yields a ~35% speedup when 126e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. 127e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org const Address entry = 128e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org Isolate::c_entry_fp(isolate->thread_local_top()); 129e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org Address* pc_address = 130e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); 131e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 132e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // If there's another JavaScript frame on the stack or a 133e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // StubFailureTrampoline, we need to look one frame further down the stack to 134e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // find the frame pointer and the return address stack slot. 135e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org if (depth == EXTRA_CALL_FRAME) { 136e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; 137e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); 138e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); 139e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 140e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org#ifdef DEBUG 141c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org StackFrameIterator it(isolate); 14243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < depth + 1; i++) it.Advance(); 14343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen StackFrame* frame = it.frame(); 144e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); 145e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org#endif 146e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org fp_ = fp; 1471510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); 148fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org target_ = handle(raw_target(), isolate); 149fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org state_ = target_->ic_state(); 15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 15143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 15464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgAddress IC::OriginalCodeAddress() const { 155c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org HandleScope scope(isolate()); 15643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute the JavaScript frame for the frame pointer of this IC 15743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // structure. We need this to be able to find the function 15843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // corresponding to the frame. 159c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org StackFrameIterator it(isolate()); 16043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (it.frame()->fp() != this->fp()) it.Advance(); 16143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame()); 16243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Find the function on the stack and both the active code for the 16343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function and the original code. 164169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org JSFunction* function = frame->function(); 1657bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 16643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Code* code = shared->code(); 16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(Debug::HasDebugInfo(shared)); 16843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Code* original_code = Debug::GetDebugInfo(shared)->original_code(); 16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(original_code->IsCode()); 17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the address of the call site in the active code. This is the 17143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // place where the call to DebugBreakXXX is and where the IC 17243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // normally would be. 17389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org Address addr = Assembler::target_address_from_return_address(pc()); 17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Return the address in the original code. This is the place where 1753291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // the call which has been overwritten by the DebugBreakXXX resides 17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // and the place where the inline cache system should look. 177c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org intptr_t delta = 178c4c927273ae2b690c4a015b4640a2a469c9a1a69ager@chromium.org original_code->instruction_start() - code->instruction_start(); 17943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return addr + delta; 18043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 18165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif 18243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 184d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgstatic bool HasInterceptorGetter(JSObject* object) { 185d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return !object->GetNamedInterceptor()->getter()->IsUndefined(); 186d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 187d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 188d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 189d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgstatic bool HasInterceptorSetter(JSObject* object) { 190d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return !object->GetNamedInterceptor()->setter()->IsUndefined(); 191d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 192d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 193d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 194d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgstatic void LookupForRead(Handle<Object> object, 195d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<String> name, 196d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org LookupResult* lookup) { 197d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Skip all the objects with named interceptors, but 198d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // without actual getter. 199d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org while (true) { 200d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org object->Lookup(*name, lookup); 201d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Besides normal conditions (property not found or it's not 202d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // an interceptor), bail out if lookup is not cacheable: we won't 203d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // be able to IC it anyway and regular lookup should work fine. 204d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (!lookup->IsInterceptor() || !lookup->IsCacheable()) { 205d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return; 206d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 207d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 208d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<JSObject> holder(lookup->holder(), lookup->isolate()); 209d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (HasInterceptorGetter(*holder)) { 210d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return; 211d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 212d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 213d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org holder->LocalLookupRealNamedProperty(*name, lookup); 214d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (lookup->IsFound()) { 215d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(!lookup->IsInterceptor()); 216d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return; 217d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 218d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 219d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> proto(holder->GetPrototype(), lookup->isolate()); 220d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (proto->IsNull()) { 221d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(!lookup->IsFound()); 222d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return; 223d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 224d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 225d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org object = proto; 226d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 227d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 228d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 229d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 230d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgbool CallIC::TryUpdateExtraICState(LookupResult* lookup, 231d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> object) { 232d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (!lookup->IsConstantFunction()) return false; 233d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org JSFunction* function = lookup->GetConstantFunction(); 234d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (!function->shared()->HasBuiltinFunctionId()) return false; 235d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 236d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Fetch the arguments passed to the called function. 237d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org const int argc = target()->arguments_count(); 238d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Address entry = isolate()->c_entry_fp(isolate()->thread_local_top()); 239d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 240d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Arguments args(argc + 1, 241d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org &Memory::Object_at(fp + 242d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StandardFrameConstants::kCallerSPOffset + 243d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org argc * kPointerSize)); 244d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org switch (function->shared()->builtin_function_id()) { 245d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org case kStringCharCodeAt: 246d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org case kStringCharAt: 247d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (object->IsString()) { 248d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org String* string = String::cast(*object); 249d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // Check there's the right string value or wrapper in the receiver slot. 250d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(string == args[0] || string == JSValue::cast(args[0])->value()); 251d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // If we're in the default (fastest) state and the index is 252d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // out of bounds, update the state to record this fact. 253d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB && 254d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org argc >= 1 && args[1]->IsNumber()) { 255d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org double index = DoubleToInteger(args.number_at(1)); 256d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (index < 0 || index >= string->length()) { 257d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org extra_ic_state_ = 258d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org StringStubState::update(extra_ic_state(), 259d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org STRING_INDEX_OUT_OF_BOUNDS); 260d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return true; 261d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 262d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 263d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 264d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org break; 265d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org default: 266d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return false; 267d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 268d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return false; 269d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 270d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 271d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 272d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgbool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 273d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<String> name) { 274d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (target()->is_call_stub()) { 275d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org LookupResult lookup(isolate()); 276d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org LookupForRead(receiver, name, &lookup); 277d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (static_cast<CallIC*>(this)->TryUpdateExtraICState(&lookup, receiver)) { 278d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return true; 279d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 280d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 281d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 282fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (target()->is_keyed_stub()) { 28357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Determine whether the failure is due to a name failure. 28457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!name->IsName()) return false; 285fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Name* stub_name = target()->FindFirstName(); 286d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (*name != stub_name) return false; 287f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 288f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 28969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org InlineCacheHolderFlag cache_holder = 290fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Code::ExtractCacheHolderFromFlags(target()->flags()); 29169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 292fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org switch (cache_holder) { 293fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org case OWN_MAP: 294fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // The stub was generated for JSObject but called for non-JSObject. 295fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // IC::GetCodeCacheHolder is not applicable. 296fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (!receiver->IsJSObject()) return false; 297fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org break; 298fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org case PROTOTYPE_MAP: 299fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org // IC::GetCodeCacheHolder is not applicable. 300fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (receiver->GetPrototype(isolate())->IsNull()) return false; 301fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org break; 30269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 303fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 3042efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Map> map( 3052efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org IC::GetCodeCacheHolder(isolate(), *receiver, cache_holder)->map()); 30643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Decide whether the inline cache failed because of changes to the 30843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // receiver itself or changes to one of its prototypes. 30943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // 31043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there are changes to the receiver itself, the map of the 31143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // receiver will have changed and the current target will not be in 31243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // the receiver map's code cache. Therefore, if the current target 31343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // is in the receiver map's code cache, the inline cache failed due 31443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // to prototype check failure. 315d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org int index = map->IndexInCodeCache(*name, *target()); 316b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org if (index >= 0) { 317d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org map->RemoveFromCodeCache(*name, *target(), index); 31832aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org // Handlers are stored in addition to the ICs on the map. Remove those, too. 3192efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org TryRemoveInvalidHandlers(map, name); 3200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com return true; 3210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 32243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 32310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // The stub is not in the cache. We've ruled out all other kinds of failure 32410480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org // except for proptotype chain changes, a deprecated map, a map that's 325d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // different from the one that the stub expects, elements kind changes, or a 326d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // constant global property that will become mutable. Threat all those 327d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org // situations as prototype failures (stay monomorphic if possible). 32810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 32957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // If the IC is shared between multiple receivers (slow dictionary mode), then 33057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // the map cannot be deprecated and the stub invalidated. 33110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (cache_holder == OWN_MAP) { 332fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Map* old_map = target()->FindFirstMap(); 3332efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (old_map == *map) return true; 334d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (old_map != NULL) { 335d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (old_map->is_deprecated()) return true; 336d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(), 337d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org map->elements_kind())) { 338d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org return true; 339d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 340d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 34110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 34257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 34310480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (receiver->IsGlobalObject()) { 344fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org LookupResult lookup(isolate()); 345d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org GlobalObject* global = GlobalObject::cast(*receiver); 346d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org global->LocalLookupRealNamedProperty(*name, &lookup); 34710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (!lookup.IsFound()) return false; 34810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org PropertyCell* cell = global->GetPropertyCell(&lookup); 34910480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org return cell->type()->IsConstant(); 35010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 35110480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 35210480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org return false; 3530511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 3540511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3550511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3562efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgvoid IC::TryRemoveInvalidHandlers(Handle<Map> map, Handle<String> name) { 3572efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org CodeHandleList handlers; 3582efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org target()->FindHandlers(&handlers); 3592efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org for (int i = 0; i < handlers.length(); i++) { 3602efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Code> handler = handlers.at(i); 3612efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org int index = map->IndexInCodeCache(*name, *handler); 3622efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (index >= 0) { 3632efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org map->RemoveFromCodeCache(*name, *handler, index); 3642efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return; 3652efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } 3662efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } 3672efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org} 3682efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 3692efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 370d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { 3712efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (!name->IsString()) return; 3722efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (state() != MONOMORPHIC) { 3732efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (state() == POLYMORPHIC && receiver->IsHeapObject()) { 3742efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org TryRemoveInvalidHandlers( 3752efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org handle(Handle<HeapObject>::cast(receiver)->map()), 3762efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<String>::cast(name)); 3772efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } 3782efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return; 3792efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } 380fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (receiver->IsUndefined() || receiver->IsNull()) return; 3810511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3820511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Remove the target from the code cache if it became invalid 3830511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // because of changes in the prototype chain to avoid hitting it 3840511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // again. 385d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (TryRemoveInvalidPrototypeDependentStub( 386d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org receiver, Handle<String>::cast(name))) { 387d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return MarkMonomorphicPrototypeFailure(); 38843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 389b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 390b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // The builtins object is special. It only changes when JavaScript 391b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // builtins are loaded lazily. It is important to keep inline 392b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // caches for the builtins object monomorphic. Therefore, if we get 393b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // an inline cache miss for the builtins object after lazily loading 394236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // JavaScript builtins, we return uninitialized as the state to 395236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // force the inline cache back to monomorphic state. 396fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED; 39743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 39843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 39943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 400236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.orgRelocInfo::Mode IC::ComputeMode() { 40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Address addr = address(); 402ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Code* code = Code::cast(isolate()->FindCodeObject(addr)); 40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (RelocIterator it(code, RelocInfo::kCodeTargetMask); 40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen !it.done(); it.next()) { 40543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen RelocInfo* info = it.rinfo(); 40643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (info->pc() == addr) return info->rmode(); 40743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 40843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 40959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org return RelocInfo::NONE32; 41043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 41143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 41343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenFailure* IC::TypeError(const char* type, 41443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<Object> object, 4151af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Handle<Object> key) { 416ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HandleScope scope(isolate()); 4171af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org Handle<Object> args[2] = { key, object }; 418ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<Object> error = isolate()->factory()->NewTypeError( 419ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org type, HandleVector(args, 2)); 420ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return isolate()->Throw(*error); 42143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 42243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 42443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenFailure* IC::ReferenceError(const char* type, Handle<String> name) { 425ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HandleScope scope(isolate()); 426ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Handle<Object> error = isolate()->factory()->NewReferenceError( 427ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org type, HandleVector(&name, 1)); 428ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return isolate()->Throw(*error); 42943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 43043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 43143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4321456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstatic int ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state) { 4331456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org bool was_uninitialized = 4341456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org old_state == UNINITIALIZED || old_state == PREMONOMORPHIC; 4351456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org bool is_uninitialized = 4361456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org new_state == UNINITIALIZED || new_state == PREMONOMORPHIC; 4371456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return (was_uninitialized && !is_uninitialized) ? 1 : 4381456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org (!was_uninitialized && is_uninitialized) ? -1 : 0; 4391456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 4401456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4411456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 442f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgvoid IC::PostPatching(Address address, Code* target, Code* old_target) { 4431456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org if (FLAG_type_info_threshold == 0 && !FLAG_watch_ic_patching) { 4441456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org return; 4451456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org } 446fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Isolate* isolate = target->GetHeap()->isolate(); 447fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Code* host = isolate-> 4481456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org inner_pointer_to_code_cache()->GetCacheEntry(address)->code; 4491456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org if (host->kind() != Code::FUNCTION) return; 4501456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 4511456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org if (FLAG_type_info_threshold > 0 && 4521456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org old_target->is_inline_cache_stub() && 4531456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org target->is_inline_cache_stub()) { 4541456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org int delta = ComputeTypeInfoCountDelta(old_target->ic_state(), 4551456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org target->ic_state()); 4561456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // Not all Code objects have TypeFeedbackInfo. 45746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) { 4581456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org TypeFeedbackInfo* info = 4591456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org TypeFeedbackInfo::cast(host->type_feedback_info()); 46046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org info->change_ic_with_type_info_count(delta); 461f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 462f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 46346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (host->type_feedback_info()->IsTypeFeedbackInfo()) { 46446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org TypeFeedbackInfo* info = 46546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org TypeFeedbackInfo::cast(host->type_feedback_info()); 46646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org info->change_own_type_change_checksum(); 46746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 46878d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org if (FLAG_watch_ic_patching) { 4691456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org host->set_profiler_ticks(0); 470fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org isolate->runtime_profiler()->NotifyICChanged(); 47178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org } 4721456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // TODO(2029): When an optimized function is patched, it would 4731456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // be nice to propagate the corresponding type information to its 4741456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // unoptimized version for the benefit of later inlining. 47578d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org} 47678d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 47778d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 4783d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid IC::Clear(Isolate* isolate, Address address) { 47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Code* target = GetTargetAtAddress(address); 48043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Don't clear debug break inline cache as it will remove the break point. 482ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org if (target->is_debug_stub()) return; 48343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (target->kind()) { 4853d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org case Code::LOAD_IC: return LoadIC::Clear(isolate, address, target); 4863d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org case Code::KEYED_LOAD_IC: 4873d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org return KeyedLoadIC::Clear(isolate, address, target); 4883d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org case Code::STORE_IC: return StoreIC::Clear(isolate, address, target); 4893d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org case Code::KEYED_STORE_IC: 4903d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org return KeyedStoreIC::Clear(isolate, address, target); 49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case Code::CALL_IC: return CallIC::Clear(address, target); 4921af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target); 4933d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org case Code::COMPARE_IC: return CompareIC::Clear(isolate, address, target); 494ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org case Code::COMPARE_NIL_IC: return CompareNilIC::Clear(address, target); 49540cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org case Code::BINARY_OP_IC: 4969fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org case Code::TO_BOOLEAN_IC: 497a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Clearing these is tricky and does not 498a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // make any performance difference. 499a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return; 50043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen default: UNREACHABLE(); 50143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 50243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 50343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 50443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5051af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgvoid CallICBase::Clear(Address address, Code* target) { 5068e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (IsCleared(target)) return; 50740cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); 50871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org Code* code = 5093d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org target->GetIsolate()->stub_cache()->FindCallInitialize( 510ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org target->arguments_count(), 51140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, 512ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org target->kind()); 51343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen SetTargetAtAddress(address, code); 51443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 51543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 51643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5173d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) { 5188e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (IsCleared(target)) return; 51937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Make sure to also clear the map used in inline fast cases. If we 52037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // do not clear these maps, cached code can keep objects alive 52137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // through the embedded maps. 5228e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); 52343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 52443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 52543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5263d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid LoadIC::Clear(Isolate* isolate, Address address, Code* target) { 5278e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (IsCleared(target)) return; 5288e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); 52943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 53043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 53143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5323d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid StoreIC::Clear(Isolate* isolate, Address address, Code* target) { 5338e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (IsCleared(target)) return; 534496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org SetTargetAtAddress(address, 535fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org *pre_monomorphic_stub( 536cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); 53743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 53843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 53943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5403d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { 5418e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (IsCleared(target)) return; 5429ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org SetTargetAtAddress(address, 543fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org *pre_monomorphic_stub( 544cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); 54543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 54643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgvoid CompareIC::Clear(Isolate* isolate, Address address, Code* target) { 549fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ASSERT(target->major_key() == CodeStub::CompareIC); 550fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org CompareIC::State handler_state; 551fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Token::Value op; 552fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL, 553fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org &handler_state, &op); 554212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Only clear CompareICs that can retain objects. 5558432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (handler_state != KNOWN_OBJECT) return; 5563d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org SetTargetAtAddress(address, GetRawUninitialized(isolate, op)); 557212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); 558212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org} 559212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 560212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 561394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Object> CallICBase::TryCallAsFunction(Handle<Object> object) { 562e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.org Handle<Object> delegate = Execution::GetFunctionDelegate(isolate(), object); 5639258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 564394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (delegate->IsJSFunction() && !object->IsJSFunctionProxy()) { 5659258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Patch the receiver and use the delegate as the function to 566394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // invoke. This is used for invoking objects as if they were functions. 567394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com const int argc = target()->arguments_count(); 568c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org StackFrameLocator locator(isolate()); 5699258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 5709258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org int index = frame->ComputeExpressionsCount() - (argc + 1); 571394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com frame->SetExpression(index, *object); 5729258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } 5739258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 574394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return delegate; 5759258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org} 5769258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 5772c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org 5783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.orgvoid CallICBase::ReceiverToObjectIfRequired(Handle<Object> callee, 5793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Handle<Object> object) { 580394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com while (callee->IsJSFunctionProxy()) { 58109d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org callee = Handle<Object>(JSFunctionProxy::cast(*callee)->call_trap(), 58209d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate()); 583394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 584394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 5853a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (callee->IsJSFunction()) { 5863a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org Handle<JSFunction> function = Handle<JSFunction>::cast(callee); 5871b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org if (!function->shared()->is_classic_mode() || function->IsBuiltin()) { 5883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Do not wrap receiver for strict mode functions or for builtins. 5893a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return; 5903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 5913a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 5923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 5933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // And only wrap string, number or boolean. 5943a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (object->IsString() || object->IsNumber() || object->IsBoolean()) { 5953a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Change the receiver to the result of calling ToObject on it. 5963a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org const int argc = this->target()->arguments_count(); 597c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org StackFrameLocator locator(isolate()); 5983a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); 5993a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org int index = frame->ComputeExpressionsCount() - (argc + 1); 600ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org frame->SetExpression(index, *isolate()->factory()->ToObject(object)); 6013a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org } 602b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org} 603b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org 6049258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 605d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgstatic bool MigrateDeprecated(Handle<Object> object) { 606d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (!object->IsJSObject()) return false; 607d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 608d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (!receiver->map()->is_deprecated()) return false; 609d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org JSObject::MigrateInstance(Handle<JSObject>::cast(object)); 610d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return true; 611d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 612d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 613d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 614fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgMaybeObject* CallICBase::LoadFunction(Handle<Object> object, 615303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Handle<String> name) { 616d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; 617f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 61843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the object is undefined or null it's illegal to try to get any 61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // of its properties; throw a TypeError in that case. 62043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (object->IsUndefined() || object->IsNull()) { 62143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return TypeError("non_object_property_call", object, name); 62243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 62343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6249258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Check if the name is trivially convertible to an index and get 6259258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // the element if so. 6269258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org uint32_t index; 6279258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org if (name->AsArrayIndex(&index)) { 6283d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org Handle<Object> result = Object::GetElement(isolate(), object, index); 629394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com RETURN_IF_EMPTY_HANDLE(isolate(), result); 630394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (result->IsJSFunction()) return *result; 6319258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 6329258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Try to find a suitable function delegate for the object at hand. 6339258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org result = TryCallAsFunction(result); 634394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (result->IsJSFunction()) return *result; 6359258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 6369258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org // Otherwise, it will fail in the lookup step. 6379258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org } 6389258b6bc66e09368ada54001f619d53b4fc976d5ager@chromium.org 63943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Lookup the property in the object. 640394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupResult lookup(isolate()); 641394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupForRead(object, name, &lookup); 64243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 643753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org if (!lookup.IsFound()) { 64443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the object does not have the requested property, check which 64543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // exception we need to throw. 646c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org return IsUndeclaredGlobal(object) 647394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ? ReferenceError("not_defined", name) 648394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com : TypeError("undefined_method", object, name); 64943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 65043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 65143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Lookup is valid: Update inline cache and stub cache. 652fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (use_ic) UpdateCaches(&lookup, object, name); 65343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6542abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org // Get the property. 6552abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org PropertyAttributes attr; 656394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Object> result = 657394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Object::GetProperty(object, object, &lookup, name, &attr); 658394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com RETURN_IF_EMPTY_HANDLE(isolate(), result); 6593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 660de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org if (lookup.IsInterceptor() && attr == ABSENT) { 66143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the object does not have the requested property, check which 66243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // exception we need to throw. 663c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org return IsUndeclaredGlobal(object) 664394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ? ReferenceError("not_defined", name) 665394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com : TypeError("undefined_method", object, name); 66643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 66743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6683a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ASSERT(!result->IsTheHole()); 66943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6703a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Make receiver an object if the callee requires it. Strict mode or builtin 6713a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // functions do not wrap the receiver, non-strict functions and objects 6723a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // called as functions do. 673394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ReceiverToObjectIfRequired(result, object); 6743a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 675394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (result->IsJSFunction()) { 676394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSFunction> function = Handle<JSFunction>::cast(result); 67765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 67837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Handle stepping into a function if step into is active. 679ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Debug* debug = isolate()->debug(); 680ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (debug->StepInActive()) { 68137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Protect the result in a handle as the debugger can allocate and might 68237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // cause GC. 683ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org debug->HandleStepIn(function, object, fp(), false); 68443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 68565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif 686394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return *function; 68743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 68843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 68943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Try to find a suitable function delegate for the object at hand. 690394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com result = TryCallAsFunction(result); 691394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (result->IsJSFunction()) return *result; 6923a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 6933a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return TypeError("property_not_function", object, name); 69443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 69543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 69643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 697394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comHandle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup, 698394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Object> object, 699394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<String> name) { 7000511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com int argc = target()->arguments_count(); 7017bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<JSObject> holder(lookup->holder(), isolate()); 7020511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com switch (lookup->type()) { 7030511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com case FIELD: { 704eeb44b681a16e45f1415dfacff0ba3dba9de5d8cyangguo@chromium.org PropertyIndex index = lookup->GetFieldIndex(); 705394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return isolate()->stub_cache()->ComputeCallField( 706d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org argc, kind_, extra_ic_state(), name, object, holder, index); 7070511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 708fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org case CONSTANT: { 709fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org if (!lookup->IsConstantFunction()) return Handle<Code>::null(); 7100511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Get the constant function and compute the code stub for this 7110511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // call; used for rewriting to monomorphic state and making sure 7120511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // that the code stub is in the stub cache. 7137bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<JSFunction> function(lookup->GetConstantFunction(), isolate()); 714394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return isolate()->stub_cache()->ComputeCallConstant( 715d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org argc, kind_, extra_ic_state(), name, object, holder, function); 7160511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7170511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com case NORMAL: { 718394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // If we return a null handle, the IC will not be patched. 719394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!object->IsJSObject()) return Handle<Code>::null(); 7200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com Handle<JSObject> receiver = Handle<JSObject>::cast(object); 7210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 722394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (holder->IsGlobalObject()) { 723394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 724b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell( 7257bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org global->GetPropertyCell(lookup), isolate()); 726394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!cell->value()->IsJSFunction()) return Handle<Code>::null(); 727394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSFunction> function(JSFunction::cast(cell->value())); 728394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return isolate()->stub_cache()->ComputeCallGlobal( 729d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org argc, kind_, extra_ic_state(), name, 730d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org receiver, global, cell, function); 7310511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } else { 7320511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // There is only one shared stub for calling normalized 7330511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // properties. It does not traverse the prototype chain, so the 7340511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // property must be found in the receiver for the stub to be 7350511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // applicable. 736394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!holder.is_identical_to(receiver)) return Handle<Code>::null(); 737394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return isolate()->stub_cache()->ComputeCallNormal( 738d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org argc, kind_, extra_ic_state()); 7390511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7400511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com break; 7410511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 742394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com case INTERCEPTOR: 743394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com ASSERT(HasInterceptorGetter(*holder)); 744394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return isolate()->stub_cache()->ComputeCallInterceptor( 745d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org argc, kind_, extra_ic_state(), name, object, holder); 7460511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com default: 747394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return Handle<Code>::null(); 7480511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com } 7490511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com} 7500511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 7510511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 752d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgHandle<Code> CallICBase::megamorphic_stub() { 753d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return isolate()->stub_cache()->ComputeCallMegamorphic( 754d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org target()->arguments_count(), kind_, extra_ic_state()); 755d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 756d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 757d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 758d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgHandle<Code> CallICBase::pre_monomorphic_stub() { 759d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return isolate()->stub_cache()->ComputeCallPreMonomorphic( 760d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org target()->arguments_count(), kind_, extra_ic_state()); 761d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 762d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 763d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 7641af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgvoid CallICBase::UpdateCaches(LookupResult* lookup, 76569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Handle<Object> object, 76669ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Handle<String> name) { 76743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Bail out if we didn't find a result. 7685c838251403b0be9a882540f1922577abba4c872ager@chromium.org if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 76943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 770e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (state() == UNINITIALIZED) { 771e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org set_target(*pre_monomorphic_stub()); 772e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org TRACE_IC("CallIC", name); 773e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return; 774e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 77543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 776e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Code> code = ComputeMonomorphicStub(lookup, object, name); 777394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // If there's no appropriate stub we simply avoid updating the caches. 778d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // TODO(verwaest): Install a slow fallback in this case to avoid not learning, 779d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // and deopting Crankshaft code. 780394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (code.is_null()) return; 78143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 782d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<JSObject> cache_object = object->IsJSObject() 783d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ? Handle<JSObject>::cast(object) 784d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())), 785d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org isolate()); 78659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org 787f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org PatchCache(CurrentTypeOf(cache_object, isolate()), name, code); 788d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org TRACE_IC("CallIC", name); 78943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 79043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 79143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 792fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgMaybeObject* KeyedCallIC::LoadFunction(Handle<Object> object, 793303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Handle<Object> key) { 7944a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (key->IsInternalizedString()) { 795fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return CallICBase::LoadFunction(object, Handle<String>::cast(key)); 7961af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 7971af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 7981af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org if (object->IsUndefined() || object->IsNull()) { 7991af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org return TypeError("non_object_property_call", object, key); 8001af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 8011af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 802d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org bool use_ic = MigrateDeprecated(object) 803d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ? false : FLAG_use_ic && !object->IsAccessCheckNeeded(); 804d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 805fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (use_ic && state() != MEGAMORPHIC) { 806d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(!object->IsJSGlobalProxy()); 8072cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org int argc = target()->arguments_count(); 808ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Handle<Code> stub; 809ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 810ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Use the KeyedArrayCallStub if the call is of the form array[smi](...), 811ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // where array is an instance of one of the initial array maps (without 812ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // extra named properties). 813ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // TODO(verwaest): Also support keyed calls on instances of other maps. 814ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (object->IsJSArray() && key->IsSmi()) { 815ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Handle<JSArray> array = Handle<JSArray>::cast(object); 816ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ElementsKind kind = array->map()->elements_kind(); 817ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (IsFastObjectElementsKind(kind) && 818ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org array->map() == isolate()->get_initial_js_array_map(kind)) { 819ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org KeyedArrayCallStub stub_gen(IsHoleyElementsKind(kind), argc); 820ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org stub = stub_gen.GetCode(isolate()); 821d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org } 8221af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 823ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 824ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (stub.is_null()) { 825ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org stub = isolate()->stub_cache()->ComputeCallMegamorphic( 826cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org argc, Code::KEYED_CALL_IC, kNoExtraICState); 827ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (object->IsJSObject()) { 828ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 829ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (receiver->elements()->map() == 830ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org isolate()->heap()->non_strict_arguments_elements_map()) { 831ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org stub = isolate()->stub_cache()->ComputeCallArguments(argc); 832ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 833ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 834ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(!stub.is_null()); 835ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org } 836d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org set_target(*stub); 837d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org TRACE_IC("CallIC", key); 8381af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org } 8393a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 84009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> result = GetProperty(isolate(), object, key); 841ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org RETURN_IF_EMPTY_HANDLE(isolate(), result); 8423a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 8433a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // Make receiver an object if the callee requires it. Strict mode or builtin 8443a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // functions do not wrap the receiver, non-strict functions and objects 8453a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org // called as functions do. 8463a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org ReceiverToObjectIfRequired(result, object); 8473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (result->IsJSFunction()) return *result; 848394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 849394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com result = TryCallAsFunction(result); 8503a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org if (result->IsJSFunction()) return *result; 8513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org 8523a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org return TypeError("property_not_function", object, key); 8531af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 8541af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 8551af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 856fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgMaybeObject* LoadIC::Load(Handle<Object> object, 857003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<String> name) { 85843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the object is undefined or null it's illegal to try to get any 85943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // of its properties; throw a TypeError in that case. 86043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (object->IsUndefined() || object->IsNull()) { 86143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return TypeError("non_object_property_load", object, name); 86243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 86343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 864d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (FLAG_use_ic) { 8659fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org // Use specialized code for getting the length of strings and 8669fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org // string wrapper objects. The length property of string wrapper 8679fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org // objects is read-only and therefore always returns the length of 8689fe21c6d4c657d15af27c8751257d3e2bf113e45kasperl@chromium.org // the underlying string value. See ECMA-262 15.5.5.1. 869528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (object->IsStringWrapper() && 8704a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org name->Equals(isolate()->heap()->length_string())) { 871394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Code> stub; 872fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == UNINITIALIZED) { 873ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org stub = pre_monomorphic_stub(); 874fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } else if (state() == PREMONOMORPHIC || state() == MONOMORPHIC) { 875528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org StringLengthStub string_length_stub(kind()); 8768432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org stub = string_length_stub.GetCode(isolate()); 877fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } else if (state() != MEGAMORPHIC) { 878fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ASSERT(state() != GENERIC); 879ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org stub = megamorphic_stub(); 880ac2828d8d201b0631783404187688fbb786458a3lrn@chromium.org } 881394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!stub.is_null()) { 882394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com set_target(*stub); 883528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org if (FLAG_trace_ic) PrintF("[LoadIC : +#length /stringwrapper]\n"); 884378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 885378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org // Get the string if we have a string wrapper object. 886528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org String* string = String::cast(JSValue::cast(*object)->value()); 887528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return Smi::FromInt(string->length()); 88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 89043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Use specialized code for getting prototype of functions. 891ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (object->IsJSFunction() && 8924a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org name->Equals(isolate()->heap()->prototype_string()) && 893394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSFunction>::cast(object)->should_have_prototype()) { 894394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<Code> stub; 895fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == UNINITIALIZED) { 896394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com stub = pre_monomorphic_stub(); 897fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } else if (state() == PREMONOMORPHIC) { 8986bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org FunctionPrototypeStub function_prototype_stub(kind()); 8998432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org stub = function_prototype_stub.GetCode(isolate()); 900fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org } else if (state() != MEGAMORPHIC) { 901fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ASSERT(state() != GENERIC); 902394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com stub = megamorphic_stub(); 903394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 904394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!stub.is_null()) { 905394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com set_target(*stub); 906394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); 907378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org } 908ebeba02c9ae4ffb0ceab36eb7239f143420f8607rossberg@chromium.org return *Accessors::FunctionGetPrototype(Handle<JSFunction>::cast(object)); 90943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 91043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 91143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 91243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check if the name is trivially convertible to an index and get 9136bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // the element or char if so. 91443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t index; 9156bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { 9166bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // Rewrite to the generic keyed load stub. 917d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (FLAG_use_ic) set_target(*generic_stub()); 91877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org return Runtime::GetElementOrCharAtOrFail(isolate(), object, index); 9196bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 92043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 921d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; 922f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 92343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Named lookup in the object. 924394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupResult lookup(isolate()); 925394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com LookupForRead(object, name, &lookup); 92643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9275c838251403b0be9a882540f1922577abba4c872ager@chromium.org // If we did not find a property, check if we need to throw an exception. 928753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org if (!lookup.IsFound()) { 929c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org if (IsUndeclaredGlobal(object)) { 93043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return ReferenceError("not_defined", name); 93143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 932ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org LOG(isolate(), SuspectReadEvent(*name, *object)); 93343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 93443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 93543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Update inline cache and stub cache. 936fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (use_ic) UpdateCaches(&lookup, object, name); 93743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 93843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PropertyAttributes attr; 93943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the property. 940d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> result = 941d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Object::GetProperty(object, object, &lookup, name, &attr); 942d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org RETURN_IF_EMPTY_HANDLE(isolate(), result); 943d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // If the property is not present, check if we need to throw an 944d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // exception. 945d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if ((lookup.IsInterceptor() || lookup.IsHandler()) && 946d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org attr == ABSENT && IsUndeclaredGlobal(object)) { 947d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return ReferenceError("not_defined", name); 948d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 949d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return *result; 95043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 95143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 95243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9534a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgstatic bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, 9544a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<Map> new_receiver_map) { 9554a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org ASSERT(!new_receiver_map.is_null()); 9564a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org for (int current = 0; current < receiver_maps->length(); ++current) { 9574a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (!receiver_maps->at(current).is_null() && 9584a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org receiver_maps->at(current).is_identical_to(new_receiver_map)) { 9594a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return false; 9604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 9614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 9624a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org receiver_maps->Add(new_receiver_map); 9634a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return true; 9644a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 9654a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 9664a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 967af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgbool IC::UpdatePolymorphicIC(Handle<Type> type, 9684a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<String> name, 969fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<Code> code) { 970fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (!code->is_handler()) return false; 971af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org TypeHandleList types; 9724a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org CodeHandleList handlers; 9734a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 974af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int number_of_valid_types; 97557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org int handler_to_overwrite = -1; 976af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 977af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org target()->FindAllTypes(&types); 978af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org int number_of_types = types.length(); 979af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org number_of_valid_types = number_of_types; 980af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 981af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org for (int i = 0; i < number_of_types; i++) { 982af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Handle<Type> current_type = types.at(i); 983af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org // Filter out deprecated maps to ensure their instances get migrated. 984af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (current_type->IsClass() && current_type->AsClass()->is_deprecated()) { 985af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org number_of_valid_types--; 986af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org // If the receiver type is already in the polymorphic IC, this indicates 987e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // there was a prototoype chain failure. In that case, just overwrite the 988e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // handler. 989f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } else if (type->IsCurrently(current_type)) { 990af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org ASSERT(handler_to_overwrite == -1); 991af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org number_of_valid_types--; 992e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org handler_to_overwrite = i; 993f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 994e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 995f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 996af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (number_of_valid_types >= 4) return false; 997af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (number_of_types == 0) return false; 998af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (!target()->FindHandlers(&handlers, types.length())) return false; 99932aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org 1000af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org number_of_valid_types++; 100157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (handler_to_overwrite >= 0) { 100257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org handlers.Set(handler_to_overwrite, code); 100357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 1004af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org types.Add(type); 100557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org handlers.Add(code); 10064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 10074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 1008fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( 1009cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org &types, &handlers, number_of_valid_types, name, extra_ic_state()); 10104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org set_target(*ic); 10114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return true; 10124a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 10134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 10144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 1015f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.orgHandle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { 1016f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Type* type = object->IsJSGlobalObject() 1017f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org ? Type::Constant(Handle<JSGlobalObject>::cast(object)) 1018f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org : Type::OfCurrently(object); 1019f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org return handle(type, isolate); 1020f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 1021f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 1022f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 1023af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgHandle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { 1024af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); 1025af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); 1026f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (type->IsConstant()) { 1027f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); 1028f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 1029af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org ASSERT(type->IsClass()); 1030af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org return type->AsClass(); 1031af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org} 1032af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 1033af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 1034af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgType* IC::MapToType(Handle<Map> map) { 1035af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(); 1036af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org // The only oddballs that can be recorded in ICs are booleans. 1037af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); 1038af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org return Type::Class(map); 1039af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org} 1040af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 1041af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 1042af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgvoid IC::UpdateMonomorphicIC(Handle<Type> type, 1043fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<Code> handler, 1044fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<String> name) { 1045fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (!handler->is_handler()) return set_target(*handler); 1046fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( 1047cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org name, type, handler, extra_ic_state()); 1048bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org set_target(*ic); 1049bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 1050bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 1051bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 10526e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.orgvoid IC::CopyICToMegamorphicCache(Handle<String> name) { 1053af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org TypeHandleList types; 10546e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org CodeHandleList handlers; 1055af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org target()->FindAllTypes(&types); 1056af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (!target()->FindHandlers(&handlers, types.length())) return; 1057af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org for (int i = 0; i < types.length(); i++) { 1058af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); 10596e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 10606e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 10616e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 10626e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 1063af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgbool IC::IsTransitionOfMonomorphicTarget(Type* type) { 1064af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (!type->IsClass()) return false; 1065af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Map* receiver_map = *type->AsClass(); 1066f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Map* current_map = target()->FindFirstMap(); 1067f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ElementsKind receiver_elements_kind = receiver_map->elements_kind(); 1068f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org bool more_general_transition = 1069f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org IsMoreGeneralElementsKindTransition( 1070f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org current_map->elements_kind(), receiver_elements_kind); 1071f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Map* transitioned_map = more_general_transition 1072f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ? current_map->LookupElementsTransitionMap(receiver_elements_kind) 1073f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org : NULL; 1074f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 1075f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return transitioned_map == receiver_map; 1076f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org} 1077f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 1078f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 1079af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgvoid IC::PatchCache(Handle<Type> type, 1080d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org Handle<String> name, 1081d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org Handle<Code> code) { 1082fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org switch (state()) { 108359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case UNINITIALIZED: 108459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case PREMONOMORPHIC: 108559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case MONOMORPHIC_PROTOTYPE_FAILURE: 1086af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org UpdateMonomorphicIC(type, code, name); 108759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org break; 1088b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org case MONOMORPHIC: { 1089d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // For now, call stubs are allowed to rewrite to the same stub. This 1090d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org // happens e.g., when the field does not contain a function. 1091d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(target()->is_call_stub() || 1092d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org target()->is_keyed_call_stub() || 1093d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org !target().is_identical_to(code)); 1094b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Code* old_handler = target()->FindFirstHandler(); 1095af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (old_handler == *code && IsTransitionOfMonomorphicTarget(*type)) { 1096af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org UpdateMonomorphicIC(type, code, name); 1097b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org break; 1098e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 1099e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Fall through. 1100b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 1101e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org case POLYMORPHIC: 1102e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (!target()->is_keyed_stub()) { 1103af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (UpdatePolymorphicIC(type, name, code)) break; 1104fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org CopyICToMegamorphicCache(name); 110559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 1106fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org set_target(*megamorphic_stub()); 1107e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // Fall through. 110859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case MEGAMORPHIC: 1109af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org UpdateMegamorphicCache(*type, *name, *code); 111059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org break; 1111d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org case DEBUG_STUB: 111259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org break; 1113068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org case GENERIC: 1114068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org UNREACHABLE(); 1115068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org break; 111643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1117d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org} 1118d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 1119d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 11202efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> LoadIC::SimpleFieldLoad(int offset, 11212efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org bool inobject, 11222efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Representation representation) { 11232efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (kind() == Code::LOAD_IC) { 11242efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org LoadFieldStub stub(inobject, offset, representation); 11252efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return stub.GetCode(isolate()); 11262efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } else { 11272efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org KeyedLoadFieldStub stub(inobject, offset, representation); 11282efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return stub.GetCode(isolate()); 11292efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } 11302efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org} 11312efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 1132e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1133d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.orgvoid LoadIC::UpdateCaches(LookupResult* lookup, 1134d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org Handle<Object> object, 1135d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org Handle<String> name) { 1136fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == UNINITIALIZED) { 1137d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org // This is the first time we execute this inline cache. 1138d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org // Set the target to the pre monomorphic stub to delay 1139d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org // setting the monomorphic state. 1140e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org set_target(*pre_monomorphic_stub()); 1141e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org TRACE_IC("LoadIC", name); 1142e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return; 1143b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 1144b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 1145f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Type> type = CurrentTypeOf(object, isolate()); 1146b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Code> code; 1147b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!lookup->IsCacheable()) { 11484a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org // Bail out if the result is not cacheable. 11494a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org code = slow_stub(); 11502efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } else if (!lookup->IsProperty()) { 1151b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (kind() == Code::LOAD_IC) { 1152f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org code = isolate()->stub_cache()->ComputeLoadNonexistent(name, type); 1153b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else { 1154b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org code = slow_stub(); 1155b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 1156d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org } else { 1157b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org code = ComputeHandler(lookup, object, name); 1158d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org } 115943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1160f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org PatchCache(type, name, code); 1161d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org TRACE_IC("LoadIC", name); 116243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 116343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 116443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1165af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.orgvoid IC::UpdateMegamorphicCache(Type* type, Name* name, Code* code) { 1166003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // Cache code holding map should be consistent with 1167003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // GenerateMonomorphicCacheProbe. 1168af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Map* map = *TypeToMap(type, isolate()); 1169003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org isolate()->stub_cache()->Set(name, map, code); 1170ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 1171ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1172ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 11732efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> IC::ComputeHandler(LookupResult* lookup, 1174b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Object> object, 11752efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<String> name, 11762efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Object> value) { 1177b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org InlineCacheHolderFlag cache_holder = GetCodeCacheForObject(*object); 1178b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<HeapObject> stub_holder(GetCodeCacheHolder( 1179b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org isolate(), *object, cache_holder)); 1180b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 11812efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Code> code = isolate()->stub_cache()->FindHandler( 1182cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org name, handle(stub_holder->map()), kind(), cache_holder); 11832efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (!code.is_null()) return code; 11842efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 1185b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org code = CompileHandler(lookup, object, name, value, cache_holder); 1186e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org ASSERT(code->is_handler()); 11872efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 1188e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (code->type() != Code::NORMAL) { 1189b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HeapObject::UpdateMapCodeCache(stub_holder, name, code); 1190003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1191003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 11922efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return code; 11932efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org} 11942efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 11952efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 11962efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> LoadIC::CompileHandler(LookupResult* lookup, 1197b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Object> object, 11982efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<String> name, 1199b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Object> unused, 1200b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org InlineCacheHolderFlag cache_holder) { 1201b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (object->IsString() && name->Equals(isolate()->heap()->length_string())) { 1202b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org int length_index = String::kLengthOffset / kPointerSize; 1203b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return SimpleFieldLoad(length_index); 1204b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 1205b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 1206f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org Handle<Type> type = CurrentTypeOf(object, isolate()); 1207003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<JSObject> holder(lookup->holder()); 1208ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org LoadStubCompiler compiler(isolate(), kNoExtraICState, cache_holder, kind()); 12092efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 1210003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org switch (lookup->type()) { 12112efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org case FIELD: { 12122efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org PropertyIndex field = lookup->GetFieldIndex(); 1213b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (object.is_identical_to(holder)) { 12142efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return SimpleFieldLoad(field.translate(holder), 12152efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org field.is_inobject(holder), 12162efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org lookup->representation()); 12172efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } 12182efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return compiler.CompileLoadField( 1219f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org type, holder, name, field, lookup->representation()); 12202efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } 1221fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org case CONSTANT: { 1222fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org Handle<Object> constant(lookup->GetConstant(), isolate()); 1223fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // TODO(2803): Don't compute a stub for cons strings because they cannot 1224fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org // be embedded into code. 12252efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (constant->IsConsString()) break; 1226f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org return compiler.CompileLoadConstant(type, holder, name, constant); 1227003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1228003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case NORMAL: 12292efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (kind() != Code::LOAD_IC) break; 1230003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (holder->IsGlobalObject()) { 1231003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 1232b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<PropertyCell> cell( 12337bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org global->GetPropertyCell(lookup), isolate()); 1234e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Code> code = compiler.CompileLoadGlobal( 1235f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org type, global, cell, name, lookup->IsDontDelete()); 1236e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1237b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<HeapObject> stub_holder(GetCodeCacheHolder( 1238b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org isolate(), *object, cache_holder)); 1239b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org HeapObject::UpdateMapCodeCache(stub_holder, name, code); 1240e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return code; 1241003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1242003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // There is only one shared stub for loading normalized 1243003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // properties. It does not traverse the prototype chain, so the 1244b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // property must be found in the object for the stub to be 1245003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // applicable. 1246b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!object.is_identical_to(holder)) break; 12472efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return isolate()->builtins()->LoadIC_Normal(); 1248003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case CALLBACKS: { 12492efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org // Use simple field loads for some well-known callback properties. 1250b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (object->IsJSObject()) { 1251b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1252b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Map> map(receiver->map()); 12537ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org int object_offset; 1254b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (Accessors::IsJSObjectFieldAccessor(map, name, &object_offset)) { 12557ff7607c2315ea91e4d13330ce14125e4bb4851amachenbach@chromium.org return SimpleFieldLoad(object_offset / kPointerSize); 1256b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 1257528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 12588e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org 12598e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org Handle<Object> callback(lookup->GetCallbackObject(), isolate()); 12607c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (callback->IsExecutableAccessorInfo()) { 12617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Handle<ExecutableAccessorInfo> info = 12627c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Handle<ExecutableAccessorInfo>::cast(callback); 1263003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (v8::ToCData<Address>(info->getter()) == 0) break; 1264b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!info->IsCompatibleReceiver(*object)) break; 1265f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org return compiler.CompileLoadCallback(type, holder, name, info); 1266003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } else if (callback->IsAccessorPair()) { 126709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter(), 126809d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org isolate()); 1269003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (!getter->IsJSFunction()) break; 1270003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (holder->IsGlobalObject()) break; 1271003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (!holder->HasFastProperties()) break; 12722c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org Handle<JSFunction> function = Handle<JSFunction>::cast(getter); 1273b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!object->IsJSObject() && 1274b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org !function->IsBuiltin() && 1275b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org function->shared()->is_classic_mode()) { 1276b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // Calling non-strict non-builtins with a value as the receiver 1277b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // requires boxing. 1278b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org break; 1279b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 12802c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org CallOptimization call_optimization(function); 12812c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org if (call_optimization.is_simple_api_call() && 1282b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org call_optimization.IsCompatibleReceiver(*object)) { 12832efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return compiler.CompileLoadCallback( 1284f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org type, holder, name, call_optimization); 12852c9426bdda5e95459527292063d885c98180cb0fjkummerow@chromium.org } 1286f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org return compiler.CompileLoadViaGetter(type, holder, name, function); 1287003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 12887c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // TODO(dcarney): Handle correctly. 12897c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (callback->IsDeclaredAccessorInfo()) break; 1290003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ASSERT(callback->IsForeign()); 1291003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // No IC support for old-style native accessors. 1292003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org break; 1293003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1294003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case INTERCEPTOR: 1295003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org ASSERT(HasInterceptorGetter(*holder)); 1296f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org return compiler.CompileLoadInterceptor(type, holder, name); 1297003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org default: 1298003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org break; 1299003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 13002efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 13012efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return slow_stub(); 1302ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 1303ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1304ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 130528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgstatic Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { 130628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // This helper implements a few common fast cases for converting 130728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // non-smi keys of keyed loads/stores to a smi or a string. 130828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (key->IsHeapNumber()) { 130928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org double value = Handle<HeapNumber>::cast(key)->value(); 131077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (std::isnan(value)) { 13114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org key = isolate->factory()->nan_string(); 131228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else { 131328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int int_value = FastD2I(value); 131428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (value == int_value && Smi::IsValid(int_value)) { 131509d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org key = Handle<Smi>(Smi::FromInt(int_value), isolate); 131628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 131728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 131828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else if (key->IsUndefined()) { 13194a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org key = isolate->factory()->undefined_string(); 132028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 132128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org return key; 132228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org} 132328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 132428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 1325003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgHandle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) { 1326003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1327003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // via megamorphic stubs, since they don't have a map in their relocation info 1328003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // and so the stubs can't be harvested for the object needed for a map check. 1329003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (target()->type() != Code::NORMAL) { 1330c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); 1331003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return generic_stub(); 1332003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1333003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 13347bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<Map> receiver_map(receiver->map(), isolate()); 1335003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org MapHandleList target_receiver_maps; 1336fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) { 1337003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 1338003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // yet will do so and stay there. 1339003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); 1340003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1341003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1342fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (target().is_identical_to(string_stub())) { 1343003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org target_receiver_maps.Add(isolate()->factory()->string_map()); 1344003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } else { 1345fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org target()->FindAllMaps(&target_receiver_maps); 1346068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org if (target_receiver_maps.length() == 0) { 1347068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); 1348068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 1349003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1350003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1351003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // The first time a receiver is seen that is a transitioned version of the 1352003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // previous monomorphic receiver type, assume the new ElementsKind is the 1353003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // monomorphic type. This benefits global arrays that only transition 1354003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // once, and all call sites accessing them are faster if they remain 1355003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // monomorphic. If this optimistic assumption is not true, the IC will 1356003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // miss again and it will become polymorphic and support both the 1357003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // untransitioned and transitioned maps. 1358fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == MONOMORPHIC && 1359003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org IsMoreGeneralElementsKindTransition( 1360003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org target_receiver_maps.at(0)->elements_kind(), 1361003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org receiver->GetElementsKind())) { 1362003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); 1363003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1364003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1365fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ASSERT(state() != GENERIC); 1366003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1367003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // Determine the list of receiver maps that this call site has seen, 1368003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // adding the map that was just encountered. 1369003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { 1370003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // If the miss wasn't due to an unseen map, a polymorphic stub 1371003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // won't help, use the generic stub. 1372c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); 1373003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return generic_stub(); 1374003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1375003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1376003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // If the maximum number of receiver maps has been exceeded, use the generic 1377003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // version of the IC. 1378003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1379c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); 1380003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return generic_stub(); 1381003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1382003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1383003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return isolate()->stub_cache()->ComputeLoadElementPolymorphic( 1384003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org &target_receiver_maps); 1385003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org} 1386003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1387003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1388b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgMaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) { 1389d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (MigrateDeprecated(object)) { 1390d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return Runtime::GetObjectPropertyOrFail(isolate(), object, key); 1391d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 1392d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1393c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MaybeObject* maybe_object = NULL; 1394c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Handle<Code> stub = generic_stub(); 1395c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 13964a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Check for values that can be converted into an internalized string directly 13974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // or is representable as a smi. 139828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org key = TryConvertKey(key, isolate()); 1399c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 14004a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (key->IsInternalizedString()) { 1401c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org maybe_object = LoadIC::Load(object, Handle<String>::cast(key)); 1402c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (maybe_object->IsFailure()) return maybe_object; 1403c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { 1404d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(!object->IsJSGlobalProxy()); 1405b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (object->IsString() && key->IsNumber()) { 1406b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (state() == UNINITIALIZED) stub = string_stub(); 1407b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else if (object->IsJSObject()) { 1408b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1409b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (receiver->elements()->map() == 1410b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org isolate()->heap()->non_strict_arguments_elements_map()) { 1411b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org stub = non_strict_arguments_stub(); 1412b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else if (receiver->HasIndexedInterceptor()) { 1413b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org stub = indexed_interceptor_stub(); 1414b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else if (!key->ToSmi()->IsFailure() && 1415b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org (!target().is_identical_to(non_strict_arguments_stub()))) { 1416b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org stub = LoadElementStub(receiver); 1417d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 14183811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 1419c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 1420d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1421c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (!is_target_set()) { 1422c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (*stub == *generic_stub()) { 1423c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic"); 1424c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 1425d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ASSERT(!stub.is_null()); 1426d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org set_target(*stub); 1427d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org TRACE_IC("LoadIC", key); 1428ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 1429a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1430c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (maybe_object != NULL) return maybe_object; 1431b228be01a466e0ba4d8389148671d196b2081f76mstarzinger@chromium.org return Runtime::GetObjectPropertyOrFail(isolate(), object, key); 143243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 143343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 143443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1435394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comstatic bool LookupForWrite(Handle<JSObject> receiver, 1436394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<String> name, 1437f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org Handle<Object> value, 143857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org LookupResult* lookup, 1439fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org IC* ic) { 1440f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org Handle<JSObject> holder = receiver; 1441f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org receiver->Lookup(*name, lookup); 1442f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (lookup->IsFound()) { 1443f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (lookup->IsReadOnly() || !lookup->IsCacheable()) return false; 1444f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 1445f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (lookup->holder() == *receiver) { 1446fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (lookup->IsInterceptor() && !HasInterceptorSetter(*receiver)) { 1447f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org receiver->LocalLookupRealNamedProperty(*name, lookup); 1448f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org return lookup->IsFound() && 1449f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org !lookup->IsReadOnly() && 1450f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org lookup->CanHoldValue(value) && 1451f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org lookup->IsCacheable(); 1452f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } 1453f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org return lookup->CanHoldValue(value); 1454f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org } 1455f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 1456f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (lookup->IsPropertyCallbacks()) return true; 14578a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org // JSGlobalProxy always goes via the runtime, so it's safe to cache. 14588a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org if (receiver->IsJSGlobalProxy()) return true; 1459f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // Currently normal holders in the prototype chain are not supported. They 1460f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // would require a runtime positive lookup and verification that the details 1461f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // have not changed. 1462f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org if (lookup->IsInterceptor() || lookup->IsNormal()) return false; 1463f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org holder = Handle<JSObject>(lookup->holder(), lookup->isolate()); 14645aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org } 14655aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 1466f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // While normally LookupTransition gets passed the receiver, in this case we 1467f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // pass the holder of the property that we overwrite. This keeps the holder in 1468f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // the LookupResult intact so we can later use it to generate a prototype 1469f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // chain check. This avoids a double lookup, but requires us to pass in the 1470f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org // receiver when trying to fetch extra information from the transition. 1471f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org receiver->map()->LookupTransition(*holder, *name, lookup); 1472f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (!lookup->IsTransition()) return false; 14738b363d4621a720d7a111f30bf168a09f82127ef2verwaest@chromium.org PropertyDetails target_details = lookup->GetTransitionDetails(); 1474f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org if (target_details.IsReadOnly()) return false; 147557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 147657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // If the value that's being stored does not fit in the field that the 147757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // instance would transition to, create a new transition that fits the value. 147857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // This has to be done before generating the IC, since that IC will embed the 147957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // transition target. 148057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // Ensure the instance and its map were migrated before trying to update the 148157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org // transition target. 148257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(!receiver->map()->is_deprecated()); 148357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!value->FitsRepresentation(target_details.representation())) { 14848b363d4621a720d7a111f30bf168a09f82127ef2verwaest@chromium.org Handle<Map> target(lookup->GetTransitionTarget()); 148557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Map::GeneralizeRepresentation( 14869259716434187c932704601f700375e53d865de8rossberg@chromium.org target, target->LastAdded(), 14879259716434187c932704601f700375e53d865de8rossberg@chromium.org value->OptimalRepresentation(), FORCE_FIELD); 14888a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // Lookup the transition again since the transition tree may have changed 14898a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org // entirely by the migration above. 14908a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org receiver->map()->LookupTransition(*holder, *name, lookup); 14918a00e82ec5c3dbedfd3dcb56996c7df2452da4a5verwaest@chromium.org if (!lookup->IsTransition()) return false; 1492fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ic->MarkMonomorphicPrototypeFailure(); 149357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 149457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org return true; 14955aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 14965aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 14975aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 1498fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgMaybeObject* StoreIC::Store(Handle<Object> object, 1499003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<String> name, 1500003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org Handle<Object> value, 1501003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org JSReceiver::StoreFromKeyed store_mode) { 1502d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (MigrateDeprecated(object) || object->IsJSProxy()) { 1503528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Handle<Object> result = JSReceiver::SetProperty( 1504fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<JSReceiver>::cast(object), name, value, NONE, strict_mode()); 1505528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org RETURN_IF_EMPTY_HANDLE(isolate(), result); 1506528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return *result; 15076bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 1508c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 15096bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // If the object is undefined or null it's illegal to try to set any 15106bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // properties on it; throw a TypeError in that case. 15116bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (object->IsUndefined() || object->IsNull()) { 15126bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org return TypeError("non_object_property_store", object, name); 15136bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 151443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15156bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // The length property of string values is read-only. Throw in strict mode. 1516fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (strict_mode() == kStrictMode && object->IsString() && 15174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org name->Equals(isolate()->heap()->length_string())) { 15186bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org return TypeError("strict_read_only_property", object, name); 15198f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org } 15208f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org 15216bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // Ignore other stores where the receiver is not a JSObject. 15226bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // TODO(1475): Must check prototype chains of object wrappers. 15236bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (!object->IsJSObject()) return *value; 15246bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org 152543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Handle<JSObject> receiver = Handle<JSObject>::cast(object); 152643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 152743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check if the given name is an array index. 152843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t index; 152943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (name->AsArrayIndex(&index)) { 1530f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com Handle<Object> result = 1531fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org JSObject::SetElement(receiver, index, value, NONE, strict_mode()); 1532394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com RETURN_IF_EMPTY_HANDLE(isolate(), result); 153343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return *value; 153443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 153543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1536e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Observed objects are always modified through the runtime. 1537e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org if (FLAG_harmony_observation && receiver->map()->is_observed()) { 1538528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Handle<Object> result = JSReceiver::SetProperty( 1539fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org receiver, name, value, NONE, strict_mode(), store_mode); 1540528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org RETURN_IF_EMPTY_HANDLE(isolate(), result); 1541528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return *result; 1542e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 1543e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 15447ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org // Use specialized code for setting the length of arrays with fast 15456bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // properties. Slow properties might indicate redefinition of the length 15461bc70abe0daf6c4ffb92b6c0783d8a4a6ed091b8danno@chromium.org // property. Note that when redefined using Object.freeze, it's possible 15471bc70abe0daf6c4ffb92b6c0783d8a4a6ed091b8danno@chromium.org // to have fast properties but a read-only length. 1548d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (FLAG_use_ic && 15496bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org receiver->IsJSArray() && 15504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org name->Equals(isolate()->heap()->length_string()) && 15517ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() && 15521bc70abe0daf6c4ffb92b6c0783d8a4a6ed091b8danno@chromium.org receiver->HasFastProperties() && 15531bc70abe0daf6c4ffb92b6c0783d8a4a6ed091b8danno@chromium.org !receiver->map()->is_frozen()) { 15548432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<Code> stub = 1555fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org StoreArrayLengthStub(kind(), strict_mode()).GetCode(isolate()); 1556394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com set_target(*stub); 1557d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org TRACE_IC("StoreIC", name); 1558528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Handle<Object> result = JSReceiver::SetProperty( 1559fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org receiver, name, value, NONE, strict_mode(), store_mode); 1560528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org RETURN_IF_EMPTY_HANDLE(isolate(), result); 1561528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return *result; 1562ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org } 1563ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 15646bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org LookupResult lookup(isolate()); 1565fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org bool can_store = LookupForWrite(receiver, name, value, &lookup, this); 15663d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org if (!can_store && 1567fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org strict_mode() == kStrictMode && 15683d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org !(lookup.IsProperty() && lookup.IsReadOnly()) && 15693d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org IsUndeclaredGlobal(object)) { 1570c47dff5fc3b12ecc3a7a9fc61fbd02868548dde6mvstanton@chromium.org // Strict mode doesn't allow setting non-existent global property. 15716bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org return ReferenceError("not_defined", name); 15723d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org } 1573d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (FLAG_use_ic) { 1574fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == UNINITIALIZED) { 1575fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<Code> stub = pre_monomorphic_stub(); 15763d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org set_target(*stub); 1577d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org TRACE_IC("StoreIC", name); 15783d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org } else if (can_store) { 1579fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org UpdateCaches(&lookup, receiver, name, value); 15803d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org } else if (!name->IsCacheable(isolate()) || 15813d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org lookup.IsNormal() || 15823d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org (lookup.IsField() && lookup.CanHoldValue(value))) { 1583fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org Handle<Code> stub = generic_stub(); 15843d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org set_target(*stub); 15853d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org } 1586a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 1587a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set the property. 1589528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org Handle<Object> result = JSReceiver::SetProperty( 1590fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org receiver, name, value, NONE, strict_mode(), store_mode); 1591528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org RETURN_IF_EMPTY_HANDLE(isolate(), result); 1592528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org return *result; 159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 159543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1596d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.orgvoid StoreIC::UpdateCaches(LookupResult* lookup, 1597d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org Handle<JSObject> receiver, 1598d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org Handle<String> name, 1599d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org Handle<Object> value) { 16007a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org ASSERT(lookup->IsFound()); 16017a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org 1602c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org // These are not cacheable, so we never see such LookupResults here. 1603de0db002768654f346a9059d80ab47602018bfa0yangguo@chromium.org ASSERT(!lookup->IsHandler()); 160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16052efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<Code> code = ComputeHandler(lookup, receiver, name, value); 1606d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 1607f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org PatchCache(CurrentTypeOf(receiver, isolate()), name, code); 1608d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org TRACE_IC("StoreIC", name); 1609d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org} 1610d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 161143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 16122efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.orgHandle<Code> StoreIC::CompileHandler(LookupResult* lookup, 1613b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Object> object, 16142efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org Handle<String> name, 1615b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Object> value, 1616b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org InlineCacheHolderFlag cache_holder) { 16178a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org if (object->IsJSGlobalProxy()) return slow_stub(); 1618b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ASSERT(cache_holder == OWN_MAP); 1619b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // This is currently guaranteed by checks in StoreIC::Store. 1620b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1621b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 16227028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org Handle<JSObject> holder(lookup->holder()); 1623c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org // Handlers do not use strict mode. 1624c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org StoreStubCompiler compiler(isolate(), kNonStrictMode, kind()); 1625d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org switch (lookup->type()) { 1626394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com case FIELD: 16272efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return compiler.CompileStoreField(receiver, lookup, name); 16282efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org case TRANSITION: { 16292efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org // Explicitly pass in the receiver map since LookupForWrite may have 16302efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org // stored something else than the receiver in the holder. 16318b363d4621a720d7a111f30bf168a09f82127ef2verwaest@chromium.org Handle<Map> transition(lookup->GetTransitionTarget()); 16328b363d4621a720d7a111f30bf168a09f82127ef2verwaest@chromium.org PropertyDetails details = transition->GetLastDescriptorDetails(); 16332efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 16342efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (details.type() == CALLBACKS || details.attributes() != NONE) break; 16352efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 16362efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return compiler.CompileStoreTransition( 16372efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org receiver, lookup, transition, name); 16382efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } 1639394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com case NORMAL: 16402efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (kind() == Code::KEYED_STORE_IC) break; 164169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org if (receiver->IsGlobalObject()) { 164269ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // The stub generated for the global object picks the value directly 164369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // from the property cell. So the property must be directly on the 164469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org // global object. 164569ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 1646e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate()); 1647e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Type> union_type = PropertyCell::UpdatedType(cell, value); 1648c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org StoreGlobalStub stub(union_type->IsConstant()); 1649e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 1650e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Code> code = stub.GetCodeCopyFromTemplate( 1651e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org isolate(), receiver->map(), *cell); 1652e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 1653e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org HeapObject::UpdateMapCodeCache(receiver, name, code); 1654e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return code; 16552abc450936e88b5c98a5e9d43ee6230ccc748272kasperl@chromium.org } 1656f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org ASSERT(holder.is_identical_to(receiver)); 1657c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org return isolate()->builtins()->StoreIC_Normal(); 165843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen case CALLBACKS: { 16592efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (kind() == Code::KEYED_STORE_IC) break; 166009d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org Handle<Object> callback(lookup->GetCallbackObject(), isolate()); 16617c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (callback->IsExecutableAccessorInfo()) { 16627c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Handle<ExecutableAccessorInfo> info = 16637c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org Handle<ExecutableAccessorInfo>::cast(callback); 1664d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org if (v8::ToCData<Address>(info->setter()) == 0) break; 1665d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org if (!holder->HasFastProperties()) break; 1666d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org if (!info->IsCompatibleReceiver(*receiver)) break; 16672efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return compiler.CompileStoreCallback(receiver, holder, name, info); 16687028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } else if (callback->IsAccessorPair()) { 16697bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<Object> setter( 16707bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<AccessorPair>::cast(callback)->setter(), isolate()); 1671d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org if (!setter->IsJSFunction()) break; 1672d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org if (holder->IsGlobalObject()) break; 1673d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org if (!holder->HasFastProperties()) break; 1674639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org Handle<JSFunction> function = Handle<JSFunction>::cast(setter); 1675639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org CallOptimization call_optimization(function); 1676639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org if (call_optimization.is_simple_api_call() && 1677528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org call_optimization.IsCompatibleReceiver(*receiver)) { 16782efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return compiler.CompileStoreCallback( 16792efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org receiver, holder, name, call_optimization); 1680639bac0c5319f96e1bbe3399fb7f7f37344928bddslomov@chromium.org } 16812efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return compiler.CompileStoreViaSetter( 16822efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org receiver, holder, name, Handle<JSFunction>::cast(setter)); 16837028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org } 16847c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org // TODO(dcarney): Handle correctly. 16857c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org if (callback->IsDeclaredAccessorInfo()) break; 1686d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org ASSERT(callback->IsForeign()); 1687d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org // No IC support for old-style native accessors. 168843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen break; 168943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1690394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com case INTERCEPTOR: 16912efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (kind() == Code::KEYED_STORE_IC) break; 1692fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ASSERT(HasInterceptorSetter(*receiver)); 16932efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return compiler.CompileStoreInterceptor(receiver, name); 1694fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org case CONSTANT: 1695d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org break; 16967a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org case NONEXISTENT: 1697c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org case HANDLER: 1698c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org UNREACHABLE(); 169959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org break; 170043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 17012efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return slow_stub(); 170243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 170343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 170443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1705003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgHandle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, 1706fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org KeyedAccessStoreMode store_mode) { 1707ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1708ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // via megamorphic stubs, since they don't have a map in their relocation info 1709ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // and so the stubs can't be harvested for the object needed for a map check. 17107a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org if (target()->type() != Code::NORMAL) { 1711c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); 1712fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 1713ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 1714ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 17157bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<Map> receiver_map(receiver->map(), isolate()); 1716fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == UNINITIALIZED || state() == PREMONOMORPHIC) { 17177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 17187028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org // yet will do so and stay there. 1719750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); 1720750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org store_mode = GetNonTransitioningStoreMode(store_mode); 1721003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return isolate()->stub_cache()->ComputeKeyedStoreElement( 1722fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org monomorphic_map, strict_mode(), store_mode); 1723003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1724003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1725750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org MapHandleList target_receiver_maps; 1726750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org target()->FindAllMaps(&target_receiver_maps); 1727068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org if (target_receiver_maps.length() == 0) { 1728750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // In the case that there is a non-map-specific IC is installed (e.g. keyed 1729750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // stores into properties in dictionary mode), then there will be not 1730750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // receiver maps in the target. 1731fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 1732068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org } 1733750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 1734750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // There are several special cases where an IC that is MONOMORPHIC can still 1735750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // transition to a different GetNonTransitioningStoreMode IC that handles a 1736750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // superset of the original IC. Handle those here if the receiver map hasn't 1737750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // changed or it has transitioned to a more general kind. 1738750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org KeyedAccessStoreMode old_store_mode = 1739cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); 1740750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Map> previous_receiver_map = target_receiver_maps.at(0); 1741fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == MONOMORPHIC) { 1742750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // If the "old" and "new" maps are in the same elements map family, stay 1743750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // MONOMORPHIC and use the map for the most generic ElementsKind. 1744750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Map> transitioned_receiver_map = receiver_map; 1745750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (IsTransitionStoreMode(store_mode)) { 1746750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org transitioned_receiver_map = 1747750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org ComputeTransitionedMap(receiver, store_mode); 1748750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 1749af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (IsTransitionOfMonomorphicTarget(MapToType(transitioned_receiver_map))) { 1750750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // Element family is the same, use the "worst" case map. 1751750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org store_mode = GetNonTransitioningStoreMode(store_mode); 1752750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return isolate()->stub_cache()->ComputeKeyedStoreElement( 1753fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org transitioned_receiver_map, strict_mode(), store_mode); 1754169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org } else if (*previous_receiver_map == receiver->map() && 1755169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org old_store_mode == STANDARD_STORE && 1756169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org (IsGrowStoreMode(store_mode) || 1757169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1758169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { 1759169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // A "normal" IC that handles stores can switch to a version that can 1760169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // grow at the end of the array, handle OOB accesses or copy COW arrays 1761169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // and still stay MONOMORPHIC. 1762169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org return isolate()->stub_cache()->ComputeKeyedStoreElement( 1763fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org receiver_map, strict_mode(), store_mode); 1764750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 176565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 176665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 1767fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org ASSERT(state() != GENERIC); 176865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 1769b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org bool map_added = 1770394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1771003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1772750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (IsTransitionStoreMode(store_mode)) { 1773750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Map> transitioned_receiver_map = 1774750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org ComputeTransitionedMap(receiver, store_mode); 1775750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, 1776750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org transitioned_receiver_map); 1777b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } 1778003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1779b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (!map_added) { 1780b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // If the miss wasn't due to an unseen map, a polymorphic stub 1781ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // won't help, use the generic stub. 1782c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); 1783fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 1784ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 1785ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1786e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org // If the maximum number of receiver maps has been exceeded, use the generic 1787ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // version of the IC. 17887b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1789c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); 1790fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 1791ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 1792ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1793750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // Make sure all polymorphic handlers have the same store mode, otherwise the 1794750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // generic stub must be used. 1795750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org store_mode = GetNonTransitioningStoreMode(store_mode); 1796750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (old_store_mode != STANDARD_STORE) { 1797750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (store_mode == STANDARD_STORE) { 1798750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org store_mode = old_store_mode; 1799750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else if (store_mode != old_store_mode) { 1800750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedIC", "store mode mismatch"); 1801fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 1802750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 180365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 180465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 180591efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org // If the store mode isn't the standard mode, make sure that all polymorphic 180691efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org // receivers are either external arrays, or all "normal" arrays. Otherwise, 180791efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org // use the generic stub. 180891efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org if (store_mode != STANDARD_STORE) { 180991efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org int external_arrays = 0; 181091efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org for (int i = 0; i < target_receiver_maps.length(); ++i) { 181191efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org if (target_receiver_maps[i]->has_external_array_elements()) { 181291efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org external_arrays++; 181391efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org } 181491efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org } 181591efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org if (external_arrays != 0 && 181691efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org external_arrays != target_receiver_maps.length()) { 181791efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedIC", 181891efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org "unsupported combination of external and normal arrays"); 1819fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 182091efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org } 182191efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org } 182291efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org 1823003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return isolate()->stub_cache()->ComputeStoreElementPolymorphic( 1824fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org &target_receiver_maps, store_mode, strict_mode()); 1825ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 1826ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1827ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1828750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgHandle<Map> KeyedStoreIC::ComputeTransitionedMap( 1829750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<JSObject> receiver, 1830750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org KeyedAccessStoreMode store_mode) { 1831750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org switch (store_mode) { 1832003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_SMI_TO_OBJECT: 1833003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_DOUBLE_TO_OBJECT: 1834003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: 1835003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT: 1836394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS); 1837003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_SMI_TO_DOUBLE: 1838003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE: 1839394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS); 1840003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT: 1841003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: 1842003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT: 1843003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: 1844830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return JSObject::GetElementsTransitionMap(receiver, 1845830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FAST_HOLEY_ELEMENTS); 1846003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE: 1847003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE: 1848830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return JSObject::GetElementsTransitionMap(receiver, 1849830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org FAST_HOLEY_DOUBLE_ELEMENTS); 1850750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: 1851750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org ASSERT(receiver->map()->has_external_array_elements()); 1852750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // Fall through 1853750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org case STORE_NO_TRANSITION_HANDLE_COW: 1854750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org case STANDARD_STORE: 1855003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_NO_TRANSITION: 18567bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org return Handle<Map>(receiver->map(), isolate()); 1857b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } 1858830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return Handle<Map>::null(); 1859b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org} 1860b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 1861b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 1862750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgbool IsOutOfBoundsAccess(Handle<JSObject> receiver, 1863750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org int index) { 1864750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (receiver->IsJSArray()) { 1865750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return JSArray::cast(*receiver)->length()->IsSmi() && 1866750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org index >= Smi::cast(JSArray::cast(*receiver)->length())->value(); 1867750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 1868750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return index >= receiver->elements()->length(); 1869750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 1870750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 1871750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 1872750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgKeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver, 1873750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Object> key, 1874750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Object> value) { 18757bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ASSERT(!key->ToSmi()->IsFailure()); 18767bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Smi* smi_key = NULL; 18777bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org key->ToSmi()->To(&smi_key); 18787bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org int index = smi_key->value(); 1879750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org bool oob_access = IsOutOfBoundsAccess(receiver, index); 1880750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org bool allow_growth = receiver->IsJSArray() && oob_access; 188165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (allow_growth) { 188265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Handle growing array in stub if necessary. 1883830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastSmiElements()) { 188465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (value->IsHeapNumber()) { 1885830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1886830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE; 1887830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1888830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE; 1889830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 189065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 189165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (value->IsHeapObject()) { 1892830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1893830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT; 1894830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1895830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT; 1896830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 189765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 189865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } else if (receiver->HasFastDoubleElements()) { 189965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (!value->IsSmi() && !value->IsHeapNumber()) { 1900830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1901830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT; 1902830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1903830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT; 1904830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 190565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 190665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 190765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org return STORE_AND_GROW_NO_TRANSITION; 190865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } else { 190965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Handle only in-bounds elements accesses. 1910830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastSmiElements()) { 191165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (value->IsHeapNumber()) { 1912830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1913830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE; 1914830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1915830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_SMI_TO_DOUBLE; 1916830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 191765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } else if (value->IsHeapObject()) { 1918830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1919830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_HOLEY_SMI_TO_OBJECT; 1920830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1921830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_SMI_TO_OBJECT; 1922830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 192365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 192465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } else if (receiver->HasFastDoubleElements()) { 192565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (!value->IsSmi() && !value->IsHeapNumber()) { 1926830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1927830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT; 1928830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1929830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_DOUBLE_TO_OBJECT; 1930830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 193165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 193265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 1933750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (!FLAG_trace_external_array_abuse && 1934750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org receiver->map()->has_external_array_elements() && oob_access) { 1935750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS; 19367bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 19377bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Heap* heap = receiver->GetHeap(); 19387bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org if (receiver->elements()->map() == heap->fixed_cow_array_map()) { 19397bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org return STORE_NO_TRANSITION_HANDLE_COW; 1940750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else { 1941750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return STANDARD_STORE; 1942750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 194365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 194465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org} 194565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 194665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 1947fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.orgMaybeObject* KeyedStoreIC::Store(Handle<Object> object, 1948303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Handle<Object> key, 1949b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Object> value) { 1950d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (MigrateDeprecated(object)) { 1951e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Object> result = Runtime::SetObjectProperty(isolate(), object, 1952e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org key, 1953e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org value, 1954e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org NONE, 1955e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org strict_mode()); 1956e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org RETURN_IF_EMPTY_HANDLE(isolate(), result); 1957e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return *result; 1958d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 1959d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 19604a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // Check for values that can be converted into an internalized string directly 19614a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // or is representable as a smi. 196228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org key = TryConvertKey(key, isolate()); 196328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 1964c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org MaybeObject* maybe_object = NULL; 1965c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Handle<Code> stub = generic_stub(); 196643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1967c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (key->IsInternalizedString()) { 1968c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org maybe_object = StoreIC::Store(object, 1969c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Handle<String>::cast(key), 1970c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org value, 1971c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org JSReceiver::MAY_BE_STORE_FROM_KEYED); 1972c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (maybe_object->IsFailure()) return maybe_object; 1973c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } else { 1974c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() && 1975c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org !(FLAG_harmony_observation && object->IsJSObject() && 1976c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org JSObject::cast(*object)->map()->is_observed()); 1977c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (use_ic && !object->IsSmi()) { 1978c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // Don't use ICs for maps of the objects in Array's prototype chain. We 1979c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // expect to be able to trap element sets to objects with those maps in 1980c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org // the runtime to enable optimization of element hole access. 1981c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); 1982c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false; 1983c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 1984d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1985c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (use_ic) { 1986c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org ASSERT(!object->IsJSGlobalProxy()); 1987c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 1988b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (object->IsJSObject()) { 1989b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1990b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org bool key_is_smi_like = key->IsSmi() || !key->ToSmi()->IsFailure(); 1991b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (receiver->elements()->map() == 1992b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org isolate()->heap()->non_strict_arguments_elements_map()) { 1993b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org stub = non_strict_arguments_stub(); 1994b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else if (key_is_smi_like && 1995b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org !(target().is_identical_to(non_strict_arguments_stub()))) { 1996b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // We should go generic if receiver isn't a dictionary, but our 1997b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // prototype chain does have dictionary elements. This ensures that 1998b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // other non-dictionary receivers in the polymorphic case benefit 1999b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // from fast path keyed stores. 2000b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) { 2001b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org KeyedAccessStoreMode store_mode = 2002b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org GetStoreMode(receiver, key, value); 2003b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org stub = StoreElementStub(receiver, store_mode); 2004c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 20057b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 20063811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 2007c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 2008c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 2009c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 2010c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (!is_target_set()) { 2011c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (*stub == *generic_stub()) { 2012c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 20133811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 2014d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org ASSERT(!stub.is_null()); 2015d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org set_target(*stub); 2016d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org TRACE_IC("StoreIC", key); 20173811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 201843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2019c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (maybe_object) return maybe_object; 2020e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Object> result = Runtime::SetObjectProperty(isolate(), object, key, 2021e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org value, 2022e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org NONE, 2023e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org strict_mode()); 2024e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org RETURN_IF_EMPTY_HANDLE(isolate(), result); 2025e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return *result; 202643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 202743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 202843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2029394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#undef TRACE_IC 2030394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2031394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 203243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 203343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Static IC stub generators. 203443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 203543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20361af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc. 2037c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) { 2038394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HandleScope scope(isolate); 203943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(args.length() == 2); 2040ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org CallIC ic(isolate); 2041d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2042d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<String> key = args.at<String>(1); 2043d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2044d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org MaybeObject* maybe_result = ic.LoadFunction(receiver, key); 204559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org JSFunction* raw_function; 2046394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!maybe_result->To(&raw_function)) return maybe_result; 204771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org 204871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // The first time the inline cache is updated may be the first time the 204959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // function it references gets called. If the function is lazily compiled 205059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org // then the first call will trigger a compilation. We check for this case 205171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // and we do the compilation immediately, instead of waiting for the stub 2052394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // currently attached to the JSFunction object to trigger compilation. 2053394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (raw_function->is_compiled()) return raw_function; 2054394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2055394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com Handle<JSFunction> function(raw_function); 2056394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSFunction::CompileLazy(function, CLEAR_EXCEPTION); 2057394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return *function; 20581af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org} 20593bf7b91c90e9bff46f53eec55055d2d1a1949215ager@chromium.org 20601af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 20611af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc. 2062c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { 2063394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HandleScope scope(isolate); 20641af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org ASSERT(args.length() == 2); 2065ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org KeyedCallIC ic(isolate); 2066d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2067d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> key = args.at<Object>(1); 2068d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2069d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org MaybeObject* maybe_result = ic.LoadFunction(receiver, key); 2070394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Result could be a function or a failure. 2071394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSFunction* raw_function = NULL; 2072394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!maybe_result->To(&raw_function)) return maybe_result; 20731af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org 2074394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (raw_function->is_compiled()) return raw_function; 2075394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 20767bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<JSFunction> function(raw_function, isolate); 2077394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com JSFunction::CompileLazy(function, CLEAR_EXCEPTION); 2078394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return *function; 207943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 208043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 208143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20821af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc. 2083c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { 2084394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HandleScope scope(isolate); 208543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(args.length() == 2); 2086e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2087d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2088d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<String> key = args.at<String>(1); 2089d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2090d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return ic.Load(receiver, key); 209143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 209243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 209343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20941af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc 2095c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) { 2096394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HandleScope scope(isolate); 209743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(args.length() == 2); 2098e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2099d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2100d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> key = args.at<Object>(1); 2101d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2102b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return ic.Load(receiver, key); 2103e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 2104e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 2105e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 2106e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) { 2107e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org HandleScope scope(isolate); 2108e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org ASSERT(args.length() == 2); 2109e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate); 2110d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2111d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> key = args.at<Object>(1); 2112d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2113b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return ic.Load(receiver, key); 2114ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 2115ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2116ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 21171af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc. 2118c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { 2119c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org HandleScope scope(isolate); 212043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(args.length() == 3); 21217bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2122d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2123d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<String> key = args.at<String>(1); 2124d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2125d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return ic.Store(receiver, key, args.at<Object>(2)); 212643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 212743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 212843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2129e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.orgRUNTIME_FUNCTION(MaybeObject*, StoreIC_MissFromStubFailure) { 2130e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org HandleScope scope(isolate); 2131e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org ASSERT(args.length() == 3); 2132e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2133d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2134d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<String> key = args.at<String>(1); 2135d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2136d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return ic.Store(receiver, key, args.at<Object>(2)); 2137e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org} 2138e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 2139e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 2140ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.orgRUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_MissFromStubFailure) { 2141ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org HandleScope scope(isolate); 2142ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ASSERT(args.length() == 2); 2143ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org KeyedCallIC ic(isolate); 2144ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Arguments* caller_args = reinterpret_cast<Arguments*>(args[0]); 2145ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Handle<Object> key = args.at<Object>(1); 2146ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Handle<Object> receiver((*caller_args)[0], isolate); 2147ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 2148ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org ic.UpdateState(receiver, key); 2149ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org MaybeObject* maybe_result = ic.LoadFunction(receiver, key); 2150ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org // Result could be a function or a failure. 2151ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org JSFunction* raw_function = NULL; 2152ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (!maybe_result->To(&raw_function)) return maybe_result; 2153ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 2154ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org if (raw_function->is_compiled()) return raw_function; 2155ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 2156ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org Handle<JSFunction> function(raw_function, isolate); 2157ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org JSFunction::CompileLazy(function, CLEAR_EXCEPTION); 2158ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org return *function; 2159ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org} 2160ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 2161ea468886ebe54afda9c81df0e85eea04bbb4f0f2machenbach@chromium.org 2162c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { 216379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org SealHandleScope shs(isolate); 21645c838251403b0be9a882540f1922577abba4c872ager@chromium.org 21655c838251403b0be9a882540f1922577abba4c872ager@chromium.org ASSERT(args.length() == 2); 21667ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org JSArray* receiver = JSArray::cast(args[0]); 21675c838251403b0be9a882540f1922577abba4c872ager@chromium.org Object* len = args[1]; 21685c838251403b0be9a882540f1922577abba4c872ager@chromium.org 2169303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org // The generated code should filter out non-Smis before we get here. 2170303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org ASSERT(len->IsSmi()); 2171303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org 21727ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org#ifdef DEBUG 21737ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org // The length property has to be a writable callback property. 21747ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org LookupResult debug_lookup(isolate); 21754a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org receiver->LocalLookup(isolate->heap()->length_string(), &debug_lookup); 2176753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly()); 21777ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org#endif 21787ad65226b3ba6f9250a5ee869ee77e2b9258fc91ricow@chromium.org 2179303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Object* result; 2180d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org MaybeObject* maybe_result = receiver->SetElementsLength(len); 2181d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org if (!maybe_result->To(&result)) return maybe_result; 2182d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 2183ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org return len; 21845c838251403b0be9a882540f1922577abba4c872ager@chromium.org} 21855c838251403b0be9a882540f1922577abba4c872ager@chromium.org 21865c838251403b0be9a882540f1922577abba4c872ager@chromium.org 218741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org// Extend storage is called in a store inline cache when 218841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org// it is necessary to extend the properties array of a 218941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org// JSObject. 2190c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, SharedStoreIC_ExtendStorage) { 219179e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org SealHandleScope shs(isolate); 219241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org ASSERT(args.length() == 3); 219341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 219441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Convert the parameters 219541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org JSObject* object = JSObject::cast(args[0]); 219641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org Map* transition = Map::cast(args[1]); 219741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org Object* value = args[2]; 219841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 219941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Check the object has run out out property space. 220041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org ASSERT(object->HasFastProperties()); 220141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org ASSERT(object->map()->unused_property_fields() == 0); 220241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 220341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Expand the properties array. 220441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org FixedArray* old_storage = object->properties(); 220541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org int new_unused = transition->unused_property_fields(); 220641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org int new_size = old_storage->length() + new_unused + 1; 2207303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org Object* result; 220857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org MaybeObject* maybe_result = old_storage->CopySize(new_size); 220957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!maybe_result->ToObject(&result)) return maybe_result; 221057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 221141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org FixedArray* new_storage = FixedArray::cast(result); 221257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 221357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Object* to_store = value; 221457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 221557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (FLAG_track_double_fields) { 221657ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org DescriptorArray* descriptors = transition->instance_descriptors(); 221757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org PropertyDetails details = descriptors->GetDetails(transition->LastAdded()); 221857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (details.representation().IsDouble()) { 221957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org MaybeObject* maybe_storage = 222057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org isolate->heap()->AllocateHeapNumber(value->Number()); 222157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org if (!maybe_storage->To(&to_store)) return maybe_storage; 222257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 222357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 222457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 222557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org new_storage->set(old_storage->length(), to_store); 222641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 22273291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org // Set the new property value and do the map transition. 222841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org object->set_properties(new_storage); 222941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org object->set_map(transition); 223041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 223141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Return the stored value. 223241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org return value; 223341044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org} 223441044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 223541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 22361af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc. 2237c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { 2238394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HandleScope scope(isolate); 223943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(args.length() == 3); 22407bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2241d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2242d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> key = args.at<Object>(1); 2243d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2244b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return ic.Store(receiver, key, args.at<Object>(2)); 22457bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org} 22467bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 22477bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 22487bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissFromStubFailure) { 22497bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org HandleScope scope(isolate); 22507bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org ASSERT(args.length() == 3); 22517bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2252d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2253d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> key = args.at<Object>(1); 2254d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2255b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return ic.Store(receiver, key, args.at<Object>(2)); 2256ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 2257ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2258ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 225957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, StoreIC_Slow) { 2260fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HandleScope scope(isolate); 226157ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org ASSERT(args.length() == 3); 226257ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 226357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Object> object = args.at<Object>(0); 226457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Object> key = args.at<Object>(1); 226557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Object> value = args.at<Object>(2); 2266fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org StrictModeFlag strict_mode = ic.strict_mode(); 2267e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key, 2268e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org value, 2269e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org NONE, 2270e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org strict_mode); 2271e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org RETURN_IF_EMPTY_HANDLE(isolate, result); 2272e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return *result; 227357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org} 227457ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 227557ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 2276ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgRUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) { 2277fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HandleScope scope(isolate); 2278ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org ASSERT(args.length() == 3); 22797bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2280ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Object> object = args.at<Object>(0); 2281ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Object> key = args.at<Object>(1); 2282ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Object> value = args.at<Object>(2); 2283fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org StrictModeFlag strict_mode = ic.strict_mode(); 2284e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key, 2285e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org value, 2286e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org NONE, 2287e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org strict_mode); 2288e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org RETURN_IF_EMPTY_HANDLE(isolate, result); 2289e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return *result; 2290ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 2291ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2292ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2293ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, ElementsTransitionAndStoreIC_Miss) { 2294fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HandleScope scope(isolate); 2295ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org ASSERT(args.length() == 4); 2296ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2297ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Object> value = args.at<Object>(0); 2298e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Map> map = args.at<Map>(1); 2299ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Object> key = args.at<Object>(2); 2300ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Object> object = args.at<Object>(3); 2301fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org StrictModeFlag strict_mode = ic.strict_mode(); 2302e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (object->IsJSObject()) { 2303e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), 2304e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org map->elements_kind()); 2305e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 2306e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Object> result = Runtime::SetObjectProperty(isolate, object, key, 2307e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org value, 2308e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org NONE, 2309e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org strict_mode); 2310e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org RETURN_IF_EMPTY_HANDLE(isolate, result); 2311e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return *result; 2312ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 2313ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2314ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2315ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgBinaryOpIC::State::State(ExtraICState extra_ic_state) { 2316ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // We don't deserialize the SSE2 Field, since this is only used to be able 2317ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // to include SSE2 as well as non-SSE2 versions in the snapshot. For code 2318ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // generation we always want it to reflect the current state. 2319ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org op_ = static_cast<Token::Value>( 2320ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org FIRST_TOKEN + OpField::decode(extra_ic_state)); 2321ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org mode_ = OverwriteModeField::decode(extra_ic_state); 2322ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org fixed_right_arg_ = Maybe<int>( 2323ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org HasFixedRightArgField::decode(extra_ic_state), 2324ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 1 << FixedRightArgValueField::decode(extra_ic_state)); 2325ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org left_kind_ = LeftKindField::decode(extra_ic_state); 2326ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (fixed_right_arg_.has_value) { 2327ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org right_kind_ = Smi::IsValid(fixed_right_arg_.value) ? SMI : INT32; 2328ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 2329ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org right_kind_ = RightKindField::decode(extra_ic_state); 2330ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2331ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org result_kind_ = ResultKindField::decode(extra_ic_state); 2332ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSERT_LE(FIRST_TOKEN, op_); 2333ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSERT_LE(op_, LAST_TOKEN); 2334ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org} 2335ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2336ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2337ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgExtraICState BinaryOpIC::State::GetExtraICState() const { 2338ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org bool sse2 = (Max(result_kind_, Max(left_kind_, right_kind_)) > SMI && 2339ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org CpuFeatures::IsSafeForSnapshot(SSE2)); 2340ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ExtraICState extra_ic_state = 2341ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org SSE2Field::encode(sse2) | 2342ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org OpField::encode(op_ - FIRST_TOKEN) | 2343ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org OverwriteModeField::encode(mode_) | 2344ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org LeftKindField::encode(left_kind_) | 2345ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ResultKindField::encode(result_kind_) | 2346ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org HasFixedRightArgField::encode(fixed_right_arg_.has_value); 2347ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (fixed_right_arg_.has_value) { 2348ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org extra_ic_state = FixedRightArgValueField::update( 2349ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org extra_ic_state, WhichPowerOf2(fixed_right_arg_.value)); 2350ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 2351ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org extra_ic_state = RightKindField::update(extra_ic_state, right_kind_); 2352ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2353ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org return extra_ic_state; 2354ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org} 2355ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2356ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2357ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org// static 2358ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgvoid BinaryOpIC::State::GenerateAheadOfTime( 2359ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Isolate* isolate, void (*Generate)(Isolate*, const State&)) { 2360ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // TODO(olivf) We should investigate why adding stubs to the snapshot is so 2361ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // expensive at runtime. When solved we should be able to add most binops to 2362ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // the snapshot instead of hand-picking them. 2363ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Generated list of commonly used stubs 2364ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org#define GENERATE(op, left_kind, right_kind, result_kind, mode) \ 2365ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org do { \ 2366ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org State state(op, mode); \ 2367ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.left_kind_ = left_kind; \ 2368ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.fixed_right_arg_.has_value = false; \ 2369ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.right_kind_ = right_kind; \ 2370ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.result_kind_ = result_kind; \ 2371ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Generate(isolate, state); \ 2372ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } while (false) 2373ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE); 2374ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT); 2375ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE); 2376ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT); 2377ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE); 2378ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT); 2379ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT); 2380ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE); 2381ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT); 2382ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT); 2383ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE); 2384ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT); 2385ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT); 2386ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE); 2387ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT); 2388ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT); 2389ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE); 2390ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); 2391ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT); 2392ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE); 2393ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT); 2394ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE); 2395ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE); 2396ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT); 2397ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT); 2398ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT); 2399ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT); 2400ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE); 2401ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT); 2402ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT); 2403ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE); 2404ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT); 2405ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE); 2406ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT); 2407ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE); 2408ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT); 2409ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT); 2410ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT); 2411ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE); 2412ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT); 2413ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE); 2414ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT); 2415ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT); 2416ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE); 2417ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT); 2418ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT); 2419ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT); 2420ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT); 2421ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT); 2422ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE); 2423ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT); 2424ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT); 2425ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE); 2426ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT); 2427ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE); 2428ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT); 2429ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT); 2430ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE); 2431ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT); 2432ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT); 2433ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT); 2434ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT); 2435ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT); 2436ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT); 2437ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE); 2438ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT); 2439ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT); 2440ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE); 2441ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT); 2442ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE); 2443ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE); 2444ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT); 2445ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT); 2446ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE); 2447ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE); 2448ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE); 2449ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE); 2450ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT); 2451ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT); 2452ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE); 2453ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT); 2454ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT); 2455ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE); 2456ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE); 2457ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE); 2458ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT); 2459ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE); 2460ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE); 2461ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE); 2462ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT); 2463ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE); 2464ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT); 2465ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT); 2466ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE); 2467ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); 2468ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE); 2469ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE); 2470ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT); 2471ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE); 2472ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT); 2473ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT); 2474ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE); 2475ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT); 2476ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT); 2477ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE); 2478ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT); 2479ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT); 2480ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); 2481ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE); 2482ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT); 2483ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE); 2484ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE); 2485ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE); 2486ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT); 2487ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE); 2488ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT); 2489ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE); 2490ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE); 2491ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT); 2492ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT); 2493ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE); 2494ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT); 2495ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE); 2496ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); 2497ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT); 2498ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE); 2499ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT); 2500ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE); 2501ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE); 2502ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT); 2503ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT); 2504ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE); 2505ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE); 2506ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT); 2507ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE); 2508ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT); 2509ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT); 2510ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT); 2511ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE); 2512ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT); 2513ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE); 2514ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT); 2515ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT); 2516ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT); 2517ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE); 2518ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT); 2519ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE); 2520ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT); 2521ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT); 2522ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE); 2523ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT); 2524ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT); 2525ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE); 2526ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT); 2527ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT); 2528ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE); 2529ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT); 2530ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT); 2531ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE); 2532ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT); 2533ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT); 2534ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE); 2535ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT); 2536ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT); 2537ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE); 2538ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT); 2539ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE); 2540ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT); 2541ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT); 2542ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT); 2543ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE); 2544ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT); 2545ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE); 2546ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT); 2547ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT); 2548ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE); 2549ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT); 2550ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT); 2551ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE); 2552ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE); 2553ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT); 2554ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT); 2555ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE); 2556ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT); 2557ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT); 2558ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org#undef GENERATE 2559ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind, mode) \ 2560ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org do { \ 2561ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org State state(op, mode); \ 2562ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.left_kind_ = left_kind; \ 2563ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.fixed_right_arg_.has_value = true; \ 2564ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.fixed_right_arg_.value = fixed_right_arg_value; \ 2565ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.right_kind_ = SMI; \ 2566ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.result_kind_ = result_kind; \ 2567ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Generate(isolate, state); \ 2568ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } while (false) 2569ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, SMI, 2, SMI, NO_OVERWRITE); 2570ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE); 2571ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT); 2572ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE); 2573ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT); 2574ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE); 2575ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); 2576ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org#undef GENERATE 2577ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org} 2578ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2579ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2580ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgHandle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const { 2581ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Kind result_kind = result_kind_; 2582ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (HasSideEffects()) { 2583ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org result_kind = NONE; 2584ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else if (result_kind == GENERIC && op_ == Token::ADD) { 2585ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org return handle(Type::Union(handle(Type::Number(), isolate), 2586ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org handle(Type::String(), isolate)), isolate); 2587ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else if (result_kind == NUMBER && op_ == Token::SHR) { 2588ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org return handle(Type::Unsigned32(), isolate); 2589ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2590ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSERT_NE(GENERIC, result_kind); 2591ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org return KindToType(result_kind, isolate); 2592ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org} 2593ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2594ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2595ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgvoid BinaryOpIC::State::Print(StringStream* stream) const { 2596ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org stream->Add("(%s", Token::Name(op_)); 2597ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); 2598ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); 2599ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org stream->Add(":%s*", KindToString(left_kind_)); 2600ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (fixed_right_arg_.has_value) { 2601ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org stream->Add("%d", fixed_right_arg_.value); 2602ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 2603ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org stream->Add("%s", KindToString(right_kind_)); 2604ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2605ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org stream->Add("->%s)", KindToString(result_kind_)); 2606ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org} 2607ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2608ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2609ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgvoid BinaryOpIC::State::Update(Handle<Object> left, 2610ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Handle<Object> right, 2611ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Handle<Object> result) { 2612ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ExtraICState old_extra_ic_state = GetExtraICState(); 2613ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2614ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org left_kind_ = UpdateKind(left, left_kind_); 2615ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org right_kind_ = UpdateKind(right, right_kind_); 2616ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2617ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org int32_t fixed_right_arg_value = 0; 2618ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org bool has_fixed_right_arg = 2619ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org op_ == Token::MOD && 2620ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org right->ToInt32(&fixed_right_arg_value) && 2621ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org fixed_right_arg_value > 0 && 2622ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org IsPowerOf2(fixed_right_arg_value) && 2623ddf3811f8018dfe9e8ec7d1b8f4a8be1122fd767machenbach@chromium.org FixedRightArgValueField::is_valid(WhichPowerOf2(fixed_right_arg_value)) && 2624ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org (left_kind_ == SMI || left_kind_ == INT32) && 2625ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org (result_kind_ == NONE || !fixed_right_arg_.has_value); 2626ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org fixed_right_arg_ = Maybe<int32_t>(has_fixed_right_arg, 2627ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org fixed_right_arg_value); 2628ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2629ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org result_kind_ = UpdateKind(result, result_kind_); 2630ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2631ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (!Token::IsTruncatingBinaryOp(op_)) { 2632ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Kind input_kind = Max(left_kind_, right_kind_); 2633ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (result_kind_ < input_kind && input_kind <= NUMBER) { 2634ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org result_kind_ = input_kind; 2635ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2636ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2637ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2638ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Reset overwrite mode unless we can actually make use of it, or may be able 2639ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // to make use of it at some point in the future. 2640ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) || 2641ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org (mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) || 2642ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org result_kind_ > NUMBER) { 2643ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org mode_ = NO_OVERWRITE; 2644ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2645ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2646ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (old_extra_ic_state == GetExtraICState()) { 2647ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Tagged operations can lead to non-truncating HChanges 2648ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (left->IsUndefined() || left->IsBoolean()) { 2649ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org left_kind_ = GENERIC; 2650ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else if (right->IsUndefined() || right->IsBoolean()) { 2651ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org right_kind_ = GENERIC; 2652ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else { 2653ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Since the X87 is too precise, we might bail out on numbers which 2654ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // actually would truncate with 64 bit precision. 2655ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSERT(!CpuFeatures::IsSupported(SSE2)); 2656ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ASSERT(result_kind_ < NUMBER); 2657ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org result_kind_ = NUMBER; 2658ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2659ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2660ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org} 2661ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2662ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2663ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgBinaryOpIC::State::Kind BinaryOpIC::State::UpdateKind(Handle<Object> object, 2664ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Kind kind) const { 2665ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Kind new_kind = GENERIC; 2666ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org bool is_truncating = Token::IsTruncatingBinaryOp(op()); 2667ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (object->IsBoolean() && is_truncating) { 2668ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Booleans will be automatically truncated by HChange. 2669ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org new_kind = INT32; 2670ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else if (object->IsUndefined()) { 2671ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Undefined will be automatically truncated by HChange. 2672ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org new_kind = is_truncating ? INT32 : NUMBER; 2673ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else if (object->IsSmi()) { 2674ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org new_kind = SMI; 2675ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else if (object->IsHeapNumber()) { 2676ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org double value = Handle<HeapNumber>::cast(object)->value(); 2677ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org new_kind = TypeInfo::IsInt32Double(value) ? INT32 : NUMBER; 2678ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else if (object->IsString() && op() == Token::ADD) { 2679ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org new_kind = STRING; 2680ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2681ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (new_kind == INT32 && SmiValuesAre32Bits()) { 2682ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org new_kind = NUMBER; 2683ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2684ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (kind != NONE && 2685ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org ((new_kind <= NUMBER && kind > NUMBER) || 2686ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org (new_kind > NUMBER && kind <= NUMBER))) { 2687ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org new_kind = GENERIC; 2688ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2689ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org return Max(kind, new_kind); 2690ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org} 2691ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2692ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2693ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org// static 2694ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgconst char* BinaryOpIC::State::KindToString(Kind kind) { 2695ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org switch (kind) { 2696ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org case NONE: return "None"; 26978432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org case SMI: return "Smi"; 2698fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org case INT32: return "Int32"; 26998432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org case NUMBER: return "Number"; 2700fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org case STRING: return "String"; 2701a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case GENERIC: return "Generic"; 2702a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 2703ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org UNREACHABLE(); 2704ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org return NULL; 2705ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org} 2706ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2707ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2708ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org// static 2709ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.orgHandle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) { 2710ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Type* type = NULL; 2711ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org switch (kind) { 2712ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org case NONE: type = Type::None(); break; 2713ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org case SMI: type = Type::Smi(); break; 2714ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org case INT32: type = Type::Signed32(); break; 2715ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org case NUMBER: type = Type::Number(); break; 2716ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org case STRING: type = Type::String(); break; 2717ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org case GENERIC: type = Type::Any(); break; 2718ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } 2719ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org return handle(type, isolate); 2720a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2721a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2722a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 272325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.orgMaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) { 2724ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org State state(target()->extended_extra_ic_state()); 2725ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2726ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Compute the actual result using the builtin for the binary operation. 2727ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Object* builtin = isolate()->js_builtins_object()->javascript_builtin( 2728ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org TokenToJSBuiltin(state.op())); 2729ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); 2730ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org bool caught_exception; 2731ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Handle<Object> result = Execution::Call( 2732ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org isolate(), function, left, 1, &right, &caught_exception); 2733ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (caught_exception) return Failure::Exception(); 2734a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2735ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Compute the new state. 2736ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org State old_state = state; 2737ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.Update(left, right, result); 2738a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2739ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Install the new stub. 2740ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org BinaryOpICStub stub(state); 2741ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org set_target(*stub.GetCode(isolate())); 274225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org 274325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org if (FLAG_trace_ic) { 2744ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org char buffer[150]; 2745ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org NoAllocationStringAllocator allocator( 2746ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org buffer, static_cast<unsigned>(sizeof(buffer))); 274725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org StringStream stream(&allocator); 2748ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org stream.Add("[BinaryOpIC"); 2749ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org old_state.Print(&stream); 275025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org stream.Add(" => "); 2751ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.Print(&stream); 2752ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org stream.Add(" @ %p <- ", static_cast<void*>(*target())); 275325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org stream.OutputToStdOut(); 275425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 275525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org PrintF("]\n"); 2756fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 2757fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2758ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Patch the inlined smi code as necessary. 2759ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (!old_state.UseInlinedSmiCode() && state.UseInlinedSmiCode()) { 276025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); 2761ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else if (old_state.UseInlinedSmiCode() && !state.UseInlinedSmiCode()) { 276225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK); 276325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 2764fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2765ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org return *result; 2766d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org} 2767d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 2768a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 276925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.orgRUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss) { 2770ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HandleScope scope(isolate); 2771ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft); 2772ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight); 277325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org BinaryOpIC ic(isolate); 277425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return ic.Transition(left, right); 2775ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 2776ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2777ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 27783d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgCode* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { 2779fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); 2780212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org Code* code = NULL; 27813d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org CHECK(stub.FindCodeInCache(&code, isolate)); 2782212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org return code; 2783212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org} 2784212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 2785212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 27868432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgHandle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) { 2787fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); 27888432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org return stub.GetCode(isolate); 2789a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2790a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2791a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2792a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.orgconst char* CompareIC::GetStateName(State state) { 2793a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org switch (state) { 2794a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case UNINITIALIZED: return "UNINITIALIZED"; 2795fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org case SMI: return "SMI"; 27968432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org case NUMBER: return "NUMBER"; 27974a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org case INTERNALIZED_STRING: return "INTERNALIZED_STRING"; 2798fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org case STRING: return "STRING"; 27994a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org case UNIQUE_NAME: return "UNIQUE_NAME"; 28008432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org case OBJECT: return "OBJECT"; 28018432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org case KNOWN_OBJECT: return "KNOWN_OBJECT"; 2802a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org case GENERIC: return "GENERIC"; 2803a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org } 280441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org UNREACHABLE(); 280541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return NULL; 280641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org} 280741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 280841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org 280941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.orgHandle<Type> CompareIC::StateToType( 281041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Isolate* isolate, 281141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org CompareIC::State state, 281241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org Handle<Map> map) { 281341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org switch (state) { 281441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CompareIC::UNINITIALIZED: 281541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return handle(Type::None(), isolate); 281641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CompareIC::SMI: 28171510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org return handle(Type::Smi(), isolate); 281841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CompareIC::NUMBER: 281941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return handle(Type::Number(), isolate); 282041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CompareIC::STRING: 282141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return handle(Type::String(), isolate); 282241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CompareIC::INTERNALIZED_STRING: 282341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return handle(Type::InternalizedString(), isolate); 282441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CompareIC::UNIQUE_NAME: 282541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return handle(Type::UniqueName(), isolate); 282641728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CompareIC::OBJECT: 282741728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return handle(Type::Receiver(), isolate); 282841728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CompareIC::KNOWN_OBJECT: 282941728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return handle( 283041728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org map.is_null() ? Type::Receiver() : Type::Class(map), isolate); 283141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org case CompareIC::GENERIC: 283241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return handle(Type::Any(), isolate); 283341728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org } 283441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org UNREACHABLE(); 283541728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org return Handle<Type>(); 2836a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2837a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2838a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2839b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgvoid CompareIC::StubInfoToType(int stub_minor_key, 2840b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<Type>* left_type, 2841b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<Type>* right_type, 2842b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<Type>* overall_type, 2843b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<Map> map, 2844b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Isolate* isolate) { 2845b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org State left_state, right_state, handler_state; 2846b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state, 2847b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org &handler_state, NULL); 2848b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org *left_type = StateToType(isolate, left_state); 2849b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org *right_type = StateToType(isolate, right_state); 2850b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org *overall_type = StateToType(isolate, handler_state, map); 2851b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org} 2852b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2853b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org 2854b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.orgCompareIC::State CompareIC::NewInputState(State old_state, 2855b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org Handle<Object> value) { 2856fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org switch (old_state) { 2857b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case UNINITIALIZED: 2858b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsSmi()) return SMI; 2859b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsHeapNumber()) return NUMBER; 2860b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsInternalizedString()) return INTERNALIZED_STRING; 2861b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsString()) return STRING; 2862b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsSymbol()) return UNIQUE_NAME; 2863b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsJSObject()) return OBJECT; 2864fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 2865b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case SMI: 2866b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsSmi()) return SMI; 2867b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsHeapNumber()) return NUMBER; 2868fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 2869b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case NUMBER: 2870b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsNumber()) return NUMBER; 2871fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 2872b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case INTERNALIZED_STRING: 2873b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsInternalizedString()) return INTERNALIZED_STRING; 2874b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsString()) return STRING; 2875b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsSymbol()) return UNIQUE_NAME; 2876fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 2877b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case STRING: 2878b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsString()) return STRING; 28794a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org break; 2880b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case UNIQUE_NAME: 2881b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsUniqueName()) return UNIQUE_NAME; 2882fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 2883b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case OBJECT: 2884b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org if (value->IsJSObject()) return OBJECT; 2885fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 2886b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case GENERIC: 2887fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 2888b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org case KNOWN_OBJECT: 2889fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org UNREACHABLE(); 2890fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org break; 2891fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 2892b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org return GENERIC; 2893fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} 2894fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2895fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2896fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.orgCompareIC::State CompareIC::TargetState(State old_state, 2897fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org State old_left, 2898fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org State old_right, 28995f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org bool has_inlined_smi_code, 29005f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Handle<Object> x, 29015f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org Handle<Object> y) { 2902fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org switch (old_state) { 290364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case UNINITIALIZED: 2904fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (x->IsSmi() && y->IsSmi()) return SMI; 29058432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (x->IsNumber() && y->IsNumber()) return NUMBER; 29069a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org if (Token::IsOrderedRelationalCompareOp(op_)) { 29079a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org // Ordered comparisons treat undefined as NaN, so the 29088432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // NUMBER stub will do the right thing. 29099a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org if ((x->IsNumber() && y->IsUndefined()) || 29109a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org (y->IsNumber() && x->IsUndefined())) { 29118432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org return NUMBER; 29129a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org } 29139a21ec41a2007f01ba18cf5fa48f7987e40e5109ulan@chromium.org } 29144a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (x->IsInternalizedString() && y->IsInternalizedString()) { 29154a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org // We compare internalized strings as plain ones if we need to determine 29164efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org // the order in a non-equality compare. 29174a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return Token::IsEqualityOp(op_) ? INTERNALIZED_STRING : STRING; 29184efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org } 2919fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (x->IsString() && y->IsString()) return STRING; 29204efbdb18fa3063085682c44cc77cf5254cb3d75dsvenpanne@chromium.org if (!Token::IsEqualityOp(op_)) return GENERIC; 29214a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (x->IsUniqueName() && y->IsUniqueName()) return UNIQUE_NAME; 292264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (x->IsJSObject() && y->IsJSObject()) { 292364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org if (Handle<JSObject>::cast(x)->map() == 29248432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org Handle<JSObject>::cast(y)->map()) { 29258432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org return KNOWN_OBJECT; 292664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } else { 2927fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return OBJECT; 292864e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 292964e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org } 293064e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org return GENERIC; 2931fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org case SMI: 29328432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org return x->IsNumber() && y->IsNumber() ? NUMBER : GENERIC; 29334a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org case INTERNALIZED_STRING: 293464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org ASSERT(Token::IsEqualityOp(op_)); 29354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (x->IsString() && y->IsString()) return STRING; 29364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (x->IsUniqueName() && y->IsUniqueName()) return UNIQUE_NAME; 29374a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return GENERIC; 29388432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org case NUMBER: 29398432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // If the failure was due to one side changing from smi to heap number, 29408432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // then keep the state (if other changed at the same time, we will get 29418432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org // a second miss and then go to generic). 29428432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (old_left == SMI && x->IsHeapNumber()) return NUMBER; 29438432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (old_right == SMI && y->IsHeapNumber()) return NUMBER; 29448432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org return GENERIC; 29458432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org case KNOWN_OBJECT: 29468432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org ASSERT(Token::IsEqualityOp(op_)); 29478432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (x->IsJSObject() && y->IsJSObject()) return OBJECT; 29488432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org return GENERIC; 2949fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org case STRING: 29504a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org case UNIQUE_NAME: 2951fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org case OBJECT: 295264e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org case GENERIC: 295364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org return GENERIC; 295483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org } 295564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org UNREACHABLE(); 2956fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org return GENERIC; // Make the compiler happy. 2957fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org} 2958fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2959fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2960b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgCode* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { 2961c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org HandleScope scope(isolate()); 2962fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org State previous_left, previous_right, previous_state; 2963fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, 2964fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org &previous_right, &previous_state, NULL); 2965b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org State new_left = NewInputState(previous_left, x); 2966b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org State new_right = NewInputState(previous_right, y); 2967fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org State state = TargetState(previous_state, previous_left, previous_right, 2968fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org HasInlinedSmiCode(address()), x, y); 2969fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org ICCompareStub stub(op_, new_left, new_right, state); 29708432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org if (state == KNOWN_OBJECT) { 29717bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org stub.set_known_map( 29727bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate())); 2973fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 2974b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Code> new_target = stub.GetCode(isolate()); 2975b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org set_target(*new_target); 2976fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2977fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (FLAG_trace_ic) { 2978fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org PrintF("[CompareIC in "); 2979c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 2980fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", 2981fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GetStateName(previous_left), 2982fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GetStateName(previous_right), 2983fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GetStateName(previous_state), 2984fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GetStateName(new_left), 2985fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GetStateName(new_right), 2986fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org GetStateName(state), 2987fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org Token::Name(op_), 29888432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org static_cast<void*>(*stub.GetCode(isolate()))); 2989fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 2990fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2991fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Activate inlined smi code. 2992fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (previous_state == UNINITIALIZED) { 2993fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); 2994fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 2995b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2996b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return *new_target; 2997a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2998a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2999a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3000fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org// Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc. 3001c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.orgRUNTIME_FUNCTION(Code*, CompareIC_Miss) { 3002fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HandleScope scope(isolate); 3003a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org ASSERT(args.length() == 3); 30046d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); 3005b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); 3006a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 3007a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3008a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 3009ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid CompareNilIC::Clear(Address address, Code* target) { 3010fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (IsCleared(target)) return; 3011cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExtraICState state = target->extended_extra_ic_state(); 3012ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3013a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); 301441728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org stub.ClearState(); 3015ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 30164e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Code* code = NULL; 30174e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); 30184e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 30194e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org SetTargetAtAddress(address, code); 3020ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3021ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3022ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3023837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.orgMaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, 3024ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Handle<Object> object) { 3025ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (object->IsNull() || object->IsUndefined()) { 3026ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org return Smi::FromInt(true); 3027ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 3028ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org return Smi::FromInt(object->IsUndetectableObject()); 3029ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3030ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3031ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3032ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgMaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { 3033cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExtraICState extra_ic_state = target()->extended_extra_ic_state(); 3034ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 30354e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org CompareNilICStub stub(extra_ic_state); 30364e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 3037ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Extract the current supported types from the patched IC and calculate what 3038ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // types must be supported as a result of the miss. 30394e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org bool already_monomorphic = stub.IsMonomorphic(); 30404e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 3041e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org stub.UpdateStatus(object); 3042ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 30434e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org NilValue nil = stub.GetNilValue(); 3044ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3045ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Find or create the specialized stub to support the new set of types. 3046ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Handle<Code> code; 30474e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (stub.IsMonomorphic()) { 3048ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Handle<Map> monomorphic_map(already_monomorphic 3049ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org ? target()->FindFirstMap() 3050ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org : HeapObject::cast(*object)->map()); 30514e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); 3052ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 3053ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org code = stub.GetCode(isolate()); 3054ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 3055b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org set_target(*code); 3056837a67edd9afdbfe1b59482b41693f59c48846ffulan@chromium.org return DoCompareNilSlow(nil, object); 3057ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3058ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3059ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3060ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgRUNTIME_FUNCTION(MaybeObject*, CompareNilIC_Miss) { 3061ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HandleScope scope(isolate); 3062ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Handle<Object> object = args.at<Object>(0); 3063ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CompareNilIC ic(isolate); 3064ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org return ic.CompareNil(object); 3065ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 3066ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 3067ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 306877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.orgRUNTIME_FUNCTION(MaybeObject*, Unreachable) { 306977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org UNREACHABLE(); 307077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org CHECK(false); 307177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org return isolate->heap()->undefined_value(); 307277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org} 307377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 307477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 307525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.orgBuiltins::JavaScript BinaryOpIC::TokenToJSBuiltin(Token::Value op) { 307625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org switch (op) { 307725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org default: 307825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org UNREACHABLE(); 307925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::ADD: 308025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::ADD; 308125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 308225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SUB: 308325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::SUB; 308425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 308525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::MUL: 308625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::MUL; 308725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 308825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::DIV: 308925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::DIV; 309025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 309125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::MOD: 309225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::MOD; 309325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 309425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::BIT_OR: 309525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::BIT_OR; 309625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 309725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::BIT_AND: 309825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::BIT_AND; 309925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 310025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::BIT_XOR: 310125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::BIT_XOR; 310225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 310325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SAR: 310425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::SAR; 310525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 310625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SHR: 310725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::SHR; 310825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 310925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SHL: 311025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::SHL; 311125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 311225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 311325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org} 311425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org 311525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org 3116b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgMaybeObject* ToBooleanIC::ToBoolean(Handle<Object> object) { 3117b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org ToBooleanStub stub(target()->extended_extra_ic_state()); 3118e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org bool to_boolean_value = stub.UpdateStatus(object); 3119b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org Handle<Code> code = stub.GetCode(isolate()); 3120b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org set_target(*code); 31219fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org return Smi::FromInt(to_boolean_value ? 1 : 0); 31229fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org} 31239fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 31249fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 3125b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.orgRUNTIME_FUNCTION(MaybeObject*, ToBooleanIC_Miss) { 3126b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ASSERT(args.length() == 1); 3127b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org HandleScope scope(isolate); 3128b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org Handle<Object> object = args.at<Object>(0); 3129b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ToBooleanIC ic(isolate); 3130b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return ic.ToBoolean(object); 31319fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org} 31329fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 31339fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 3134ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const Address IC_utilities[] = { 313543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define ADDR(name) FUNCTION_ADDR(name), 313643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen IC_UTIL_LIST(ADDR) 313743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen NULL 313843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef ADDR 313943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 314043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 314143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 314243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenAddress IC::AddressFromUtilityId(IC::UtilityId id) { 314343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return IC_utilities[id]; 314443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 314543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 314643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 314743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} } // namespace v8::internal 3148