12efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h" 6196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org 7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/accessors.h" 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h" 9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arguments.h" 1021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org#include "src/base/bits.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/conversions.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/execution.h" 14a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/call-optimization.h" 156474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/handler-compiler.h" 16a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/ic-inl.h" 17a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/ic-compiler.h" 18a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/stub-cache.h" 199bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org#include "src/prototype.h" 20196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/runtime.h" 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 { 2371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal { 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.orgchar IC::TransitionMarkFromState(IC::State state) { 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (state) { 27a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case UNINITIALIZED: 28a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return '0'; 29a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case PREMONOMORPHIC: 30a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return '.'; 31a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case MONOMORPHIC: 32a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return '1'; 33474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org case PROTOTYPE_FAILURE: 34474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org return '^'; 35a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case POLYMORPHIC: 36a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return 'P'; 37a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case MEGAMORPHIC: 38a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return 'N'; 39a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case GENERIC: 40a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return 'G'; 4143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // We never see the debugger states here, because the state is 4343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // computed from the original code - not the patched code. Let 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // these cases fall through to the unreachable code below. 45a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case DEBUG_STUB: 46a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org break; 478640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // Type-vector-based ICs resolve state to one of the above. 488640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org case DEFAULT: 498640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org break; 5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen UNREACHABLE(); 5243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return 0; 5343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 5443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 55750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 56750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgconst char* GetTransitionMarkModifier(KeyedAccessStoreMode mode) { 57750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (mode == STORE_NO_TRANSITION_HANDLE_COW) return ".COW"; 58750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { 59750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return ".IGNORE_OOB"; 60750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 61750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (IsGrowStoreMode(mode)) return ".GROW"; 62750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return ""; 63750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 64750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 65750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 66f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org#ifdef DEBUG 67f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 68f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org#define TRACE_GENERIC_IC(isolate, type, reason) \ 69f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org do { \ 70f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org if (FLAG_trace_ic) { \ 71f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org PrintF("[%s patching generic stub in ", type); \ 72f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org JavaScriptFrame::PrintTop(isolate, stdout, false, true); \ 73f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org PrintF(" (%s)]\n", reason); \ 74f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org } \ 75f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org } while (false) 76f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 77f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org#else 78f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 7906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org#define TRACE_GENERIC_IC(isolate, type, reason) \ 8006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org do { \ 8106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (FLAG_trace_ic) { \ 8206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org PrintF("[%s patching generic stub in ", type); \ 8306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org PrintF("(see below) (%s)]\n", reason); \ 8406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } \ 8506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } while (false) 86f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 87f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org#endif // DEBUG 88f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 898640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 90f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.orgvoid IC::TraceIC(const char* type, Handle<Object> name) { 9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (FLAG_trace_ic) { 92d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Code* new_target = raw_target(); 93fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org State new_state = new_target->ic_state(); 948640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org TraceIC(type, name, state(), new_state); 958640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 968640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org} 978640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 988640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 998640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgvoid IC::TraceIC(const char* type, Handle<Object> name, State old_state, 1008640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org State new_state) { 1018640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (FLAG_trace_ic) { 1028640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Code* new_target = raw_target(); 103d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org PrintF("[%s%s in ", new_target->is_keyed_stub() ? "Keyed" : "", type); 104f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 105f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org // TODO(jkummerow): Add support for "apply". The logic is roughly: 106f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org // marker = [fp_ + kMarkerOffset]; 107f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org // if marker is smi and marker.value == INTERNAL and 108f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org // the frame's code == builtin(Builtins::kFunctionApply): 109f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org // then print "apply from" and advance one frame 110f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 111f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org Object* maybe_function = 112f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org Memory::Object_at(fp_ + JavaScriptFrameConstants::kFunctionOffset); 113f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org if (maybe_function->IsJSFunction()) { 114f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org JSFunction* function = JSFunction::cast(maybe_function); 115f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org JavaScriptFrame::PrintFunctionAndOffset(function, function->code(), pc(), 116f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org stdout, true); 117ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 118f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 119cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org ExtraICState extra_state = new_target->extra_ic_state(); 120a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org const char* modifier = ""; 121a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org if (new_target->kind() == Code::KEYED_STORE_IC) { 122a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org modifier = GetTransitionMarkModifier( 123a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org KeyedStoreIC::GetKeyedAccessStoreMode(extra_state)); 124a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 1258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org PrintF(" (%c->%c%s)", TransitionMarkFromState(old_state), 1268640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org TransitionMarkFromState(new_state), modifier); 127f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org#ifdef OBJECT_PRINT 128f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org OFStream os(stdout); 129f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org name->Print(os); 130f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org#else 131f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org name->ShortPrint(stdout); 132f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org#endif 13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen PrintF("]\n"); 13443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 137f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org#define TRACE_IC(type, name) TraceIC(type, name) 1388640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org#define TRACE_VECTOR_IC(type, name, old_state, new_state) \ 1398640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org TraceIC(type, name, old_state, new_state) 14043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 141c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.orgIC::IC(FrameDepth depth, Isolate* isolate) 142a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org : isolate_(isolate), target_set_(false), target_maps_set_(false) { 143e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // To improve the performance of the (much used) IC code, we unfold a few 144e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // levels of the stack frame iteration code. This yields a ~35% speedup when 145e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag. 146a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org const Address entry = Isolate::c_entry_fp(isolate->thread_local_top()); 14797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Address constant_pool = NULL; 14897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org if (FLAG_enable_ool_constant_pool) { 149a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org constant_pool = 150a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Memory::Address_at(entry + ExitFrameConstants::kConstantPoolOffset); 15197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org } 152e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org Address* pc_address = 153e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset); 154e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset); 155e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // If there's another JavaScript frame on the stack or a 156e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // StubFailureTrampoline, we need to look one frame further down the stack to 157e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org // find the frame pointer and the return address stack slot. 158e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org if (depth == EXTRA_CALL_FRAME) { 15997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org if (FLAG_enable_ool_constant_pool) { 160a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org constant_pool = 161a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Memory::Address_at(fp + StandardFrameConstants::kConstantPoolOffset); 16297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org } 163e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset; 164e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset); 165e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org fp = Memory::Address_at(fp + StandardFrameConstants::kCallerFPOffset); 166e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org } 167e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org#ifdef DEBUG 168c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org StackFrameIterator it(isolate); 16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (int i = 0; i < depth + 1; i++) it.Advance(); 17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen StackFrame* frame = it.frame(); 171e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(fp == frame->fp() && pc_address == frame->pc_address()); 172e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org#endif 173e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org fp_ = fp; 17497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org if (FLAG_enable_ool_constant_pool) { 17597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org raw_constant_pool_ = handle( 17697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray::cast(reinterpret_cast<Object*>(constant_pool)), 17797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org isolate); 17897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org } 1791510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); 180fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org target_ = handle(raw_target(), isolate); 181fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org state_ = target_->ic_state(); 1827c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org kind_ = target_->kind(); 183f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org extra_ic_state_ = target_->extra_ic_state(); 18443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 18543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 18797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgSharedFunctionInfo* IC::GetSharedFunctionInfo() const { 18843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Compute the JavaScript frame for the frame pointer of this IC 18943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // structure. We need this to be able to find the function 19043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // corresponding to the frame. 191c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org StackFrameIterator it(isolate()); 19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (it.frame()->fp() != this->fp()) it.Advance(); 19343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen JavaScriptFrame* frame = JavaScriptFrame::cast(it.frame()); 19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Find the function on the stack and both the active code for the 19543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // function and the original code. 196169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org JSFunction* function = frame->function(); 19797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return function->shared(); 19897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org} 19997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org 20097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org 20197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgCode* IC::GetCode() const { 20297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org HandleScope scope(isolate()); 20397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Handle<SharedFunctionInfo> shared(GetSharedFunctionInfo(), isolate()); 20443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Code* code = shared->code(); 20597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return code; 20697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org} 20797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org 20897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org 20997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgCode* IC::GetOriginalCode() const { 21097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org HandleScope scope(isolate()); 21197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Handle<SharedFunctionInfo> shared(GetSharedFunctionInfo(), isolate()); 212e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(Debug::HasDebugInfo(shared)); 21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Code* original_code = Debug::GetDebugInfo(shared)->original_code(); 214e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(original_code->IsCode()); 21597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return original_code; 21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 21743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org 219e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgstatic void LookupForRead(LookupIterator* it) { 220e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org for (; it->IsFound(); it->Next()) { 221e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org switch (it->state()) { 222e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org case LookupIterator::NOT_FOUND: 223a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case LookupIterator::TRANSITION: 224e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org UNREACHABLE(); 225e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org case LookupIterator::JSPROXY: 226e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return; 227e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org case LookupIterator::INTERCEPTOR: { 228e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org // If there is a getter, return; otherwise loop to perform the lookup. 229e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Handle<JSObject> holder = it->GetHolder<JSObject>(); 230e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (!holder->GetNamedInterceptor()->getter()->IsUndefined()) { 231e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return; 232e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org } 233e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org break; 234e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org } 235e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org case LookupIterator::ACCESS_CHECK: 2363e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // PropertyHandlerCompiler::CheckPrototypes() knows how to emit 2373e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // access checks for global proxies. 2383e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (it->GetHolder<JSObject>()->IsJSGlobalProxy() && 2393e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org it->HasAccess(v8::ACCESS_GET)) { 2403e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org break; 2413e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org } 242e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return; 2431af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::ACCESSOR: 2441af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::DATA: 2451af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return; 246d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 247d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 248d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 249d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 250d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 251d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgbool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver, 252d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<String> name) { 253474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (!IsNameCompatibleWithPrototypeFailure(name)) return false; 254474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Handle<Map> receiver_map = TypeToMap(*receiver_type(), isolate()); 255474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org maybe_handler_ = target()->FindHandlerForMap(*receiver_map); 256474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 257474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // The current map wasn't handled yet. There's no reason to stay monomorphic, 258474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // *unless* we're moving from a deprecated map to its replacement, or 259474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // to a more general elements kind. 260474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // TODO(verwaest): Check if the current map is actually what the old map 261474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // would transition to. 262474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (maybe_handler_.is_null()) { 263474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (!receiver_map->IsJSObjectMap()) return false; 264474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Map* first_map = FirstTargetMap(); 265474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (first_map == NULL) return false; 266474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Handle<Map> old_map(first_map); 267474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (old_map->is_deprecated()) return true; 268474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (IsMoreGeneralElementsKindTransition(old_map->elements_kind(), 269474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org receiver_map->elements_kind())) { 270474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org return true; 271474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } 272474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org return false; 27369ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org } 274fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org 275474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org CacheHolderFlag flag; 276474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Handle<Map> ic_holder_map( 277474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org GetICCacheHolder(*receiver_type(), isolate(), &flag)); 27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 279e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(flag != kCacheOnReceiver || receiver->IsJSObject()); 280e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(flag != kCacheOnPrototype || !receiver->IsJSReceiver()); 281e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(flag != kCacheOnPrototypeReceiverIsDictionary); 282474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org 283474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (state() == MONOMORPHIC) { 284474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org int index = ic_holder_map->IndexInCodeCache(*name, *target()); 285474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (index >= 0) { 286474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org ic_holder_map->RemoveFromCodeCache(*name, *target(), index); 287d3c42109e5b85232d19beab8deeb24bdcbbf07f9danno@chromium.org } 28810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 28957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 29010480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org if (receiver->IsGlobalObject()) { 291e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 2929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR); 2939aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org if (it.state() == LookupIterator::ACCESS_CHECK) return false; 2941af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (!it.IsFound()) return false; 295e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org Handle<PropertyCell> cell = it.GetPropertyCell(); 29610480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org return cell->type()->IsConstant(); 29710480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org } 29810480471c0db59c51c15e57d2a3489551d61b273jkummerow@chromium.org 299474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org return true; 3002efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org} 3012efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 3022efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 303474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.orgbool IC::IsNameCompatibleWithPrototypeFailure(Handle<Object> name) { 304ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (target()->is_keyed_stub()) { 305ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org // Determine whether the failure is due to a name failure. 306ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (!name->IsName()) return false; 307ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org Name* stub_name = target()->FindFirstName(); 308ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org if (*name != stub_name) return false; 309ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org } 310ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 311ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org return true; 312ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org} 313ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 314ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 315d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgvoid IC::UpdateState(Handle<Object> receiver, Handle<Object> name) { 316a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org update_receiver_type(receiver); 3172efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org if (!name->IsString()) return; 318474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (state() != MONOMORPHIC && state() != POLYMORPHIC) return; 319fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (receiver->IsUndefined() || receiver->IsNull()) return; 3200511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com 3210511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // Remove the target from the code cache if it became invalid 3220511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // because of changes in the prototype chain to avoid hitting it 3230511e24c6ebf94594a7e03bdcd58157ac2971d69erik.corry@gmail.com // again. 324474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (TryRemoveInvalidPrototypeDependentStub(receiver, 325474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Handle<String>::cast(name))) { 326474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org MarkPrototypeFailure(name); 327ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org return; 32843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 329b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 330b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // The builtins object is special. It only changes when JavaScript 331b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // builtins are loaded lazily. It is important to keep inline 332b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // caches for the builtins object monomorphic. Therefore, if we get 333b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org // an inline cache miss for the builtins object after lazily loading 334236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // JavaScript builtins, we return uninitialized as the state to 335236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org // force the inline cache back to monomorphic state. 336fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED; 33743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 33843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 340a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgMaybeHandle<Object> IC::TypeError(const char* type, Handle<Object> object, 341c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> key) { 342ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HandleScope scope(isolate()); 343a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> args[2] = {key, object}; 344ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org THROW_NEW_ERROR(isolate(), NewTypeError(type, HandleVector(args, 2)), Object); 34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 34643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 34831c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgMaybeHandle<Object> IC::ReferenceError(const char* type, Handle<Name> name) { 349ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HandleScope scope(isolate()); 350ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org THROW_NEW_ERROR(isolate(), NewReferenceError(type, HandleVector(&name, 1)), 351ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org Object); 35243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 35343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3553e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.orgstatic void ComputeTypeInfoCountDelta(IC::State old_state, IC::State new_state, 3563e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org int* polymorphic_delta, 3573e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org int* generic_delta) { 3583e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org switch (old_state) { 3593e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org case UNINITIALIZED: 3603e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org case PREMONOMORPHIC: 3613e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (new_state == UNINITIALIZED || new_state == PREMONOMORPHIC) break; 3623e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (new_state == MONOMORPHIC || new_state == POLYMORPHIC) { 3633e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org *polymorphic_delta = 1; 3643e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org } else if (new_state == MEGAMORPHIC || new_state == GENERIC) { 3653e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org *generic_delta = 1; 3663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org } 3673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org break; 3683e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org case MONOMORPHIC: 3693e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org case POLYMORPHIC: 3703e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (new_state == MONOMORPHIC || new_state == POLYMORPHIC) break; 3713e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org *polymorphic_delta = -1; 3723e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (new_state == MEGAMORPHIC || new_state == GENERIC) { 3733e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org *generic_delta = 1; 3743e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org } 3753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org break; 3763e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org case MEGAMORPHIC: 3773e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org case GENERIC: 3783e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (new_state == MEGAMORPHIC || new_state == GENERIC) break; 3793e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org *generic_delta = -1; 3803e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org if (new_state == MONOMORPHIC || new_state == POLYMORPHIC) { 3813e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org *polymorphic_delta = 1; 3823e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org } 3833e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org break; 3843e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org case PROTOTYPE_FAILURE: 3853e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org case DEBUG_STUB: 3868640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org case DEFAULT: 3873e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org UNREACHABLE(); 3883e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org } 3891456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org} 3901456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 3911456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 3928640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgvoid IC::OnTypeFeedbackChanged(Isolate* isolate, Address address, 3938640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org State old_state, State new_state, 3948640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org bool target_remains_ic_stub) { 395a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Code* host = 396a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate->inner_pointer_to_code_cache()->GetCacheEntry(address)->code; 3971456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org if (host->kind() != Code::FUNCTION) return; 3981456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org 3998640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (FLAG_type_info_threshold > 0 && target_remains_ic_stub && 4003e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org // Not all Code objects have TypeFeedbackInfo. 4013e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org host->type_feedback_info()->IsTypeFeedbackInfo()) { 4023e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org int polymorphic_delta = 0; // "Polymorphic" here includes monomorphic. 4033e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org int generic_delta = 0; // "Generic" here includes megamorphic. 4048640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org ComputeTypeInfoCountDelta(old_state, new_state, &polymorphic_delta, 4058640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org &generic_delta); 4063e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info()); 4073e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org info->change_ic_with_type_info_count(polymorphic_delta); 4083e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org info->change_ic_generic_count(generic_delta); 409f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 41046839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org if (host->type_feedback_info()->IsTypeFeedbackInfo()) { 411a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org TypeFeedbackInfo* info = TypeFeedbackInfo::cast(host->type_feedback_info()); 41246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org info->change_own_type_change_checksum(); 41346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org } 414afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org host->set_profiler_ticks(0); 415afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org isolate->runtime_profiler()->NotifyICChanged(); 4161456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // TODO(2029): When an optimized function is patched, it would 4171456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // be nice to propagate the corresponding type information to its 4181456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org // unoptimized version for the benefit of later inlining. 41978d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org} 42078d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 42178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org 4228640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgvoid IC::PostPatching(Address address, Code* target, Code* old_target) { 4238640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // Type vector based ICs update these statistics at a different time because 4248640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org // they don't always patch on state change. 4258640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (target->kind() == Code::CALL_IC) return; 4268640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 4278640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Isolate* isolate = target->GetHeap()->isolate(); 4288640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org State old_state = UNINITIALIZED; 4298640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org State new_state = UNINITIALIZED; 4308640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org bool target_remains_ic_stub = false; 4318640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (old_target->is_inline_cache_stub() && target->is_inline_cache_stub()) { 4328640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org old_state = old_target->ic_state(); 4338640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org new_state = target->ic_state(); 4348640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org target_remains_ic_stub = true; 4358640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 4368640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 4378640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org OnTypeFeedbackChanged(isolate, address, old_state, new_state, 4388640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org target_remains_ic_stub); 4398640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org} 4408640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 4418640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 4422ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid IC::RegisterWeakMapDependency(Handle<Code> stub) { 4432ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_collect_maps && FLAG_weak_embedded_maps_in_ic && 4442ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org stub->CanBeWeakStub()) { 445e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!stub->is_weak_stub()); 4462ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org MapHandleList maps; 4472ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org stub->FindAllMaps(&maps); 4482ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (maps.length() == 1 && stub->IsWeakObjectInIC(*maps.at(0))) { 449e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org Map::AddDependentIC(maps.at(0), stub); 4502ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org stub->mark_as_weak_stub(); 4512ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (FLAG_enable_ool_constant_pool) { 4522ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org stub->constant_pool()->set_weak_object_state( 4532ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org ConstantPoolArray::WEAK_OBJECTS_IN_IC); 4542ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 4552ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 4562ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 4572ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org} 4582ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 4592ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 4602ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.orgvoid IC::InvalidateMaps(Code* stub) { 461e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(stub->is_weak_stub()); 4622ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org stub->mark_as_invalidated_weak_stub(); 4632ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Isolate* isolate = stub->GetIsolate(); 4642ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Heap* heap = isolate->heap(); 4652ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Object* undefined = heap->undefined_value(); 4662ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 4672ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org for (RelocIterator it(stub, mode_mask); !it.done(); it.next()) { 4682ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org RelocInfo::Mode mode = it.rinfo()->rmode(); 4692ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org if (mode == RelocInfo::EMBEDDED_OBJECT && 4702ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org it.rinfo()->target_object()->IsMap()) { 4712ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org it.rinfo()->set_target_object(undefined, SKIP_WRITE_BARRIER); 4722ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 4732ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org } 4745de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org CpuFeatures::FlushICache(stub->instruction_start(), stub->instruction_size()); 4752ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org} 4762ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 4772ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org 47897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgvoid IC::Clear(Isolate* isolate, Address address, 479a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ConstantPoolArray* constant_pool) { 48097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org Code* target = GetTargetAtAddress(address, constant_pool); 48143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Don't clear debug break inline cache as it will remove the break point. 483ec6855e761a7474a580d750a45d748323dd3b7c7verwaest@chromium.org if (target->is_debug_stub()) return; 48443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen switch (target->kind()) { 48697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org case Code::LOAD_IC: 48797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return LoadIC::Clear(isolate, address, target, constant_pool); 4883d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org case Code::KEYED_LOAD_IC: 48997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return KeyedLoadIC::Clear(isolate, address, target, constant_pool); 49097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org case Code::STORE_IC: 49197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return StoreIC::Clear(isolate, address, target, constant_pool); 4923d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org case Code::KEYED_STORE_IC: 49397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return KeyedStoreIC::Clear(isolate, address, target, constant_pool); 494a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org case Code::CALL_IC: 495a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return CallIC::Clear(isolate, address, target, constant_pool); 49697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org case Code::COMPARE_IC: 49797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return CompareIC::Clear(isolate, address, target, constant_pool); 49897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org case Code::COMPARE_NIL_IC: 49997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org return CompareNilIC::Clear(address, target, constant_pool); 50040cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org case Code::BINARY_OP_IC: 5019fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org case Code::TO_BOOLEAN_IC: 502a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // Clearing these is tricky and does not 503a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org // make any performance difference. 504a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org return; 505a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org default: 506a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org UNREACHABLE(); 50743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 50843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 50943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 51043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 511a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target, 51297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool) { 5138e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (IsCleared(target)) return; 51437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Make sure to also clear the map used in inline fast cases. If we 51537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // do not clear these maps, cached code can keep objects alive 51637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // through the embedded maps. 51797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org SetTargetAtAddress(address, *pre_monomorphic_stub(isolate), constant_pool); 51843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 51943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 52043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 521a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid CallIC::Clear(Isolate* isolate, Address address, Code* target, 522a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ConstantPoolArray* constant_pool) { 523a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // Currently, CallIC doesn't have state changes. 524a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 525a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 526a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 527a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid LoadIC::Clear(Isolate* isolate, Address address, Code* target, 52897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool) { 5298e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (IsCleared(target)) return; 530dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::LOAD_IC, 531dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org target->extra_ic_state()); 53297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org SetTargetAtAddress(address, code, constant_pool); 53343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 53443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 53543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 536a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid StoreIC::Clear(Isolate* isolate, Address address, Code* target, 53797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool) { 5388e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (IsCleared(target)) return; 539dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Code* code = PropertyICCompiler::FindPreMonomorphic(isolate, Code::STORE_IC, 540dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org target->extra_ic_state()); 54197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org SetTargetAtAddress(address, code, constant_pool); 54243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 54343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 54443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 545a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target, 54697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool) { 5478e36b5ba34174c8ceb04a47d7e10dcc8f43d94a4machenbach@chromium.org if (IsCleared(target)) return; 548a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org SetTargetAtAddress( 549a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org address, *pre_monomorphic_stub( 550a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate, StoreIC::GetStrictMode(target->extra_ic_state())), 55197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org constant_pool); 55243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 55343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 55443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 555a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid CompareIC::Clear(Isolate* isolate, Address address, Code* target, 55697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool) { 557e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC); 55842ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org CompareICStub stub(target->stub_key(), isolate); 559212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org // Only clear CompareICs that can retain objects. 560d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org if (stub.state() != CompareICState::KNOWN_OBJECT) return; 56121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org SetTargetAtAddress(address, GetRawUninitialized(isolate, stub.op()), 56221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org constant_pool); 563212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK); 564212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org} 565212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 566212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 5677c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org// static 5687c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.orgHandle<Code> KeyedLoadIC::generic_stub(Isolate* isolate) { 5691845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (FLAG_compiled_keyed_generic_loads) { 570dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return KeyedLoadGenericStub(isolate).GetCode(); 5711845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } else { 5727c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org return isolate->builtins()->KeyedLoadIC_Generic(); 5731845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org } 5741845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org} 5751845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 5761845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org 577d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgstatic bool MigrateDeprecated(Handle<Object> object) { 578d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (!object->IsJSObject()) return false; 579d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 580d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (!receiver->map()->is_deprecated()) return false; 581d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org JSObject::MigrateInstance(Handle<JSObject>::cast(object)); 582d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org return true; 583d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org} 584d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 585d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 58631c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgMaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name) { 58743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If the object is undefined or null it's illegal to try to get any 58843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // of its properties; throw a TypeError in that case. 58943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (object->IsUndefined() || object->IsNull()) { 59043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return TypeError("non_object_property_load", object, name); 59143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 59243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 59343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check if the name is trivially convertible to an index and get 5946bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // the element or char if so. 59543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t index; 5966bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) { 5976bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // Rewrite to the generic keyed load stub. 598f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org if (FLAG_use_ic) { 5997c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org set_target(*KeyedLoadIC::generic_stub(isolate())); 600f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org TRACE_IC("LoadIC", name); 601f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org TRACE_GENERIC_IC(isolate(), "LoadIC", "name as array index"); 602f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org } 603202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org Handle<Object> result; 604c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 605a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate(), result, 606a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Runtime::GetElementOrCharAt(isolate(), object, index), Object); 607c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return result; 6086bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 60943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 610d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; 611f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 61243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Named lookup in the object. 613e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org LookupIterator it(object, name); 614e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org LookupForRead(&it); 61543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 616a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (it.IsFound() || !IsUndeclaredGlobal(object)) { 617a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // Update inline cache and stub cache. 618a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (use_ic) UpdateCaches(&it); 61943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 620a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // Get the property. 621a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> result; 622a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, Object::GetProperty(&it), 623a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Object); 624a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (it.IsFound()) { 625a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return result; 626a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } else if (!IsUndeclaredGlobal(object)) { 627a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org LOG(isolate(), SuspectReadEvent(*name, *object)); 628a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return result; 629a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 630d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 631a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return ReferenceError("not_defined", name); 63243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 63343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 63443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 6354a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.orgstatic bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, 6364a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org Handle<Map> new_receiver_map) { 637e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!new_receiver_map.is_null()); 6384a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org for (int current = 0; current < receiver_maps->length(); ++current) { 6394a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org if (!receiver_maps->at(current).is_null() && 6404a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org receiver_maps->at(current).is_identical_to(new_receiver_map)) { 6414a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return false; 6424a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 6434a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 6444a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org receiver_maps->Add(new_receiver_map); 6454a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return true; 6464a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 6474a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 6484a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 64931c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgbool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Code> code) { 650fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (!code->is_handler()) return false; 651474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (target()->is_keyed_stub() && state() != PROTOTYPE_FAILURE) return false; 652474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Handle<HeapType> type = receiver_type(); 6530f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org TypeHandleList types; 6540f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org CodeHandleList handlers; 6550f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org 6564edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org TargetTypes(&types); 6570f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org int number_of_types = types.length(); 658a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org int deprecated_types = 0; 659a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org int handler_to_overwrite = -1; 660af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 661af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org for (int i = 0; i < number_of_types; i++) { 6620f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org Handle<HeapType> current_type = types.at(i); 6639fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org if (current_type->IsClass() && 6649fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org current_type->AsClass()->Map()->is_deprecated()) { 665a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org // Filter out deprecated maps to ensure their instances get migrated. 666a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org ++deprecated_types; 667ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org } else if (type->NowIs(current_type)) { 668a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org // If the receiver type is already in the polymorphic IC, this indicates 669a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org // there was a prototoype chain failure. In that case, just overwrite the 670a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org // handler. 671a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org handler_to_overwrite = i; 672a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } else if (handler_to_overwrite == -1 && current_type->IsClass() && 673a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org type->IsClass() && 6749fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org IsTransitionOfMonomorphicTarget(*current_type->AsClass()->Map(), 6759fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org *type->AsClass()->Map())) { 676e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org handler_to_overwrite = i; 677f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org } 678e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 679f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org 680a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org int number_of_valid_types = 681a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org number_of_types - deprecated_types - (handler_to_overwrite != -1); 682a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org 683af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (number_of_valid_types >= 4) return false; 684af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org if (number_of_types == 0) return false; 6850f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org if (!target()->FindHandlers(&handlers, types.length())) return false; 68632aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org 687af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org number_of_valid_types++; 688474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (number_of_valid_types > 1 && target()->is_keyed_stub()) return false; 689474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Handle<Code> ic; 690474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (number_of_valid_types == 1) { 691dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org ic = PropertyICCompiler::ComputeMonomorphic(kind(), name, type, code, 692dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org extra_ic_state()); 69357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } else { 694474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (handler_to_overwrite >= 0) { 695474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org handlers.Set(handler_to_overwrite, code); 696474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (!type->NowIs(types.at(handler_to_overwrite))) { 697474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org types.Set(handler_to_overwrite, type); 698474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } 699474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } else { 700474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org types.Add(type); 701474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org handlers.Add(code); 702474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } 703dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org ic = PropertyICCompiler::ComputePolymorphic(kind(), &types, &handlers, 704dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org number_of_valid_types, name, 705dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org extra_ic_state()); 7064a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org } 7074a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org set_target(*ic); 7084a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org return true; 7094a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org} 7104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 7114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org 7126d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgHandle<HeapType> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { 713034539689f9600e463cd5273725c6269d0f3b8cbmachenbach@chromium.org return object->IsJSGlobalObject() 714a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ? HeapType::Constant(Handle<JSGlobalObject>::cast(object), isolate) 715a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org : HeapType::NowOf(object, isolate); 716f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org} 717f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 718f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org 7196d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgHandle<Map> IC::TypeToMap(HeapType* type, Isolate* isolate) { 7206d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org if (type->Is(HeapType::Number())) 7216d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org return isolate->factory()->heap_number_map(); 72249ff8125753a4cb137f5e549671d42c7ca47ade5machenbach@chromium.org if (type->Is(HeapType::Boolean())) return isolate->factory()->boolean_map(); 723f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org if (type->IsConstant()) { 7249fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org return handle( 7259fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org Handle<JSGlobalObject>::cast(type->AsConstant()->Value())->map()); 726f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org } 727e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(type->IsClass()); 7289fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org return type->AsClass()->Map(); 729af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org} 730af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 731af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 7320a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgtemplate <class T> 7330a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.orgtypename T::TypeHandle IC::MapToType(Handle<Map> map, 7340a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org typename T::Region* region) { 7356d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org if (map->instance_type() == HEAP_NUMBER_TYPE) { 7360a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return T::Number(region); 7376d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org } else if (map->instance_type() == ODDBALL_TYPE) { 7386d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org // The only oddballs that can be recorded in ICs are booleans. 7390a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return T::Boolean(region); 7406d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org } else { 7410a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org return T::Class(map, region); 7426d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.org } 743af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org} 744af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 745af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org 746a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgtemplate Type* IC::MapToType<Type>(Handle<Map> map, Zone* zone); 7470a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 7480a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 749a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgtemplate Handle<HeapType> IC::MapToType<HeapType>(Handle<Map> map, 750a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Isolate* region); 7510a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 7520a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org 75331c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgvoid IC::UpdateMonomorphicIC(Handle<Code> handler, Handle<Name> name) { 754e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(handler->is_handler()); 755dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Code> ic = PropertyICCompiler::ComputeMonomorphic( 756474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org kind(), name, receiver_type(), handler, extra_ic_state()); 757bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org set_target(*ic); 758bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org} 759bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 760bee51999422c0eeaae85ed99b5c0bd4126510ff1danno@chromium.org 76131c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgvoid IC::CopyICToMegamorphicCache(Handle<Name> name) { 7620f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org TypeHandleList types; 7630f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org CodeHandleList handlers; 7644edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org TargetTypes(&types); 7650f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org if (!target()->FindHandlers(&handlers, types.length())) return; 7660f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org for (int i = 0; i < types.length(); i++) { 7670f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); 7686e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org } 7696e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org} 7706e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 7716e196bfaf0e555d0c835390bb6ebc0a74484491dulan@chromium.org 772a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.orgbool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { 773a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org if (source_map == NULL) return true; 774a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org if (target_map == NULL) return false; 775a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org ElementsKind target_elements_kind = target_map->elements_kind(); 776a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org bool more_general_transition = IsMoreGeneralElementsKindTransition( 777a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org source_map->elements_kind(), target_elements_kind); 778a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Map* transitioned_map = 779a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org more_general_transition 780a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ? source_map->LookupElementsTransitionMap(target_elements_kind) 781a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org : NULL; 7820f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org 783a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org return transitioned_map == target_map; 784f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org} 785f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 786f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 78731c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.orgvoid IC::PatchCache(Handle<Name> name, Handle<Code> code) { 788fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org switch (state()) { 78959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case UNINITIALIZED: 79059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case PREMONOMORPHIC: 791474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org UpdateMonomorphicIC(code, name); 79259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org break; 793474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org case PROTOTYPE_FAILURE: 794474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org case MONOMORPHIC: 795e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org case POLYMORPHIC: 796474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (!target()->is_keyed_stub() || state() == PROTOTYPE_FAILURE) { 797474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (UpdatePolymorphicIC(name, code)) break; 798fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org CopyICToMegamorphicCache(name); 79959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org } 800fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org set_target(*megamorphic_stub()); 801a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // Fall through. 80259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org case MEGAMORPHIC: 803474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org UpdateMegamorphicCache(*receiver_type(), *name, *code); 80459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org break; 805d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org case DEBUG_STUB: 80659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org break; 8078640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org case DEFAULT: 808068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org case GENERIC: 809068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org UNREACHABLE(); 810068ea0a6ea115c058d1d9798029bd7fa1eaaa955mstarzinger@chromium.org break; 81143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 812d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org} 813d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 814d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 815a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.orgHandle<Code> LoadIC::initialize_stub(Isolate* isolate, 816a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org ExtraICState extra_state) { 817dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeLoad(isolate, UNINITIALIZED, extra_state); 8189cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 8199cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 8209cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 8217c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.orgHandle<Code> LoadIC::megamorphic_stub() { 8227c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (kind() == Code::LOAD_IC) { 823d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org MegamorphicLoadStub stub(isolate(), LoadICState(extra_ic_state())); 824e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org return stub.GetCode(); 8257c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } else { 826e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); 8277c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org return KeyedLoadIC::generic_stub(isolate()); 8287c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 8297c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org} 8307c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org 8317c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org 8329cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgHandle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate, 833a03ba1e53fa6a04b8e56747536f226380bb6269bmachenbach@chromium.org ExtraICState extra_state) { 834dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeLoad(isolate, PREMONOMORPHIC, extra_state); 8359cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 8369cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 8379cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 8387c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.orgHandle<Code> KeyedLoadIC::pre_monomorphic_stub(Isolate* isolate) { 8397c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org return isolate->builtins()->KeyedLoadIC_PreMonomorphic(); 8409cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 8419cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 8429cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 8437c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.orgHandle<Code> LoadIC::pre_monomorphic_stub() const { 8447c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (kind() == Code::LOAD_IC) { 8457c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org return LoadIC::pre_monomorphic_stub(isolate(), extra_ic_state()); 8467c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } else { 847e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(Code::KEYED_LOAD_IC, kind()); 8487c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org return KeyedLoadIC::pre_monomorphic_stub(isolate()); 8497c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org } 850f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org} 851f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 852f78524cb19cf078611235da0d6e361207f7eacdcmachenbach@chromium.org 853e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.orgHandle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { 8547c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org LoadFieldStub stub(isolate(), index); 8557c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org return stub.GetCode(); 8562efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org} 8572efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 858e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org 859a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid LoadIC::UpdateCaches(LookupIterator* lookup) { 860fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == UNINITIALIZED) { 861a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // This is the first time we execute this inline cache. Set the target to 862a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // the pre monomorphic stub to delay setting the monomorphic state. 863e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org set_target(*pre_monomorphic_stub()); 864a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org TRACE_IC("LoadIC", lookup->name()); 865e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return; 866b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 867b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 868b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<Code> code; 869e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (lookup->state() == LookupIterator::JSPROXY || 870e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org lookup->state() == LookupIterator::ACCESS_CHECK) { 8714a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org code = slow_stub(); 872e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org } else if (!lookup->IsFound()) { 873b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (kind() == Code::LOAD_IC) { 874a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org code = NamedLoadHandlerCompiler::ComputeLoadNonexistent(lookup->name(), 875dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org receiver_type()); 876474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // TODO(jkummerow/verwaest): Introduce a builtin that handles this case. 877474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (code.is_null()) code = slow_stub(); 878b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else { 879b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org code = slow_stub(); 880b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 881d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org } else { 882a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org code = ComputeHandler(lookup); 883d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org } 88443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 885a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PatchCache(lookup->name(), code); 886a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org TRACE_IC("LoadIC", lookup->name()); 88743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 88843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 88943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 8906d26cbb00b8ff12ecf86400c59f4a18d3850f22dmachenbach@chromium.orgvoid IC::UpdateMegamorphicCache(HeapType* type, Name* name, Code* code) { 8917c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org if (kind() == Code::KEYED_LOAD_IC || kind() == Code::KEYED_STORE_IC) return; 892af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org Map* map = *TypeToMap(type, isolate()); 893003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org isolate()->stub_cache()->Set(name, map, code); 894ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 895ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 896ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 897a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgHandle<Code> IC::ComputeHandler(LookupIterator* lookup, Handle<Object> value) { 898e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org bool receiver_is_holder = 899a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org lookup->GetReceiver().is_identical_to(lookup->GetHolder<JSObject>()); 900e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org CacheHolderFlag flag; 901e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( 902e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org *receiver_type(), receiver_is_holder, isolate(), &flag); 903e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 904e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Handle<Code> code = PropertyHandlerCompiler::Find( 905a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org lookup->name(), stub_holder_map, kind(), flag, 9061af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org lookup->is_dictionary_holder() ? Code::NORMAL : Code::FAST); 907e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org // Use the cached value if it exists, and if it is different from the 908e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org // handler that just missed. 909e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (!code.is_null()) { 910e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (!maybe_handler_.is_null() && 911e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org !maybe_handler_.ToHandleChecked().is_identical_to(code)) { 912e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org return code; 913e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org } 914e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org if (maybe_handler_.is_null()) { 915e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org // maybe_handler_ is only populated for MONOMORPHIC and POLYMORPHIC ICs. 916e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org // In MEGAMORPHIC case, check if the handler in the megamorphic stub 917e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org // cache (which just missed) is different from the cached handler. 918a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (state() == MEGAMORPHIC && lookup->GetReceiver()->IsHeapObject()) { 919a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Map* map = Handle<HeapObject>::cast(lookup->GetReceiver())->map(); 920474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Code* megamorphic_cached_code = 921a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate()->stub_cache()->Get(*lookup->name(), map, code->flags()); 922474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org if (megamorphic_cached_code != *code) return code; 923474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } else { 924474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org return code; 925474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } 926474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org } 927f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 9282efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 929a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org code = CompileHandler(lookup, value, flag); 930e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(code->is_handler()); 9312efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 932b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org // TODO(mvstanton): we'd only like to cache code on the map when it's custom 933b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org // code compiled for this map, otherwise it's already cached in the global 934b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org // code 935b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org // cache. We are also guarding against installing code with flags that don't 936b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org // match the desired CacheHolderFlag computed above, which would lead to 937b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org // invalid lookups later. 938b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org if (code->type() != Code::NORMAL && 939b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org Code::ExtractCacheHolderFromFlags(code->flags()) == flag) { 940a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); 941003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 942003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 9432efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return code; 9442efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org} 9452efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 9462efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 947e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.orgHandle<Code> LoadIC::CompileHandler(LookupIterator* lookup, 948e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Handle<Object> unused, 949474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org CacheHolderFlag cache_holder) { 950a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> receiver = lookup->GetReceiver(); 951a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (receiver->IsString() && 952a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Name::Equals(isolate()->factory()->length_string(), lookup->name())) { 953e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org FieldIndex index = FieldIndex::ForInObjectOffset(String::kLengthOffset); 954e7a6d372100022f492c88886898add6a51e66977machenbach@chromium.org return SimpleFieldLoad(index); 955b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } 956b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 957a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (receiver->IsStringWrapper() && 958a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Name::Equals(isolate()->factory()->length_string(), lookup->name())) { 9597c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org StringLengthStub string_length_stub(isolate()); 9607c0666e15d1f68f0fef5db9e5c409fab010ed816machenbach@chromium.org return string_length_stub.GetCode(); 961381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org } 962381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org 96351e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org // Use specialized code for getting prototype of functions. 964a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (receiver->IsJSFunction() && 965a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Name::Equals(isolate()->factory()->prototype_string(), lookup->name()) && 966a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSFunction>::cast(receiver)->should_have_prototype() && 967a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org !Handle<JSFunction>::cast(receiver) 968a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ->map() 969a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ->has_non_instance_prototype()) { 97051e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org Handle<Code> stub; 971eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org FunctionPrototypeStub function_prototype_stub(isolate()); 97251e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org return function_prototype_stub.GetCode(); 97351e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org } 97451e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org 975474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org Handle<HeapType> type = receiver_type(); 976e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org Handle<JSObject> holder = lookup->GetHolder<JSObject>(); 977a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org bool receiver_is_holder = receiver.is_identical_to(holder); 9781af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org switch (lookup->state()) { 9791af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::INTERCEPTOR: { 9801af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 9811af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 9821af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org cache_holder); 9831af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // Perform a lookup behind the interceptor. Copy the LookupIterator since 9841af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // the original iterator will be used to fetch the value. 9851af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org LookupIterator it = *lookup; 9861af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org it.Next(); 9871af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org LookupForRead(&it); 9881af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileLoadInterceptor(&it); 9891af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 990e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 9911af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::ACCESSOR: { 9921af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // Use simple field loads for some well-known callback properties. 9931af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (receiver_is_holder) { 9941af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(receiver->IsJSObject()); 9951af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<JSObject> js_receiver = Handle<JSObject>::cast(receiver); 9961af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org int object_offset; 9971af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (Accessors::IsJSObjectFieldAccessor<HeapType>(type, lookup->name(), 9981af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org &object_offset)) { 9991af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org FieldIndex index = 10001af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org FieldIndex::ForInObjectOffset(object_offset, js_receiver->map()); 10011af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return SimpleFieldLoad(index); 10021af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 10032efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org } 1004e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 10051af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Object> accessors = lookup->GetAccessors(); 10061af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (accessors->IsExecutableAccessorInfo()) { 10071af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<ExecutableAccessorInfo> info = 10081af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<ExecutableAccessorInfo>::cast(accessors); 10091af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (v8::ToCData<Address>(info->getter()) == 0) break; 10101af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (!ExecutableAccessorInfo::IsCompatibleReceiverType(isolate(), info, 10111af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org type)) { 10121af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org break; 10131af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 10141af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (!holder->HasFastProperties()) break; 10151af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 10161af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org cache_holder); 10171af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileLoadCallback(lookup->name(), info); 1018e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org } 10191af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (accessors->IsAccessorPair()) { 10201af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), 10211af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org isolate()); 10221af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (!getter->IsJSFunction()) break; 10231af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (!holder->HasFastProperties()) break; 10241af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<JSFunction> function = Handle<JSFunction>::cast(getter); 10251af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (!receiver->IsJSObject() && !function->IsBuiltin() && 10261af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org function->shared()->strict_mode() == SLOPPY) { 10271af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // Calling sloppy non-builtins with a value as the receiver 10281af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // requires boxing. 10291af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org break; 10301af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 10311af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org CallOptimization call_optimization(function); 10321af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 10331af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org cache_holder); 10341af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (call_optimization.is_simple_api_call() && 10351af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org call_optimization.IsCompatibleReceiver(receiver, holder)) { 10361af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileLoadCallback(lookup->name(), 10371af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org call_optimization); 10381af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 10391af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileLoadViaGetter(lookup->name(), function); 10401af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 10411af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // TODO(dcarney): Handle correctly. 10421af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(accessors->IsDeclaredAccessorInfo()); 10431af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org break; 1044003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 10451af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org 10461af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::DATA: { 10471af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (lookup->is_dictionary_holder()) { 10481af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (kind() != Code::LOAD_IC) break; 10491af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (holder->IsGlobalObject()) { 10501af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 10511af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org cache_holder); 10521af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<PropertyCell> cell = lookup->GetPropertyCell(); 10531af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Code> code = compiler.CompileLoadGlobal( 10541af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org cell, lookup->name(), lookup->IsConfigurable()); 10551af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 10561af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org CacheHolderFlag flag; 10571af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Map> stub_holder_map = GetHandlerCacheHolder( 10581af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org *type, receiver_is_holder, isolate(), &flag); 10591af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); 10601af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return code; 10611af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 10621af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // There is only one shared stub for loading normalized 10631af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // properties. It does not traverse the prototype chain, so the 10641af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // property must be found in the object for the stub to be 10651af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // applicable. 10661af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (!receiver_is_holder) break; 10671af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return isolate()->builtins()->LoadIC_Normal(); 1068003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 10691af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org 10701af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // -------------- Fields -------------- 10711af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (lookup->property_details().type() == FIELD) { 10721af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org FieldIndex field = lookup->GetFieldIndex(); 10731af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (receiver_is_holder) { 10741af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return SimpleFieldLoad(field); 10751af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 10761af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 10771af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org cache_holder); 10781af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileLoadField(lookup->name(), field); 1079528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org } 1080e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 10811af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // -------------- Constant properties -------------- 10821af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(lookup->property_details().type() == CONSTANT); 10831af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (receiver_is_holder) { 10841af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org LoadConstantStub stub(isolate(), lookup->GetConstantIndex()); 10851af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return stub.GetCode(); 10861af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 10879d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 10889d72b8dd94263d9f500f18255d67f0c7b8c3527amachenbach@chromium.org cache_holder); 10891af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileLoadConstant(lookup->name(), 10901af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org lookup->GetConstantIndex()); 1091e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org } 1092e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 10931af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::ACCESS_CHECK: 10941af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::JSPROXY: 10951af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::NOT_FOUND: 10961af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::TRANSITION: 10971af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org UNREACHABLE(); 1098003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 10992efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 11001af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return slow_stub(); 1101ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 1102ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1103ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 110428faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.orgstatic Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) { 110528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // This helper implements a few common fast cases for converting 110628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org // non-smi keys of keyed loads/stores to a smi or a string. 110728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (key->IsHeapNumber()) { 110828faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org double value = Handle<HeapNumber>::cast(key)->value(); 110977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org if (std::isnan(value)) { 11104a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org key = isolate->factory()->nan_string(); 111128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else { 111228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org int int_value = FastD2I(value); 111328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org if (value == int_value && Smi::IsValid(int_value)) { 111409d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org key = Handle<Smi>(Smi::FromInt(int_value), isolate); 111528faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 111628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 111728faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } else if (key->IsUndefined()) { 11184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org key = isolate->factory()->undefined_string(); 111928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org } 112028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org return key; 112128faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org} 112228faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 112328faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 1124003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgHandle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) { 11257bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<Map> receiver_map(receiver->map(), isolate()); 1126003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org MapHandleList target_receiver_maps; 1127fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (target().is_identical_to(string_stub())) { 1128003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org target_receiver_maps.Add(isolate()->factory()->string_map()); 1129003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } else { 11304edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org TargetMaps(&target_receiver_maps); 11314edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org } 11324edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org if (target_receiver_maps.length() == 0) { 1133dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map); 1134003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1135003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1136003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // The first time a receiver is seen that is a transitioned version of the 1137003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // previous monomorphic receiver type, assume the new ElementsKind is the 1138003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // monomorphic type. This benefits global arrays that only transition 1139003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // once, and all call sites accessing them are faster if they remain 1140003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // monomorphic. If this optimistic assumption is not true, the IC will 1141003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // miss again and it will become polymorphic and support both the 1142003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // untransitioned and transitioned maps. 1143a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (state() == MONOMORPHIC && IsMoreGeneralElementsKindTransition( 1144a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org target_receiver_maps.at(0)->elements_kind(), 1145a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org receiver->GetElementsKind())) { 1146dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map); 1147003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1148003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1149e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(state() != GENERIC); 1150003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1151003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // Determine the list of receiver maps that this call site has seen, 1152003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // adding the map that was just encountered. 1153003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { 1154003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // If the miss wasn't due to an unseen map, a polymorphic stub 1155003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // won't help, use the generic stub. 115606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice"); 1157003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return generic_stub(); 1158003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1159003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1160003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // If the maximum number of receiver maps has been exceeded, use the generic 1161003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org // version of the IC. 1162003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 116306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded"); 1164003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org return generic_stub(); 1165003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1166003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1167dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps); 1168003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org} 1169003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1170003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1171c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgMaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, 1172c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> key) { 1173d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (MigrateDeprecated(object)) { 1174202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org Handle<Object> result; 1175c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 1176a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate(), result, Runtime::GetObjectProperty(isolate(), object, key), 1177c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Object); 1178c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return result; 1179d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 1180d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1181c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> load_handle; 1182c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Handle<Code> stub = generic_stub(); 1183c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 1184f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Check for non-string values that can be converted into an 1185f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // internalized string directly or is representable as a smi. 118628faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org key = TryConvertKey(key, isolate()); 1187c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org 118831c0e32e19ad3df48525fa9e7b2d1c0c07496d00machenbach@chromium.org if (key->IsInternalizedString() || key->IsSymbol()) { 1189a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION(isolate(), load_handle, 1190a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org LoadIC::Load(object, Handle<Name>::cast(key)), 1191a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Object); 1192c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } else if (FLAG_use_ic && !object->IsAccessCheckNeeded()) { 1193b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (object->IsString() && key->IsNumber()) { 1194b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org if (state() == UNINITIALIZED) stub = string_stub(); 1195b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org } else if (object->IsJSObject()) { 1196b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 119706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (!Object::ToSmi(isolate(), key).is_null()) { 1198b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org stub = LoadElementStub(receiver); 1199d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 12003811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 1201c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 1202d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1203c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (!is_target_set()) { 12041845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org Code* generic = *generic_stub(); 12051845eb0120c7a870d7388de091246a7d1b48a4f8machenbach@chromium.org if (*stub == generic) { 1206c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "set generic"); 1207c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 1208d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org set_target(*stub); 1209d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org TRACE_IC("LoadIC", key); 1210ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 1211a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 1212c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org if (!load_handle.is_null()) return load_handle; 1213202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org Handle<Object> result; 1214a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION(isolate(), result, 1215a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Runtime::GetObjectProperty(isolate(), object, key), 1216a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Object); 1217c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return result; 121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 121943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1221a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgbool StoreIC::LookupForWrite(LookupIterator* it, Handle<Object> value, 1222a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org JSReceiver::StoreFromKeyed store_mode) { 122351e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org // Disable ICs for non-JSObjects for now. 1224a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> receiver = it->GetReceiver(); 1225a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (!receiver->IsJSObject()) return false; 1226a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(!Handle<JSObject>::cast(receiver)->map()->is_deprecated()); 122751e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org 1228a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org for (; it->IsFound(); it->Next()) { 1229a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org switch (it->state()) { 1230a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case LookupIterator::NOT_FOUND: 1231a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case LookupIterator::TRANSITION: 1232a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org UNREACHABLE(); 1233a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case LookupIterator::JSPROXY: 1234a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return false; 1235a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case LookupIterator::INTERCEPTOR: { 1236a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> holder = it->GetHolder<JSObject>(); 1237a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org InterceptorInfo* info = holder->GetNamedInterceptor(); 1238a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (it->HolderIsReceiverOrHiddenPrototype()) { 1239a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (!info->setter()->IsUndefined()) return true; 1240a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } else if (!info->getter()->IsUndefined() || 1241a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org !info->query()->IsUndefined()) { 1242a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return false; 1243a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 1244a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org break; 1245a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 1246a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org case LookupIterator::ACCESS_CHECK: 1247a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (it->GetHolder<JSObject>()->IsAccessCheckNeeded()) return false; 1248a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org break; 12491af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::ACCESSOR: 12501af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return !it->IsReadOnly(); 12511af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::DATA: { 1252a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (it->IsReadOnly()) return false; 12531af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<JSObject> holder = it->GetHolder<JSObject>(); 12541af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (receiver.is_identical_to(holder)) { 1255a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org it->PrepareForDataProperty(value); 1256a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // The previous receiver map might just have been deprecated, 1257a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // so reload it. 1258a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org update_receiver_type(receiver); 1259a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return true; 1260a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 1261f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org 1262a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // Receiver != holder. 12631af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org PrototypeIterator iter(it->isolate(), receiver); 1264a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (receiver->IsJSGlobalProxy()) { 1265a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return it->GetHolder<Object>().is_identical_to( 1266a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PrototypeIterator::GetCurrent(iter)); 1267a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 1268a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 1269a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org it->PrepareTransitionToDataProperty(value, NONE, store_mode); 1270a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return it->IsCacheableTransition(); 12711af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 1272bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org } 127357ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org } 1274ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org 1275a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org it->PrepareTransitionToDataProperty(value, NONE, store_mode); 1276a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return it->IsCacheableTransition(); 12775aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org} 12785aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 12795aa501ca9fb4dfb30f4191aac135202fe8d80e4aager@chromium.org 1280a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgMaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name, 1281c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> value, 1282c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org JSReceiver::StoreFromKeyed store_mode) { 1283474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // TODO(verwaest): Let SetProperty do the migration, since storing a property 1284474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // might deprecate the current map again, if value does not fit. 1285d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (MigrateDeprecated(object) || object->IsJSProxy()) { 12868f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<Object> result; 1287c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 12889bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org isolate(), result, 128951e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org Object::SetProperty(object, name, value, strict_mode()), Object); 1290c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return result; 12916bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 1292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 12936bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // If the object is undefined or null it's illegal to try to set any 12946bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org // properties on it; throw a TypeError in that case. 12956bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org if (object->IsUndefined() || object->IsNull()) { 12966bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org return TypeError("non_object_property_store", object, name); 12976bec0093ef661b53a1e338a233d7aafb9536a307mvstanton@chromium.org } 129843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 129943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Check if the given name is an array index. 130043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen uint32_t index; 130143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (name->AsArrayIndex(&index)) { 130251e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org // Ignore other stores where the receiver is not a JSObject. 130351e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org // TODO(1475): Must check prototype chains of object wrappers. 130451e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org if (!object->IsJSObject()) return value; 130551e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 130651e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org 13079e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org Handle<Object> result; 1308c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 1309a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate(), result, 1310c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org JSObject::SetElement(receiver, index, value, NONE, strict_mode()), 1311c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Object); 1312c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return value; 131343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 131443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1315e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org // Observed objects are always modified through the runtime. 131651e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org if (object->IsHeapObject() && 131751e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org Handle<HeapObject>::cast(object)->map()->is_observed()) { 13188f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<Object> result; 1319c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 132051e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org isolate(), result, 132151e852008f9f67dbdbae7a40b8aa07fe5c76b45fmachenbach@chromium.org Object::SetProperty(object, name, value, strict_mode(), store_mode), 1322c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Object); 1323c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return result; 1324e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org } 1325e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org 1326a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org LookupIterator it(object, name); 1327a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (FLAG_use_ic) UpdateCaches(&it, value, store_mode); 1328a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 132943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Set the property. 13308f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<Object> result; 1331c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 13329bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org isolate(), result, 1333a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Object::SetProperty(&it, value, strict_mode(), store_mode), Object); 1334c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return result; 133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 133643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 133743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1338a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgHandle<Code> CallIC::initialize_stub(Isolate* isolate, int argc, 1339d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CallICState::CallType call_type) { 1340d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CallICStub stub(isolate, CallICState(argc, call_type)); 1341a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Handle<Code> code = stub.GetCode(); 1342a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return code; 1343a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 1344a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1345a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 13469cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgHandle<Code> StoreIC::initialize_stub(Isolate* isolate, 1347486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org StrictMode strict_mode) { 134843c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org ExtraICState extra_state = ComputeExtraICState(strict_mode); 1349dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<Code> ic = 1350dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org PropertyICCompiler::ComputeStore(isolate, UNINITIALIZED, extra_state); 13519cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org return ic; 13529cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 13539cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 13549cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 13559cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgHandle<Code> StoreIC::megamorphic_stub() { 135606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (kind() == Code::STORE_IC) { 135706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return PropertyICCompiler::ComputeStore(isolate(), MEGAMORPHIC, 135806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org extra_ic_state()); 135906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 136006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DCHECK(kind() == Code::KEYED_STORE_IC); 136106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (strict_mode() == STRICT) { 136206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 136306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 136406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return isolate()->builtins()->KeyedStoreIC_Generic(); 136506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 136606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 13679cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 13689cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 13699cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 13709cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgHandle<Code> StoreIC::generic_stub() const { 137106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (kind() == Code::STORE_IC) { 137206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return PropertyICCompiler::ComputeStore(isolate(), GENERIC, 137306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org extra_ic_state()); 137406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 137506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DCHECK(kind() == Code::KEYED_STORE_IC); 137606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (strict_mode() == STRICT) { 137706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return isolate()->builtins()->KeyedStoreIC_Generic_Strict(); 137806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 137906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return isolate()->builtins()->KeyedStoreIC_Generic(); 138006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 138106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 138206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org} 138306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 138406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org 138506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.orgHandle<Code> StoreIC::slow_stub() const { 138606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (kind() == Code::STORE_IC) { 138706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return isolate()->builtins()->StoreIC_Slow(); 138806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 138906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org DCHECK(kind() == Code::KEYED_STORE_IC); 139006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org return isolate()->builtins()->KeyedStoreIC_Slow(); 139106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 13929cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 13939cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 13949cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 13959cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.orgHandle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, 1396486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org StrictMode strict_mode) { 139743c51e51fafad9405752a3d7e953367531469575machenbach@chromium.org ExtraICState state = ComputeExtraICState(strict_mode); 1398dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state); 13999cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org} 14009cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 14019cbaabda8b4daeb06759ace10c926ab55bb69d7bulan@chromium.org 1402a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, 1403a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org JSReceiver::StoreFromKeyed store_mode) { 1404a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (state() == UNINITIALIZED) { 1405a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // This is the first time we execute this inline cache. Set the target to 1406a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // the pre monomorphic stub to delay setting the monomorphic state. 1407a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org set_target(*pre_monomorphic_stub()); 1408a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org TRACE_IC("StoreIC", lookup->name()); 1409a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return; 1410a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 141143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 141206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org bool use_ic = LookupForWrite(lookup, value, store_mode); 141306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (!use_ic) { 141406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); 141506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 141606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); 1417d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 1418a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PatchCache(lookup->name(), code); 1419a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org TRACE_IC("StoreIC", lookup->name()); 1420d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org} 1421d16d8531698e91e9c60a7db9e0ba3c3bb15aff20mvstanton@chromium.org 142243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1423a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgHandle<Code> StoreIC::CompileHandler(LookupIterator* lookup, 1424a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> value, 1425a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org CacheHolderFlag cache_holder) { 1426a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); 1427a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 1428b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org // This is currently guaranteed by checks in StoreIC::Store. 1429a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); 1430a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> holder = lookup->GetHolder<JSObject>(); 1431a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(!receiver->IsAccessCheckNeeded()); 1432a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 14331af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org switch (lookup->state()) { 14341af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::TRANSITION: { 14351af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Map> transition = lookup->transition_map(); 14361af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // Currently not handled by CompileStoreTransition. 143706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (!holder->HasFastProperties()) { 143806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); 143906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 144006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 14412efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org 14421af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(lookup->IsCacheableTransition()); 1443a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 14441af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileStoreTransition(transition, lookup->name()); 1445a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 1446a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 14471af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::INTERCEPTOR: { 14481af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined()); 14491af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 14501af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileStoreInterceptor(lookup->name()); 145143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1452a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 14531af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::ACCESSOR: { 145406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (!holder->HasFastProperties()) { 145506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "StoreIC", "accessor on slow map"); 145606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 145706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 14581af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Object> accessors = lookup->GetAccessors(); 14591af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (accessors->IsExecutableAccessorInfo()) { 14601af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<ExecutableAccessorInfo> info = 14611af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<ExecutableAccessorInfo>::cast(accessors); 146206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (v8::ToCData<Address>(info->setter()) == 0) { 146306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == 0"); 146406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 146506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 14661af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (!ExecutableAccessorInfo::IsCompatibleReceiverType( 14671af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org isolate(), info, receiver_type())) { 146806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type"); 14691af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org break; 14701af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 14711af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 14721af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileStoreCallback(receiver, lookup->name(), info); 14731af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } else if (accessors->IsAccessorPair()) { 14741af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(), 14751af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org isolate()); 147606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (!setter->IsJSFunction()) { 147706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "StoreIC", "setter not a function"); 147806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org break; 147906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 14801af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<JSFunction> function = Handle<JSFunction>::cast(setter); 14811af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org CallOptimization call_optimization(function); 14821af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 14831af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (call_optimization.is_simple_api_call() && 14841af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org call_optimization.IsCompatibleReceiver(receiver, holder)) { 14851af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileStoreCallback(receiver, lookup->name(), 14861af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org call_optimization); 14871af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 14881af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileStoreViaSetter(receiver, lookup->name(), 14891af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<JSFunction>::cast(setter)); 14901af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 14911af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // TODO(dcarney): Handle correctly. 14921af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(accessors->IsDeclaredAccessorInfo()); 149306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "StoreIC", "declared accessor info"); 14941af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org break; 1495a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 14961af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org 14971af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::DATA: { 14981af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (lookup->is_dictionary_holder()) { 14991af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (holder->IsGlobalObject()) { 15001af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<PropertyCell> cell = lookup->GetPropertyCell(); 15011af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); 15021af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org StoreGlobalStub stub(isolate(), union_type->IsConstant(), 15031af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org receiver->IsJSGlobalProxy()); 15041af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<Code> code = stub.GetCodeCopyFromTemplate( 15051af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<GlobalObject>::cast(holder), cell); 15061af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // TODO(verwaest): Move caching of these NORMAL stubs outside as well. 15071af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org HeapObject::UpdateMapCodeCache(receiver, lookup->name(), code); 15081af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return code; 15091af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 15101af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(holder.is_identical_to(receiver)); 15111af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return isolate()->builtins()->StoreIC_Normal(); 15121af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 15131af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org 15141af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // -------------- Fields -------------- 15151af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (lookup->property_details().type() == FIELD) { 15161af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org bool use_stub = true; 15171af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (lookup->representation().IsHeapObject()) { 15181af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // Only use a generic stub if no types need to be tracked. 15191af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org Handle<HeapType> field_type = lookup->GetFieldType(); 15201af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org HeapType::Iterator<Map> it = field_type->Classes(); 15211af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org use_stub = it.Done(); 15221af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 15231af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org if (use_stub) { 15241af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), 15251af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org lookup->representation()); 15261af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return stub.GetCode(); 15271af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 15281af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 15291af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org return compiler.CompileStoreField(lookup); 15301af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 15311af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org 15321af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org // -------------- Constant properties -------------- 15331af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org DCHECK(lookup->property_details().type() == CONSTANT); 153406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property"); 15351af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org break; 1536a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 1537a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 15381af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::ACCESS_CHECK: 15391af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::JSPROXY: 15401af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org case LookupIterator::NOT_FOUND: 15411af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org UNREACHABLE(); 15421af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org } 15432efc3e46d2de48d8859520ee7fe035c02108509bmstarzinger@chromium.org return slow_stub(); 154443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 154543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 154643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1547003650ee766f5e92756d470a37973fd371757485yangguo@chromium.orgHandle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, 1548fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org KeyedAccessStoreMode store_mode) { 1549ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1550ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // via megamorphic stubs, since they don't have a map in their relocation info 1551ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // and so the stubs can't be harvested for the object needed for a map check. 15527a6fc815d62905d0c52705b96225b1bd23e00a43jkummerow@chromium.org if (target()->type() != Code::NORMAL) { 155306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type"); 1554fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 1555ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 1556ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 15577bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<Map> receiver_map(receiver->map(), isolate()); 15584edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org MapHandleList target_receiver_maps; 15594edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org TargetMaps(&target_receiver_maps); 15604edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org if (target_receiver_maps.length() == 0) { 1561af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org Handle<Map> monomorphic_map = 1562af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org ComputeTransitionedMap(receiver_map, store_mode); 1563750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org store_mode = GetNonTransitioningStoreMode(store_mode); 1564dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1565fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org monomorphic_map, strict_mode(), store_mode); 1566003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org } 1567003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1568750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // There are several special cases where an IC that is MONOMORPHIC can still 1569750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // transition to a different GetNonTransitioningStoreMode IC that handles a 1570750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // superset of the original IC. Handle those here if the receiver map hasn't 1571750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // changed or it has transitioned to a more general kind. 1572750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org KeyedAccessStoreMode old_store_mode = 1573cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.org KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); 15740f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org Handle<Map> previous_receiver_map = target_receiver_maps.at(0); 1575fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (state() == MONOMORPHIC) { 1576381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org Handle<Map> transitioned_receiver_map = receiver_map; 1577750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (IsTransitionStoreMode(store_mode)) { 1578af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org transitioned_receiver_map = 1579af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org ComputeTransitionedMap(receiver_map, store_mode); 1580381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org } 15817010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org if ((receiver_map.is_identical_to(previous_receiver_map) && 15827010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org IsTransitionStoreMode(store_mode)) || 1583a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org IsTransitionOfMonomorphicTarget(*previous_receiver_map, 1584a87904f0c75c5dd48d8fee355e5c67237c9e0606svenpanne@chromium.org *transitioned_receiver_map)) { 158597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org // If the "old" and "new" maps are in the same elements map family, or 158697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org // if they at least come from the same origin for a transitioning store, 158797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org // stay MONOMORPHIC and use the map for the most generic ElementsKind. 1588381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org store_mode = GetNonTransitioningStoreMode(store_mode); 1589dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1590381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org transitioned_receiver_map, strict_mode(), store_mode); 15910f6d2bb71d05a2a2fa33acccf8a0ef762e57148fhpayer@chromium.org } else if (*previous_receiver_map == receiver->map() && 1592169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org old_store_mode == STANDARD_STORE && 1593381adef828187e237e8758ab730dee1c2834a0b3machenbach@chromium.org (store_mode == STORE_AND_GROW_NO_TRANSITION || 1594169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1595169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { 1596169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // A "normal" IC that handles stores can switch to a version that can 1597169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // grow at the end of the array, handle OOB accesses or copy COW arrays 1598169691d93a961c8b511f8ac8fd8ee33d081ca10fdanno@chromium.org // and still stay MONOMORPHIC. 1599dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1600fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org receiver_map, strict_mode(), store_mode); 1601750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 160265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 160365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 1604e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(state() != GENERIC); 160565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 1606b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org bool map_added = 1607394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1608003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1609750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (IsTransitionStoreMode(store_mode)) { 1610750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Map> transitioned_receiver_map = 1611af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org ComputeTransitionedMap(receiver_map, store_mode); 1612750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, 1613750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org transitioned_receiver_map); 1614b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } 1615003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org 1616b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org if (!map_added) { 1617b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org // If the miss wasn't due to an unseen map, a polymorphic stub 1618ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // won't help, use the generic stub. 161906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "same map added twice"); 1620fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 1621ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 1622ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1623e297f5973a8a9ff0d9945da3f1e2d8a6230c294djkummerow@chromium.org // If the maximum number of receiver maps has been exceeded, use the generic 1624ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org // version of the IC. 16257b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 162606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "max polymorph exceeded"); 1627fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 1628ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 1629ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1630750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // Make sure all polymorphic handlers have the same store mode, otherwise the 1631750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org // generic stub must be used. 1632750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org store_mode = GetNonTransitioningStoreMode(store_mode); 1633750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (old_store_mode != STANDARD_STORE) { 1634750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (store_mode == STANDARD_STORE) { 1635750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org store_mode = old_store_mode; 1636750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else if (store_mode != old_store_mode) { 163706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "store mode mismatch"); 1638fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 1639750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 164065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 164165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 164291efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org // If the store mode isn't the standard mode, make sure that all polymorphic 164391efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org // receivers are either external arrays, or all "normal" arrays. Otherwise, 164491efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org // use the generic stub. 164591efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org if (store_mode != STANDARD_STORE) { 164691efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org int external_arrays = 0; 164791efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org for (int i = 0; i < target_receiver_maps.length(); ++i) { 16485c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org if (target_receiver_maps[i]->has_external_array_elements() || 16495c88bc39690cc94affe78cf5777eb8180c4af8a4machenbach@chromium.org target_receiver_maps[i]->has_fixed_typed_array_elements()) { 165091efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org external_arrays++; 165191efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org } 165291efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org } 165391efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org if (external_arrays != 0 && 165491efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org external_arrays != target_receiver_maps.length()) { 165506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", 1656a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org "unsupported combination of external and normal arrays"); 1657fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org return generic_stub(); 165891efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org } 165991efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org } 166091efda9680c1eac04b6babfbf812d79b7df3747ajkummerow@chromium.org 1661dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org return PropertyICCompiler::ComputeKeyedStorePolymorphic( 1662fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org &target_receiver_maps, store_mode, strict_mode()); 1663ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 1664ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1665ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 1666750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgHandle<Map> KeyedStoreIC::ComputeTransitionedMap( 1667a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Map> map, KeyedAccessStoreMode store_mode) { 1668750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org switch (store_mode) { 1669003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_SMI_TO_OBJECT: 1670003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_DOUBLE_TO_OBJECT: 1671003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: 1672003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT: 1673af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return Map::TransitionElementsTo(map, FAST_ELEMENTS); 1674003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_SMI_TO_DOUBLE: 1675003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE: 1676af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return Map::TransitionElementsTo(map, FAST_DOUBLE_ELEMENTS); 1677003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT: 1678003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: 1679003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT: 1680003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: 1681af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return Map::TransitionElementsTo(map, FAST_HOLEY_ELEMENTS); 1682003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE: 1683003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE: 1684af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return Map::TransitionElementsTo(map, FAST_HOLEY_DOUBLE_ELEMENTS); 1685750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: 1686e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(map->has_external_array_elements()); 1687a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // Fall through 1688750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org case STORE_NO_TRANSITION_HANDLE_COW: 1689750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org case STANDARD_STORE: 1690003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org case STORE_AND_GROW_NO_TRANSITION: 1691af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return map; 1692b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org } 1693af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org UNREACHABLE(); 1694af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org return MaybeHandle<Map>().ToHandleChecked(); 1695b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org} 1696b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 1697b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org 1698a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgbool IsOutOfBoundsAccess(Handle<JSObject> receiver, int index) { 1699750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (receiver->IsJSArray()) { 1700750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return JSArray::cast(*receiver)->length()->IsSmi() && 1701a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org index >= Smi::cast(JSArray::cast(*receiver)->length())->value(); 1702750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 1703750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return index >= receiver->elements()->length(); 1704750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org} 1705750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 1706750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 1707750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgKeyedAccessStoreMode KeyedStoreIC::GetStoreMode(Handle<JSObject> receiver, 1708750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Object> key, 1709750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org Handle<Object> value) { 17103484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org Handle<Smi> smi_key = Object::ToSmi(isolate(), key).ToHandleChecked(); 17113484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org int index = smi_key->value(); 1712750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org bool oob_access = IsOutOfBoundsAccess(receiver, index); 17136b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org // Don't consider this a growing store if the store would send the receiver to 17146b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org // dictionary mode. 17156b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org bool allow_growth = receiver->IsJSArray() && oob_access && 1716a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org !receiver->WouldConvertToSlowElements(key); 171765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (allow_growth) { 171865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Handle growing array in stub if necessary. 1719830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastSmiElements()) { 172065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (value->IsHeapNumber()) { 1721830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1722830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE; 1723830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1724830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE; 1725830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 172665a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 172765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (value->IsHeapObject()) { 1728830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1729830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT; 1730830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1731830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT; 1732830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 173365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 173465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } else if (receiver->HasFastDoubleElements()) { 173565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (!value->IsSmi() && !value->IsHeapNumber()) { 1736830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1737830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT; 1738830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1739830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT; 1740830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 174165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 174265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 174365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org return STORE_AND_GROW_NO_TRANSITION; 174465a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } else { 174565a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org // Handle only in-bounds elements accesses. 1746830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastSmiElements()) { 174765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (value->IsHeapNumber()) { 1748830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1749830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE; 1750830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1751830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_SMI_TO_DOUBLE; 1752830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 175365a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } else if (value->IsHeapObject()) { 1754830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1755830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_HOLEY_SMI_TO_OBJECT; 1756830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1757830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_SMI_TO_OBJECT; 1758830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 175965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 176065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } else if (receiver->HasFastDoubleElements()) { 176165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org if (!value->IsSmi() && !value->IsHeapNumber()) { 1762830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org if (receiver->HasFastHoleyElements()) { 1763830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT; 1764830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } else { 1765830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org return STORE_TRANSITION_DOUBLE_TO_OBJECT; 1766830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org } 176765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 176865a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 1769750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (!FLAG_trace_external_array_abuse && 1770750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org receiver->map()->has_external_array_elements() && oob_access) { 1771750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS; 17727bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org } 17737bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Heap* heap = receiver->GetHeap(); 17747bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org if (receiver->elements()->map() == heap->fixed_cow_array_map()) { 17757bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org return STORE_NO_TRANSITION_HANDLE_COW; 1776750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } else { 1777750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return STANDARD_STORE; 1778750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org } 177965a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org } 178065a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org} 178165a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 178265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org 1783c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgMaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, 1784c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> key, 1785c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> value) { 1786474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // TODO(verwaest): Let SetProperty do the migration, since storing a property 1787474e8b19cf12dc057572a8543864dd6586ee0a65machenbach@chromium.org // might deprecate the current map again, if value does not fit. 1788d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org if (MigrateDeprecated(object)) { 17898f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<Object> result; 1790c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 1791a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate(), result, Runtime::SetObjectProperty(isolate(), object, key, 1792a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org value, strict_mode()), 1793c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Object); 1794c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return result; 1795d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org } 1796d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1797f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Check for non-string values that can be converted into an 1798f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // internalized string directly or is representable as a smi. 179928faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org key = TryConvertKey(key, isolate()); 180028faa982749c4aa9c090939453dea14bb118f613jkummerow@chromium.org 1801c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> store_handle; 1802c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org Handle<Code> stub = generic_stub(); 180343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1804c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org if (key->IsInternalizedString()) { 1805c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 1806a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate(), store_handle, 1807a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org StoreIC::Store(object, Handle<String>::cast(key), value, 1808c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org JSReceiver::MAY_BE_STORE_FROM_KEYED), 1809c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Object); 18105830436a84f7792f61451af9bccd991d923fe81cjkummerow@chromium.org // TODO(jkummerow): Ideally we'd wrap this in "if (!is_target_set())", 18115830436a84f7792f61451af9bccd991d923fe81cjkummerow@chromium.org // but doing so causes Hydrogen crashes. Needs investigation. 18125830436a84f7792f61451af9bccd991d923fe81cjkummerow@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", 18135830436a84f7792f61451af9bccd991d923fe81cjkummerow@chromium.org "unhandled internalized string key"); 18145830436a84f7792f61451af9bccd991d923fe81cjkummerow@chromium.org TRACE_IC("StoreIC", key); 18155830436a84f7792f61451af9bccd991d923fe81cjkummerow@chromium.org set_target(*stub); 1816eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org return store_handle; 1817eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org } 1818d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org 1819eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org bool use_ic = 1820eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org FLAG_use_ic && !object->IsStringWrapper() && 1821eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() && 1822eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org !(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed()); 1823eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org if (use_ic && !object->IsSmi()) { 1824eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org // Don't use ICs for maps of the objects in Array's prototype chain. We 1825eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org // expect to be able to trap element sets to objects with those maps in 1826eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org // the runtime to enable optimization of element hole access. 1827eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); 182806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (heap_object->map()->IsMapInArrayPrototypeChain()) { 182906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "map in array prototype"); 183006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org use_ic = false; 183106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 1832eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org } 1833c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 1834eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org if (use_ic) { 1835e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!object->IsAccessCheckNeeded()); 1836eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org 1837eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org if (object->IsJSObject()) { 1838eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1839eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null(); 1840eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org if (receiver->elements()->map() == 1841eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org isolate()->heap()->sloppy_arguments_elements_map()) { 1842eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org if (strict_mode() == SLOPPY) { 1843eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org stub = sloppy_arguments_stub(); 184406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 184506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); 1846eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org } 1847eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org } else if (key_is_smi_like && 1848eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org !(target().is_identical_to(sloppy_arguments_stub()))) { 1849eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org // We should go generic if receiver isn't a dictionary, but our 1850eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org // prototype chain does have dictionary elements. This ensures that 1851eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org // other non-dictionary receivers in the polymorphic case benefit 1852eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org // from fast path keyed stores. 1853eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) { 1854eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); 1855eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org stub = StoreElementStub(receiver, store_mode); 185606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 185706b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype"); 18587b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org } 185906b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 186006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key"); 18613811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 186206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } else { 186306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver"); 1864c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 1865c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org } 1866c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org 1867fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org if (store_handle.is_null()) { 1868fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 1869a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate(), store_handle, 1870a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Runtime::SetObjectProperty(isolate(), object, key, value, 1871a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org strict_mode()), 1872fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org Object); 1873fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org } 1874fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org 1875e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!is_target_set()); 1876eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org Code* generic = *generic_stub(); 1877eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org if (*stub == generic) { 1878eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 18793811b436bf328d2ace6fe79ce99aeda71f9f06d3ager@chromium.org } 188006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org if (*stub == *slow_stub()) { 188106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); 188206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org } 1883e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!stub.is_null()); 1884eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org set_target(*stub); 1885eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org TRACE_IC("StoreIC", key); 188643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1887fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org return store_handle; 188843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 188943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 189043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 1891a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgbool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, 1892a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Handle<TypeFeedbackVector> vector, 1893a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Handle<Smi> slot, const CallICState& state) { 1894e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(FLAG_use_ic && function->IsJSFunction()); 18957e6132b924829c353864933f29124419916db550machenbach@chromium.org 18967e6132b924829c353864933f29124419916db550machenbach@chromium.org // Are we the array function? 1897a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSFunction> array_function = 1898a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSFunction>(isolate()->native_context()->array_function()); 18997e6132b924829c353864933f29124419916db550machenbach@chromium.org if (array_function.is_identical_to(Handle<JSFunction>::cast(function))) { 19007e6132b924829c353864933f29124419916db550machenbach@chromium.org // Alter the slot. 19018640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org IC::State old_state = FeedbackToState(vector, slot); 1902dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Object* feedback = vector->get(slot->value()); 1903dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org if (!feedback->IsAllocationSite()) { 1904dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org Handle<AllocationSite> new_site = 1905dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org isolate()->factory()->NewAllocationSite(); 1906dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org vector->set(slot->value(), *new_site); 1907dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org } 1908dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 1909e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org CallIC_ArrayStub stub(isolate(), state); 19107e6132b924829c353864933f29124419916db550machenbach@chromium.org set_target(*stub.GetCode()); 19117e6132b924829c353864933f29124419916db550machenbach@chromium.org Handle<String> name; 19127e6132b924829c353864933f29124419916db550machenbach@chromium.org if (array_function->shared()->name()->IsString()) { 19137e6132b924829c353864933f29124419916db550machenbach@chromium.org name = Handle<String>(String::cast(array_function->shared()->name()), 19147e6132b924829c353864933f29124419916db550machenbach@chromium.org isolate()); 19157e6132b924829c353864933f29124419916db550machenbach@chromium.org } 19167e6132b924829c353864933f29124419916db550machenbach@chromium.org 19178640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org IC::State new_state = FeedbackToState(vector, slot); 19188640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); 19198640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org TRACE_VECTOR_IC("CallIC (custom handler)", name, old_state, new_state); 19207e6132b924829c353864933f29124419916db550machenbach@chromium.org return true; 19217e6132b924829c353864933f29124419916db550machenbach@chromium.org } 19227e6132b924829c353864933f29124419916db550machenbach@chromium.org return false; 19237e6132b924829c353864933f29124419916db550machenbach@chromium.org} 19247e6132b924829c353864933f29124419916db550machenbach@chromium.org 19257e6132b924829c353864933f29124419916db550machenbach@chromium.org 19268640107360766c74218cf16d51b714b1f2138839machenbach@chromium.orgvoid CallIC::PatchMegamorphic(Handle<Object> function, 1927a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Handle<TypeFeedbackVector> vector, 1928a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Handle<Smi> slot) { 1929d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CallICState state(target()->extra_ic_state()); 19308640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org IC::State old_state = FeedbackToState(vector, slot); 1931e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 1932e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // We are going generic. 1933a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org vector->set(slot->value(), 1934a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org *TypeFeedbackVector::MegamorphicSentinel(isolate()), 1935e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org SKIP_WRITE_BARRIER); 1936e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 1937e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org CallICStub stub(isolate(), state); 1938e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org Handle<Code> code = stub.GetCode(); 1939e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org set_target(*code); 1940e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 19418640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<Object> name = isolate()->factory()->empty_string(); 19428640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (function->IsJSFunction()) { 19438640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); 19448640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org name = handle(js_function->shared()->name(), isolate()); 19458640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 19468640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 19478640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org IC::State new_state = FeedbackToState(vector, slot); 19488640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); 19498640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org TRACE_VECTOR_IC("CallIC", name, old_state, new_state); 1950e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org} 1951e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 1952e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 1953a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid CallIC::HandleMiss(Handle<Object> receiver, Handle<Object> function, 1954a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Handle<TypeFeedbackVector> vector, Handle<Smi> slot) { 1955d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CallICState state(target()->extra_ic_state()); 19568640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org IC::State old_state = FeedbackToState(vector, slot); 19578640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<Object> name = isolate()->factory()->empty_string(); 1958a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Object* feedback = vector->get(slot->value()); 1959a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1960dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // Hand-coded MISS handling is easier if CallIC slots don't contain smis. 1961e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!feedback->IsSmi()); 1962dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org 1963e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org if (feedback->IsJSFunction() || !function->IsJSFunction()) { 1964a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // We are going generic. 1965a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org vector->set(slot->value(), 1966a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org *TypeFeedbackVector::MegamorphicSentinel(isolate()), 1967a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org SKIP_WRITE_BARRIER); 1968a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } else { 1969dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // The feedback is either uninitialized or an allocation site. 1970dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // It might be an allocation site because if we re-compile the full code 1971dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // to add deoptimization support, we call with the default call-ic, and 1972dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // merely need to patch the target to match the feedback. 1973dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // TODO(mvstanton): the better approach is to dispense with patching 1974dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org // altogether, which is in progress. 1975a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org DCHECK(feedback == *TypeFeedbackVector::UninitializedSentinel(isolate()) || 1976dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org feedback->IsAllocationSite()); 19777e6132b924829c353864933f29124419916db550machenbach@chromium.org 19787e6132b924829c353864933f29124419916db550machenbach@chromium.org // Do we want to install a custom handler? 19797e6132b924829c353864933f29124419916db550machenbach@chromium.org if (FLAG_use_ic && 19807e6132b924829c353864933f29124419916db550machenbach@chromium.org DoCustomHandler(receiver, function, vector, slot, state)) { 19817e6132b924829c353864933f29124419916db550machenbach@chromium.org return; 19827e6132b924829c353864933f29124419916db550machenbach@chromium.org } 19837e6132b924829c353864933f29124419916db550machenbach@chromium.org 1984a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org vector->set(slot->value(), *function); 1985a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 19868640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 19878640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org if (function->IsJSFunction()) { 19888640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org Handle<JSFunction> js_function = Handle<JSFunction>::cast(function); 19898640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org name = handle(js_function->shared()->name(), isolate()); 19908640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org } 19918640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org 19928640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org IC::State new_state = FeedbackToState(vector, slot); 19938640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org OnTypeFeedbackChanged(isolate(), address(), old_state, new_state, true); 19948640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org TRACE_VECTOR_IC("CallIC", name, old_state, new_state); 1995a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 1996a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1997a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 1998394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com#undef TRACE_IC 1999394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 2000394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 200143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ---------------------------------------------------------------------------- 200243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Static IC stub generators. 200343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 200443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20051af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc. 2006a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgRUNTIME_FUNCTION(CallIC_Miss) { 20074c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2008a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org HandleScope scope(isolate); 2009e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 4); 2010a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org CallIC ic(isolate); 2011a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Handle<Object> receiver = args.at<Object>(0); 2012a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Handle<Object> function = args.at<Object>(1); 2013a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); 2014a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org Handle<Smi> slot = args.at<Smi>(3); 2015a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ic.HandleMiss(receiver, function, vector, slot); 2016a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org return *function; 2017a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org} 2018a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2019a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 2020e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.orgRUNTIME_FUNCTION(CallIC_Customization_Miss) { 20214c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2022e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org HandleScope scope(isolate); 2023e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 4); 2024e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org // A miss on a custom call ic always results in going megamorphic. 2025e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org CallIC ic(isolate); 2026e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org Handle<Object> function = args.at<Object>(1); 2027a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Handle<TypeFeedbackVector> vector = args.at<TypeFeedbackVector>(2); 2028e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org Handle<Smi> slot = args.at<Smi>(3); 20298640107360766c74218cf16d51b714b1f2138839machenbach@chromium.org ic.PatchMegamorphic(function, vector, slot); 2030e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org return *function; 2031e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org} 2032e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 2033e31b63e9608909e17e35a3330b0075140af2fe91machenbach@chromium.org 20341af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc. 2035a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(LoadIC_Miss) { 20364c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2037394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HandleScope scope(isolate); 2038e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 2); 2039e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2040d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 20415e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org Handle<Name> key = args.at<Name>(1); 2042d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2043c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> result; 2044c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 2045c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *result; 204643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 204743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 204843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 20491af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc 2050a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(KeyedLoadIC_Miss) { 20514c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2052394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HandleScope scope(isolate); 2053e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 2); 2054e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2055d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2056d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> key = args.at<Object>(1); 2057d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2058c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> result; 2059c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 2060c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *result; 2061e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org} 2062e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 2063e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org 2064a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(KeyedLoadIC_MissFromStubFailure) { 20654c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2066e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org HandleScope scope(isolate); 2067e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 2); 2068e3b8d0fe80e858c990832db1233c069f8b8cd5c9mstarzinger@chromium.org KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate); 2069d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2070d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> key = args.at<Object>(1); 2071d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2072c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> result; 2073c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); 2074c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *result; 2075ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 2076ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2077ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 20781af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc. 2079a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(StoreIC_Miss) { 20804c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2081c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org HandleScope scope(isolate); 2082e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 3); 20837bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2084d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2085d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<String> key = args.at<String>(1); 2086d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2087c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> result; 2088c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2089a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate, result, ic.Store(receiver, key, args.at<Object>(2))); 2090c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *result; 209143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 209243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 209343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2094a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(StoreIC_MissFromStubFailure) { 20954c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2096e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org HandleScope scope(isolate); 2097e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 3); 2098e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org StoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2099d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2100d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<String> key = args.at<String>(1); 2101d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2102c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> result; 2103c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2104a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate, result, ic.Store(receiver, key, args.at<Object>(2))); 2105c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *result; 2106e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org} 2107e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 2108e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 210941044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org// Extend storage is called in a store inline cache when 211041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org// it is necessary to extend the properties array of a 211141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org// JSObject. 2112a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(SharedStoreIC_ExtendStorage) { 21134c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2114c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org HandleScope shs(isolate); 2115e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 3); 211641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 211741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Convert the parameters 2118c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<JSObject> object = args.at<JSObject>(0); 2119c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Map> transition = args.at<Map>(1); 2120c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> value = args.at<Object>(2); 212141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 212241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Check the object has run out out property space. 2123e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object->HasFastProperties()); 2124e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(object->map()->unused_property_fields() == 0); 212541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 2126975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org JSObject::MigrateToNewProperty(object, transition, value); 212741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 212841044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org // Return the stored value. 2129c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *value; 213041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org} 213141044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 213241044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org 21331af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.org// Used from ic-<arch>.cc. 2134a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(KeyedStoreIC_Miss) { 21354c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2136394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com HandleScope scope(isolate); 2137e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 3); 21387bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2139d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2140d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> key = args.at<Object>(1); 2141d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2142c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> result; 2143c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2144a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate, result, ic.Store(receiver, key, args.at<Object>(2))); 2145c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *result; 21467bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org} 21477bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 21487bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org 2149a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(KeyedStoreIC_MissFromStubFailure) { 21504c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 21517bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org HandleScope scope(isolate); 2152e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 3); 21537bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2154d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> receiver = args.at<Object>(0); 2155d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org Handle<Object> key = args.at<Object>(1); 2156d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org ic.UpdateState(receiver, key); 2157c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> result; 2158c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2159a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate, result, ic.Store(receiver, key, args.at<Object>(2))); 2160c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *result; 2161ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 2162ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2163ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2164a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(StoreIC_Slow) { 2165fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HandleScope scope(isolate); 2166e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 3); 216757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 216857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Object> object = args.at<Object>(0); 216957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Object> key = args.at<Object>(1); 217057ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org Handle<Object> value = args.at<Object>(2); 2171486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org StrictMode strict_mode = ic.strict_mode(); 21728f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<Object> result; 21738f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 21748f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org isolate, result, 2175a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Runtime::SetObjectProperty(isolate, object, key, value, strict_mode)); 2176e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return *result; 217757ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org} 217857ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 217957ff881caeb2e15b46ac9e4dfc00e378f7c5f929ulan@chromium.org 2180a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(KeyedStoreIC_Slow) { 2181fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HandleScope scope(isolate); 2182e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 3); 21837bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2184ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Object> object = args.at<Object>(0); 2185ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Object> key = args.at<Object>(1); 2186ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org Handle<Object> value = args.at<Object>(2); 2187486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org StrictMode strict_mode = ic.strict_mode(); 21888f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<Object> result; 21898f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 21908f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org isolate, result, 2191a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Runtime::SetObjectProperty(isolate, object, key, value, strict_mode)); 2192e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return *result; 2193ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 2194ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2195ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2196a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss) { 21974c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2198fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HandleScope scope(isolate); 2199e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 4); 2200ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2201ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Object> value = args.at<Object>(0); 2202e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org Handle<Map> map = args.at<Map>(1); 2203ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Object> key = args.at<Object>(2); 2204ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org Handle<Object> object = args.at<Object>(3); 2205486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org StrictMode strict_mode = ic.strict_mode(); 2206e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org if (object->IsJSObject()) { 2207e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), 2208e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org map->elements_kind()); 2209e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org } 22108f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org Handle<Object> result; 22118f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 22128f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org isolate, result, 2213a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Runtime::SetObjectProperty(isolate, object, key, value, strict_mode)); 2214e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org return *result; 2215ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org} 2216ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2217ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org 2218c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgMaybeHandle<Object> BinaryOpIC::Transition( 2219a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<AllocationSite> allocation_site, Handle<Object> left, 2220c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> right) { 2221d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org BinaryOpICState state(isolate(), target()->extra_ic_state()); 2222ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org 2223ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Compute the actual result using the builtin for the binary operation. 2224ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Object* builtin = isolate()->js_builtins_object()->javascript_builtin( 2225ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org TokenToJSBuiltin(state.op())); 2226ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); 22272ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org Handle<Object> result; 2228c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_ON_EXCEPTION( 2229a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate(), result, Execution::Call(isolate(), function, left, 1, &right), 2230c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Object); 2231a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 22322904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org // Execution::Call can execute arbitrary JavaScript, hence potentially 22332904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org // update the state of this very IC, so we must update the stored state. 22342904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org UpdateTarget(); 2235ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Compute the new state. 2236d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org BinaryOpICState old_state(isolate(), target()->extra_ic_state()); 2237ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org state.Update(left, right, result); 2238a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 22390f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Check if we have a string operation here. 22400f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org Handle<Code> target; 22410f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (!allocation_site.is_null() || state.ShouldCreateAllocationMementos()) { 22420f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Setup the allocation site on-demand. 22430f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (allocation_site.is_null()) { 22440f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org allocation_site = isolate()->factory()->NewAllocationSite(); 22450f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 22460f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 22470f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Install the stub with an allocation site. 2248f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org BinaryOpICWithAllocationSiteStub stub(isolate(), state); 2249f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org target = stub.GetCodeCopyFromTemplate(allocation_site); 22500f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 22510f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Sanity check the trampoline stub. 2252e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(*allocation_site, target->FindFirstAllocationSite()); 22530f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } else { 22540f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Install the generic stub. 2255f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org BinaryOpICStub stub(isolate(), state); 2256f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org target = stub.GetCode(); 22570f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 22580f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org // Sanity check the generic stub. 2259e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(NULL, target->FindFirstAllocationSite()); 22600f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 22610f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org set_target(*target); 226225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org 226325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org if (FLAG_trace_ic) { 2264d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org OFStream os(stdout); 2265d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org os << "[BinaryOpIC" << old_state << " => " << state << " @ " 2266d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org << static_cast<void*>(*target) << " <- "; 226725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 22680f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org if (!allocation_site.is_null()) { 2269d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org os << " using allocation site " << static_cast<void*>(*allocation_site); 22700f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org } 2271d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org os << "]" << endl; 2272fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 2273fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2274ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org // Patch the inlined smi code as necessary. 2275ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org if (!old_state.UseInlinedSmiCode() && state.UseInlinedSmiCode()) { 227625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); 2277ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org } else if (old_state.UseInlinedSmiCode() && !state.UseInlinedSmiCode()) { 227825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK); 227925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 2280fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2281c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return result; 2282d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org} 2283d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org 2284a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2285a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(BinaryOpIC_Miss) { 22864c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2287ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org HandleScope scope(isolate); 2288e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(2, args.length()); 2289ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft); 2290ce9c514a4e015930324b2b45326a478a69535388machenbach@chromium.org Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight); 229125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org BinaryOpIC ic(isolate); 2292c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> result; 2293c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2294a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate, result, 2295c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ic.Transition(Handle<AllocationSite>::null(), left, right)); 2296c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *result; 22970f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org} 22980f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 22990f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org 2300a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(BinaryOpIC_MissWithAllocationSite) { 23014c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 23020f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org HandleScope scope(isolate); 2303e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK_EQ(3, args.length()); 2304a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<AllocationSite> allocation_site = 2305a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org args.at<AllocationSite>(BinaryOpWithAllocationSiteStub::kAllocationSite); 2306a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> left = args.at<Object>(BinaryOpWithAllocationSiteStub::kLeft); 2307a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> right = 2308a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org args.at<Object>(BinaryOpWithAllocationSiteStub::kRight); 23090f13e74b7310d8b14f19c6b93b36ff95059f97f6ulan@chromium.org BinaryOpIC ic(isolate); 2310c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> result; 2311c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2312a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate, result, ic.Transition(allocation_site, left, right)); 2313c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *result; 2314ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org} 2315ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 2316ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org 23173d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgCode* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { 2318d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICStub stub(isolate, op, CompareICState::UNINITIALIZED, 2319d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::UNINITIALIZED, 2320d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::UNINITIALIZED); 2321212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org Code* code = NULL; 2322f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CHECK(stub.FindCodeInCache(&code)); 2323212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org return code; 2324212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org} 2325212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 2326212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org 23278432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.orgHandle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) { 2328d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICStub stub(isolate, op, CompareICState::UNINITIALIZED, 2329d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::UNINITIALIZED, 2330d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::UNINITIALIZED); 2331f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org return stub.GetCode(); 2332a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2333a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2334a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2335b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.orgCode* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { 2336c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org HandleScope scope(isolate()); 233742ed2fc449e83fab2ccbf1b769a5e83715c9d783machenbach@chromium.org CompareICStub old_stub(target()->stub_key(), isolate()); 2338d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::State new_left = 2339d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::NewInputState(old_stub.left(), x); 2340d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::State new_right = 2341d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::NewInputState(old_stub.right(), y); 2342d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::State state = CompareICState::TargetState( 2343d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org old_stub.state(), old_stub.left(), old_stub.right(), op_, 2344d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org HasInlinedSmiCode(address()), x, y); 23459aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org CompareICStub stub(isolate(), op_, new_left, new_right, state); 2346d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org if (state == CompareICState::KNOWN_OBJECT) { 23477bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org stub.set_known_map( 23487bd87f0fe09b5d7c12de8f1db0bdb759dc4130acjkummerow@chromium.org Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate())); 2349fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 2350f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org Handle<Code> new_target = stub.GetCode(); 2351b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org set_target(*new_target); 2352fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2353fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org if (FLAG_trace_ic) { 2354fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org PrintF("[CompareIC in "); 2355c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 235621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n", 2357d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::GetStateName(old_stub.left()), 2358d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::GetStateName(old_stub.right()), 2359d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::GetStateName(old_stub.state()), 2360d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::GetStateName(new_left), 2361d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::GetStateName(new_right), 2362d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org CompareICState::GetStateName(state), Token::Name(op_), 236321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org static_cast<void*>(*stub.GetCode())); 2364fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 2365fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org 2366fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org // Activate inlined smi code. 2367d3df75b4472c9d5d4d2615aaea74d2adce4160f8machenbach@chromium.org if (old_stub.state() == CompareICState::UNINITIALIZED) { 2368fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); 2369fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org } 2370b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org 2371b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return *new_target; 2372a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2373a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2374a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 23759aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org// Used from CompareICStub::GenerateMiss in code-stubs-<arch>.cc. 2376a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(CompareIC_Miss) { 23774c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2378fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org HandleScope scope(isolate); 2379e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 3); 23806d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org CompareIC ic(isolate, static_cast<Token::Value>(args.smi_at(2))); 2381b5be0a91a2e75da55653dd3583b7f3c1c54f7309machenbach@chromium.org return ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); 2382a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org} 2383a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2384a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org 2385a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgvoid CompareNilIC::Clear(Address address, Code* target, 238697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org ConstantPoolArray* constant_pool) { 2387fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org if (IsCleared(target)) return; 2388f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ExtraICState state = target->extra_ic_state(); 2389ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2390a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org CompareNilICStub stub(target->GetIsolate(), state, 2391f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org HydrogenCodeStub::UNINITIALIZED); 239241728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org stub.ClearState(); 2393ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 23944e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org Code* code = NULL; 2395f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CHECK(stub.FindCodeInCache(&code)); 23964e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 239797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org SetTargetAtAddress(address, code, constant_pool); 2398ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 2399ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2400ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2401a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgHandle<Object> CompareNilIC::DoCompareNilSlow(Isolate* isolate, NilValue nil, 2402c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org Handle<Object> object) { 2403ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org if (object->IsNull() || object->IsUndefined()) { 2404c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return handle(Smi::FromInt(true), isolate); 2405ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2406c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return handle(Smi::FromInt(object->IsUndetectableObject()), isolate); 2407ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 2408ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2409ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2410c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgHandle<Object> CompareNilIC::CompareNil(Handle<Object> object) { 2411f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ExtraICState extra_ic_state = target()->extra_ic_state(); 2412ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2413f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org CompareNilICStub stub(isolate(), extra_ic_state); 24144e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 2415ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Extract the current supported types from the patched IC and calculate what 2416ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // types must be supported as a result of the miss. 24174e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org bool already_monomorphic = stub.IsMonomorphic(); 24184e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org 2419e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org stub.UpdateStatus(object); 2420ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 242121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org NilValue nil = stub.nil_value(); 2422ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2423ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org // Find or create the specialized stub to support the new set of types. 2424ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Handle<Code> code; 24254e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org if (stub.IsMonomorphic()) { 24264edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org Handle<Map> monomorphic_map(already_monomorphic && FirstTargetMap() != NULL 2427a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ? FirstTargetMap() 2428a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org : HeapObject::cast(*object)->map()); 2429dc207d99f9dbff76065405b65f3d88e1fb49fc1cmachenbach@chromium.org code = PropertyICCompiler::ComputeCompareNil(monomorphic_map, &stub); 2430ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } else { 2431f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org code = stub.GetCode(); 2432ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org } 2433b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org set_target(*code); 2434c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return DoCompareNilSlow(isolate(), nil, object); 2435ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 2436ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2437ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2438a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(CompareNilIC_Miss) { 24394c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2440ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org HandleScope scope(isolate); 2441ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org Handle<Object> object = args.at<Object>(0); 2442ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org CompareNilIC ic(isolate); 2443c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *ic.CompareNil(object); 2444ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org} 2445ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2446ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org 2447a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(Unreachable) { 244877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org UNREACHABLE(); 244977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org CHECK(false); 245077ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org return isolate->heap()->undefined_value(); 245177ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org} 245277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 245377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org 245425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.orgBuiltins::JavaScript BinaryOpIC::TokenToJSBuiltin(Token::Value op) { 245525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org switch (op) { 245625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org default: 245725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org UNREACHABLE(); 245825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::ADD: 245925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::ADD; 246025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 246125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SUB: 246225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::SUB; 246325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 246425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::MUL: 246525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::MUL; 246625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 246725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::DIV: 246825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::DIV; 246925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 247025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::MOD: 247125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::MOD; 247225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 247325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::BIT_OR: 247425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::BIT_OR; 247525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 247625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::BIT_AND: 247725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::BIT_AND; 247825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 247925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::BIT_XOR: 248025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::BIT_XOR; 248125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 248225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SAR: 248325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::SAR; 248425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 248525b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SHR: 248625b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::SHR; 248725b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 248825b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org case Token::SHL: 248925b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org return Builtins::SHL; 249025b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org break; 249125b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org } 249225b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org} 249325b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org 249425b0e21ac53cd2e892094493a65f75258fa977f0jkummerow@chromium.org 2495c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.orgHandle<Object> ToBooleanIC::ToBoolean(Handle<Object> object) { 2496f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org ToBooleanStub stub(isolate(), target()->extra_ic_state()); 2497e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org bool to_boolean_value = stub.UpdateStatus(object); 2498f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org Handle<Code> code = stub.GetCode(); 2499b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org set_target(*code); 2500c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return handle(Smi::FromInt(to_boolean_value ? 1 : 0), isolate()); 25019fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org} 25029fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 25039fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 2504a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgRUNTIME_FUNCTION(ToBooleanIC_Miss) { 25054c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org TimerEventScope<TimerEventIcMiss> timer(isolate); 2506e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(args.length() == 1); 2507b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org HandleScope scope(isolate); 2508b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org Handle<Object> object = args.at<Object>(0); 2509b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org ToBooleanIC ic(isolate); 2510c2e08d7d6b03e672e13fc3bf274a292009decce6machenbach@chromium.org return *ic.ToBoolean(object); 25119fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org} 25129fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 25139fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 2514a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgRUNTIME_FUNCTION(StoreCallbackProperty) { 2515a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> receiver = args.at<JSObject>(0); 2516a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> holder = args.at<JSObject>(1); 2517a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<ExecutableAccessorInfo> callback = args.at<ExecutableAccessorInfo>(2); 2518a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Name> name = args.at<Name>(3); 2519a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> value = args.at<Object>(4); 2520a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org HandleScope scope(isolate); 2521a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2522a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(callback->IsCompatibleReceiver(*receiver)); 2523a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2524a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Address setter_address = v8::ToCData<Address>(callback->setter()); 2525a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org v8::AccessorNameSetterCallback fun = 2526a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org FUNCTION_CAST<v8::AccessorNameSetterCallback>(setter_address); 2527a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(fun != NULL); 2528a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2529a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org LOG(isolate, ApiNamedPropertyAccess("store", *receiver, *name)); 2530a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PropertyCallbackArguments custom_args(isolate, callback->data(), *receiver, 2531a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org *holder); 2532a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org custom_args.Call(fun, v8::Utils::ToLocal(name), v8::Utils::ToLocal(value)); 2533a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 2534a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return *value; 2535a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 2536a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2537a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2538a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org/** 2539a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org * Attempts to load a property with an interceptor (which must be present), 2540a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org * but doesn't search the prototype chain. 2541a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org * 2542a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org * Returns |Heap::no_interceptor_result_sentinel()| if interceptor doesn't 2543a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org * provide any value for the given name. 2544a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org */ 2545a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgRUNTIME_FUNCTION(LoadPropertyWithInterceptorOnly) { 2546a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength); 2547a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Name> name_handle = 2548a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex); 2549a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<InterceptorInfo> interceptor_info = args.at<InterceptorInfo>( 2550a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org NamedLoadHandlerCompiler::kInterceptorArgsInfoIndex); 2551a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2552a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // TODO(rossberg): Support symbols in the API. 2553a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (name_handle->IsSymbol()) 2554a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return isolate->heap()->no_interceptor_result_sentinel(); 2555a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<String> name = Handle<String>::cast(name_handle); 2556a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2557a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Address getter_address = v8::ToCData<Address>(interceptor_info->getter()); 2558a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org v8::NamedPropertyGetterCallback getter = 2559a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address); 2560a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(getter != NULL); 2561a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2562a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> receiver = 2563a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex); 2564a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> holder = 2565a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex); 2566a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PropertyCallbackArguments callback_args(isolate, interceptor_info->data(), 2567a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org *receiver, *holder); 2568a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org { 2569a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // Use the interceptor getter. 2570a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org HandleScope scope(isolate); 2571a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org v8::Handle<v8::Value> r = 2572a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org callback_args.Call(getter, v8::Utils::ToLocal(name)); 2573a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 2574a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (!r.IsEmpty()) { 2575a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> result = v8::Utils::OpenHandle(*r); 2576a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org result->VerifyApiCallResultType(); 2577a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return *v8::Utils::OpenHandle(*r); 2578a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 2579a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 2580a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2581a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return isolate->heap()->no_interceptor_result_sentinel(); 2582a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 2583a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2584a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2585a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgstatic Object* ThrowReferenceError(Isolate* isolate, Name* name) { 2586a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // If the load is non-contextual, just return the undefined result. 2587a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // Note that both keyed and non-keyed loads may end up here. 2588a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org HandleScope scope(isolate); 2589a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2590a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (ic.contextual_mode() != CONTEXTUAL) { 2591a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return isolate->heap()->undefined_value(); 2592a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 2593a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2594a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org // Throw a reference error. 2595a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Name> name_handle(name); 2596ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org THROW_NEW_ERROR_RETURN_FAILURE( 2597ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org isolate, NewReferenceError("not_defined", HandleVector(&name_handle, 1))); 2598a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 2599a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2600a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2601a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org/** 2602a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org * Loads a property with an interceptor performing post interceptor 2603a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org * lookup if interceptor failed. 2604a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org */ 2605a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgRUNTIME_FUNCTION(LoadPropertyWithInterceptor) { 2606a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org HandleScope scope(isolate); 2607a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(args.length() == NamedLoadHandlerCompiler::kInterceptorArgsLength); 2608a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Name> name = 2609a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org args.at<Name>(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex); 2610a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> receiver = 2611a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex); 2612a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> holder = 2613a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org args.at<JSObject>(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex); 2614a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2615a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> result; 2616a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org LookupIterator it(receiver, name, holder); 2617a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, 2618a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org JSObject::GetProperty(&it)); 2619a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2620a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (it.IsFound()) return *result; 2621a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2622a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return ThrowReferenceError(isolate, Name::cast(args[0])); 2623a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 2624a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2625a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2626a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgRUNTIME_FUNCTION(StorePropertyWithInterceptor) { 2627a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org HandleScope scope(isolate); 2628a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(args.length() == 3); 2629a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2630a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> receiver = args.at<JSObject>(0); 2631a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Name> name = args.at<Name>(1); 2632a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> value = args.at<Object>(2); 2633a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#ifdef DEBUG 2634a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PrototypeIterator iter(isolate, receiver, 2635a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org PrototypeIterator::START_AT_RECEIVER); 2636a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org bool found = false; 2637a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) { 2638a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> current = PrototypeIterator::GetCurrent(iter); 2639a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org if (current->IsJSObject() && 2640a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject>::cast(current)->HasNamedInterceptor()) { 2641a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org found = true; 2642a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org break; 2643a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 2644a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org } 2645a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(found); 2646a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#endif 2647a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> result; 2648a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2649a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate, result, 2650a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org JSObject::SetProperty(receiver, name, value, ic.strict_mode())); 2651a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return *result; 2652a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 2653a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2654a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2655a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgRUNTIME_FUNCTION(LoadElementWithInterceptor) { 2656a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org HandleScope scope(isolate); 2657a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<JSObject> receiver = args.at<JSObject>(0); 2658a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org DCHECK(args.smi_at(1) >= 0); 2659a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org uint32_t index = args.smi_at(1); 2660a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org Handle<Object> result; 2661a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2662a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org isolate, result, 2663a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org JSObject::GetElementWithInterceptor(receiver, receiver, index)); 2664a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org return *result; 2665a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} 2666a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2667a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org 2668fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgRUNTIME_FUNCTION(VectorLoadIC_MissFromStubFailure) { 2669fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org // TODO(mvstanton): To be enabled when ICs can accept a vector and slot 2670fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org return NULL; 2671fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org} 2672fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org 2673fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org 2674fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.orgRUNTIME_FUNCTION(VectorKeyedLoadIC_MissFromStubFailure) { 2675fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org // TODO(mvstanton): To be enabled when ICs can accept a vector and slot 2676fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org return NULL; 2677fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org} 2678fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org 2679fa7f914e3bacba481b13da5cf2bc4c935567ebc4machenbach@chromium.org 2680ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic const Address IC_utilities[] = { 268143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define ADDR(name) FUNCTION_ADDR(name), 2682a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org IC_UTIL_LIST(ADDR) NULL 268343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef ADDR 268443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 268543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 268643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2687a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.orgAddress IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 268843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 2689a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org} // namespace v8::internal 2690