V8 Project
v8::internal::KeyedStoreIC Class Reference

#include <ic.h>

+ Inheritance diagram for v8::internal::KeyedStoreIC:
+ Collaboration diagram for v8::internal::KeyedStoreIC:

Classes

class  ExtraICStateKeyedAccessStoreMode
 

Public Member Functions

 KeyedStoreIC (FrameDepth depth, Isolate *isolate)
 
MUST_USE_RESULT MaybeHandle< ObjectStore (Handle< Object > object, Handle< Object > name, Handle< Object > value)
 
- Public Member Functions inherited from v8::internal::StoreIC
 StoreIC (FrameDepth depth, Isolate *isolate)
 
StrictMode strict_mode () const
 
MUST_USE_RESULT MaybeHandle< ObjectStore (Handle< Object > object, Handle< Name > name, Handle< Object > value, JSReceiver::StoreFromKeyed store_mode=JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED)
 
bool LookupForWrite (LookupIterator *it, Handle< Object > value, JSReceiver::StoreFromKeyed store_mode)
 
- Public Member Functions inherited from v8::internal::IC
 IC (FrameDepth depth, Isolate *isolate)
 
virtual ~IC ()
 
State state () const
 
Address address () const
 
void UpdateState (Handle< Object > receiver, Handle< Object > name)
 
bool IsNameCompatibleWithPrototypeFailure (Handle< Object > name)
 
void MarkPrototypeFailure (Handle< Object > name)
 

Static Public Member Functions

static ExtraICState ComputeExtraICState (StrictMode flag, KeyedAccessStoreMode mode)
 
static KeyedAccessStoreMode GetKeyedAccessStoreMode (ExtraICState extra_state)
 
static void GenerateInitialize (MacroAssembler *masm)
 
static void GeneratePreMonomorphic (MacroAssembler *masm)
 
static void GenerateMiss (MacroAssembler *masm)
 
static void GenerateSlow (MacroAssembler *masm)
 
static void GenerateGeneric (MacroAssembler *masm, StrictMode strict_mode)
 
static void GenerateSloppyArguments (MacroAssembler *masm)
 
- Static Public Member Functions inherited from v8::internal::StoreIC
static ExtraICState ComputeExtraICState (StrictMode flag)
 
static StrictMode GetStrictMode (ExtraICState state)
 
static void GenerateSlow (MacroAssembler *masm)
 
static void GenerateInitialize (MacroAssembler *masm)
 
static void GeneratePreMonomorphic (MacroAssembler *masm)
 
static void GenerateMiss (MacroAssembler *masm)
 
static void GenerateMegamorphic (MacroAssembler *masm)
 
static void GenerateNormal (MacroAssembler *masm)
 
static void GenerateRuntimeSetProperty (MacroAssembler *masm, StrictMode strict_mode)
 
static Handle< Codeinitialize_stub (Isolate *isolate, StrictMode strict_mode)
 
- Static Public Member Functions inherited from v8::internal::IC
static Address AddressFromUtilityId (UtilityId id)
 
static void RegisterWeakMapDependency (Handle< Code > stub)
 
static void InvalidateMaps (Code *stub)
 
static void Clear (Isolate *isolate, Address address, ConstantPoolArray *constant_pool)
 
template<class TypeClass >
static JSFunctionGetRootConstructor (TypeClass *type, Context *native_context)
 
static Handle< MapGetHandlerCacheHolder (HeapType *type, bool receiver_is_holder, Isolate *isolate, CacheHolderFlag *flag)
 
static Handle< MapGetICCacheHolder (HeapType *type, Isolate *isolate, CacheHolderFlag *flag)
 
static bool IsCleared (Code *code)
 
static Handle< MapTypeToMap (HeapType *type, Isolate *isolate)
 
template<class T >
static T::TypeHandle MapToType (Handle< Map > map, typename T::Region *region)
 
static Handle< HeapTypeCurrentTypeOf (Handle< Object > object, Isolate *isolate)
 

Protected Member Functions

virtual Handle< Codepre_monomorphic_stub () const
 
Handle< CodeStoreElementStub (Handle< JSObject > receiver, KeyedAccessStoreMode store_mode)
 
- Protected Member Functions inherited from v8::internal::StoreIC
virtual Handle< Codemegamorphic_stub () OVERRIDE
 
Handle< Codegeneric_stub () const
 
Handle< Codeslow_stub () const
 
void UpdateCaches (LookupIterator *lookup, Handle< Object > value, JSReceiver::StoreFromKeyed store_mode)
 
virtual Handle< CodeCompileHandler (LookupIterator *lookup, Handle< Object > value, CacheHolderFlag cache_holder)
 
- Protected Member Functions inherited from v8::internal::IC
Handle< Codetarget () const
 
Address fp () const
 
Address pc () const
 
Isolateisolate () const
 
SharedFunctionInfoGetSharedFunctionInfo () const
 
CodeGetCode () const
 
CodeGetOriginalCode () const
 
void set_target (Code *code)
 
bool is_target_set ()
 
char TransitionMarkFromState (IC::State state)
 
void TraceIC (const char *type, Handle< Object > name)
 
void TraceIC (const char *type, Handle< Object > name, State old_state, State new_state)
 
MaybeHandle< ObjectTypeError (const char *type, Handle< Object > object, Handle< Object > key)
 
MaybeHandle< ObjectReferenceError (const char *type, Handle< Name > name)
 
Handle< CodeComputeHandler (LookupIterator *lookup, Handle< Object > value=Handle< Code >::null())
 
void UpdateMonomorphicIC (Handle< Code > handler, Handle< Name > name)
 
bool UpdatePolymorphicIC (Handle< Name > name, Handle< Code > code)
 
void UpdateMegamorphicCache (HeapType *type, Name *name, Code *code)
 
void CopyICToMegamorphicCache (Handle< Name > name)
 
bool IsTransitionOfMonomorphicTarget (Map *source_map, Map *target_map)
 
void PatchCache (Handle< Name > name, Handle< Code > code)
 
Code::Kind kind () const
 
Code::Kind handler_kind () const
 
bool TryRemoveInvalidPrototypeDependentStub (Handle< Object > receiver, Handle< String > name)
 
ExtraICState extra_ic_state () const
 
void set_extra_ic_state (ExtraICState state)
 
Handle< HeapTypereceiver_type ()
 
void update_receiver_type (Handle< Object > receiver)
 
void TargetMaps (MapHandleList *list)
 
void TargetTypes (TypeHandleList *list)
 
MapFirstTargetMap ()
 
void UpdateTarget ()
 

Static Protected Member Functions

static Handle< Codepre_monomorphic_stub (Isolate *isolate, StrictMode strict_mode)
 
- Static Protected Member Functions inherited from v8::internal::StoreIC
static Handle< Codepre_monomorphic_stub (Isolate *isolate, StrictMode strict_mode)
 
- Static Protected Member Functions inherited from v8::internal::IC
static CodeGetTargetAtAddress (Address address, ConstantPoolArray *constant_pool)
 
static void SetTargetAtAddress (Address address, Code *target, ConstantPoolArray *constant_pool)
 
static void OnTypeFeedbackChanged (Isolate *isolate, Address address, State old_state, State new_state, bool target_remains_ic_stub)
 
static void PostPatching (Address address, Code *target, Code *old_target)
 

Private Member Functions

void set_target (Code *code)
 
Handle< Codesloppy_arguments_stub ()
 
KeyedAccessStoreMode GetStoreMode (Handle< JSObject > receiver, Handle< Object > key, Handle< Object > value)
 
Handle< MapComputeTransitionedMap (Handle< Map > map, KeyedAccessStoreMode store_mode)
 

Static Private Member Functions

static void Clear (Isolate *isolate, Address address, Code *target, ConstantPoolArray *constant_pool)
 

Friends

class IC
 

Additional Inherited Members

- Public Types inherited from v8::internal::IC
enum  UtilityId { kUtilityCount }
 
enum  FrameDepth { NO_EXTRA_FRAME = 0 , EXTRA_CALL_FRAME = 1 }
 
typedef InlineCacheState State
 
- Static Public Attributes inherited from v8::internal::StoreIC
static const ExtraICState kStrictModeState = 1 << StrictModeState::kShift
 

Detailed Description

Definition at line 530 of file ic.h.

Constructor & Destructor Documentation

◆ KeyedStoreIC()

v8::internal::KeyedStoreIC::KeyedStoreIC ( FrameDepth  depth,
Isolate isolate 
)
inline

Definition at line 548 of file ic.h.

548  : StoreIC(depth, isolate) {
549  DCHECK(target()->is_keyed_store_stub());
550  }
Isolate * isolate() const
Definition: ic.h:136
Handle< Code > target() const
Definition: ic.h:132
StoreIC(FrameDepth depth, Isolate *isolate)
Definition: ic.h:461
#define DCHECK(condition)
Definition: logging.h:205

References DCHECK, and v8::internal::IC::target().

+ Here is the call graph for this function:

Member Function Documentation

◆ Clear()

void v8::internal::KeyedStoreIC::Clear ( Isolate isolate,
Address  address,
Code target,
ConstantPoolArray constant_pool 
)
staticprivate

Definition at line 545 of file ic.cc.

546  {
547  if (IsCleared(target)) return;
550  isolate, StoreIC::GetStrictMode(target->extra_ic_state())),
551  constant_pool);
552 }
static void SetTargetAtAddress(Address address, Code *target, ConstantPoolArray *constant_pool)
Definition: ic-inl.h:96
ConstantPoolArray * constant_pool() const
Definition: ic-inl.h:51
Address address() const
Definition: ic-inl.h:19
static bool IsCleared(Code *code)
Definition: ic.h:112
virtual Handle< Code > pre_monomorphic_stub() const
Definition: ic.h:567
static StrictMode GetStrictMode(ExtraICState state)
Definition: ic.h:453

References v8::internal::IC::address(), v8::internal::IC::constant_pool(), v8::internal::StoreIC::GetStrictMode(), v8::internal::IC::IsCleared(), v8::internal::IC::isolate(), pre_monomorphic_stub(), v8::internal::IC::SetTargetAtAddress(), and v8::internal::IC::target().

Referenced by v8::internal::IC::Clear().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ComputeExtraICState()

static ExtraICState v8::internal::KeyedStoreIC::ComputeExtraICState ( StrictMode  flag,
KeyedAccessStoreMode  mode 
)
inlinestatic

Definition at line 537 of file ic.h.

538  {
539  return StrictModeState::encode(flag) |
541  }
static U encode(T value)
Definition: utils.h:217
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long mode(MIPS only)") DEFINE_BOOL(enable_always_align_csp
kFeedbackVectorOffset flag
Definition: objects-inl.h:5418

References v8::internal::flag, and mode().

Referenced by v8::internal::PropertyICCompiler::ComputeKeyedStoreMonomorphic(), and v8::internal::PropertyICCompiler::ComputeKeyedStorePolymorphic().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ComputeTransitionedMap()

Handle< Map > v8::internal::KeyedStoreIC::ComputeTransitionedMap ( Handle< Map map,
KeyedAccessStoreMode  store_mode 
)
private

Definition at line 1666 of file ic.cc.

1667  {
1668  switch (store_mode) {
1686  DCHECK(map->has_external_array_elements());
1687  // Fall through
1689  case STANDARD_STORE:
1691  return map;
1692  }
1693  UNREACHABLE();
1694  return MaybeHandle<Map>().ToHandleChecked();
1695 }
static Handle< Map > TransitionElementsTo(Handle< Map > map, ElementsKind to_kind)
Definition: objects.cc:3321
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf map
#define UNREACHABLE()
Definition: logging.h:30
@ STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT
Definition: objects.h:167
@ STORE_TRANSITION_HOLEY_SMI_TO_OBJECT
Definition: objects.h:158
@ STORE_TRANSITION_DOUBLE_TO_OBJECT
Definition: objects.h:157
@ STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE
Definition: objects.h:166
@ STORE_AND_GROW_NO_TRANSITION
Definition: objects.h:161
@ STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE
Definition: objects.h:163
@ STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT
Definition: objects.h:164
@ STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS
Definition: objects.h:168
@ STORE_NO_TRANSITION_HANDLE_COW
Definition: objects.h:169
@ STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE
Definition: objects.h:159
@ STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT
Definition: objects.h:160
@ STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT
Definition: objects.h:162
@ STORE_TRANSITION_SMI_TO_DOUBLE
Definition: objects.h:156
@ STORE_TRANSITION_SMI_TO_OBJECT
Definition: objects.h:155
@ STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT
Definition: objects.h:165
@ STANDARD_STORE
Definition: objects.h:154
@ FAST_HOLEY_DOUBLE_ELEMENTS
Definition: elements-kind.h:27

References DCHECK, v8::internal::FAST_DOUBLE_ELEMENTS, v8::internal::FAST_ELEMENTS, v8::internal::FAST_HOLEY_DOUBLE_ELEMENTS, v8::internal::FAST_HOLEY_ELEMENTS, map, v8::internal::STANDARD_STORE, v8::internal::STORE_AND_GROW_NO_TRANSITION, v8::internal::STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT, v8::internal::STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT, v8::internal::STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE, v8::internal::STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT, v8::internal::STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE, v8::internal::STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT, v8::internal::STORE_NO_TRANSITION_HANDLE_COW, v8::internal::STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS, v8::internal::STORE_TRANSITION_DOUBLE_TO_OBJECT, v8::internal::STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT, v8::internal::STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE, v8::internal::STORE_TRANSITION_HOLEY_SMI_TO_OBJECT, v8::internal::STORE_TRANSITION_SMI_TO_DOUBLE, v8::internal::STORE_TRANSITION_SMI_TO_OBJECT, v8::internal::Map::TransitionElementsTo(), and UNREACHABLE.

Referenced by StoreElementStub().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GenerateGeneric()

static void v8::internal::KeyedStoreIC::GenerateGeneric ( MacroAssembler masm,
StrictMode  strict_mode 
)
static

Referenced by v8::internal::Generate_KeyedStoreIC_Generic(), and v8::internal::Generate_KeyedStoreIC_Generic_Strict().

+ Here is the caller graph for this function:

◆ GenerateInitialize()

static void v8::internal::KeyedStoreIC::GenerateInitialize ( MacroAssembler masm)
inlinestatic

Definition at line 557 of file ic.h.

557 { GenerateMiss(masm); }
static void GenerateMiss(MacroAssembler *masm)

References v8::internal::LoadIC::GenerateMiss().

Referenced by v8::internal::Generate_KeyedStoreIC_Initialize(), and v8::internal::Generate_KeyedStoreIC_Initialize_Strict().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GenerateMiss()

static void v8::internal::KeyedStoreIC::GenerateMiss ( MacroAssembler masm)
static

Referenced by v8::internal::Generate_KeyedStoreIC_Miss().

+ Here is the caller graph for this function:

◆ GeneratePreMonomorphic()

static void v8::internal::KeyedStoreIC::GeneratePreMonomorphic ( MacroAssembler masm)
inlinestatic

Definition at line 558 of file ic.h.

558  {
559  GenerateMiss(masm);
560  }

References v8::internal::LoadIC::GenerateMiss().

Referenced by v8::internal::Generate_KeyedStoreIC_PreMonomorphic(), and v8::internal::Generate_KeyedStoreIC_PreMonomorphic_Strict().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GenerateSloppyArguments()

static void v8::internal::KeyedStoreIC::GenerateSloppyArguments ( MacroAssembler masm)
static

Referenced by v8::internal::Generate_KeyedStoreIC_SloppyArguments().

+ Here is the caller graph for this function:

◆ GenerateSlow()

static void v8::internal::KeyedStoreIC::GenerateSlow ( MacroAssembler masm)
static

◆ GetKeyedAccessStoreMode()

static KeyedAccessStoreMode v8::internal::KeyedStoreIC::GetKeyedAccessStoreMode ( ExtraICState  extra_state)
inlinestatic

Definition at line 543 of file ic.h.

544  {
545  return ExtraICStateKeyedAccessStoreMode::decode(extra_state);
546  }
static T decode(U value)
Definition: utils.h:228

Referenced by v8::internal::PropertyICCompiler::ComputeKeyedStoreMonomorphic(), v8::internal::PropertyICCompiler::ComputeMonomorphic(), v8::internal::TypeFeedbackOracle::GetStoreMode(), StoreElementStub(), and v8::internal::IC::TraceIC().

+ Here is the caller graph for this function:

◆ GetStoreMode()

KeyedAccessStoreMode v8::internal::KeyedStoreIC::GetStoreMode ( Handle< JSObject receiver,
Handle< Object key,
Handle< Object value 
)
private

Definition at line 1707 of file ic.cc.

1709  {
1710  Handle<Smi> smi_key = Object::ToSmi(isolate(), key).ToHandleChecked();
1711  int index = smi_key->value();
1712  bool oob_access = IsOutOfBoundsAccess(receiver, index);
1713  // Don't consider this a growing store if the store would send the receiver to
1714  // dictionary mode.
1715  bool allow_growth = receiver->IsJSArray() && oob_access &&
1716  !receiver->WouldConvertToSlowElements(key);
1717  if (allow_growth) {
1718  // Handle growing array in stub if necessary.
1719  if (receiver->HasFastSmiElements()) {
1720  if (value->IsHeapNumber()) {
1721  if (receiver->HasFastHoleyElements()) {
1723  } else {
1725  }
1726  }
1727  if (value->IsHeapObject()) {
1728  if (receiver->HasFastHoleyElements()) {
1730  } else {
1732  }
1733  }
1734  } else if (receiver->HasFastDoubleElements()) {
1735  if (!value->IsSmi() && !value->IsHeapNumber()) {
1736  if (receiver->HasFastHoleyElements()) {
1738  } else {
1740  }
1741  }
1742  }
1744  } else {
1745  // Handle only in-bounds elements accesses.
1746  if (receiver->HasFastSmiElements()) {
1747  if (value->IsHeapNumber()) {
1748  if (receiver->HasFastHoleyElements()) {
1750  } else {
1752  }
1753  } else if (value->IsHeapObject()) {
1754  if (receiver->HasFastHoleyElements()) {
1756  } else {
1758  }
1759  }
1760  } else if (receiver->HasFastDoubleElements()) {
1761  if (!value->IsSmi() && !value->IsHeapNumber()) {
1762  if (receiver->HasFastHoleyElements()) {
1764  } else {
1766  }
1767  }
1768  }
1769  if (!FLAG_trace_external_array_abuse &&
1770  receiver->map()->has_external_array_elements() && oob_access) {
1772  }
1773  Heap* heap = receiver->GetHeap();
1774  if (receiver->elements()->map() == heap->fixed_cow_array_map()) {
1776  } else {
1777  return STANDARD_STORE;
1778  }
1779  }
1780 }
static MUST_USE_RESULT MaybeHandle< Smi > ToSmi(Isolate *isolate, Handle< Object > object)
Definition: objects-inl.h:1081
bool IsOutOfBoundsAccess(Handle< JSObject > receiver, int index)
Definition: ic.cc:1698

References v8::internal::IC::isolate(), v8::internal::IsOutOfBoundsAccess(), v8::internal::STANDARD_STORE, v8::internal::STORE_AND_GROW_NO_TRANSITION, v8::internal::STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT, v8::internal::STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT, v8::internal::STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE, v8::internal::STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT, v8::internal::STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE, v8::internal::STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT, v8::internal::STORE_NO_TRANSITION_HANDLE_COW, v8::internal::STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS, v8::internal::STORE_TRANSITION_DOUBLE_TO_OBJECT, v8::internal::STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT, v8::internal::STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE, v8::internal::STORE_TRANSITION_HOLEY_SMI_TO_OBJECT, v8::internal::STORE_TRANSITION_SMI_TO_DOUBLE, v8::internal::STORE_TRANSITION_SMI_TO_OBJECT, and v8::internal::Object::ToSmi().

Referenced by Store().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pre_monomorphic_stub() [1/2]

virtual Handle<Code> v8::internal::KeyedStoreIC::pre_monomorphic_stub ( ) const
inlineprotectedvirtual

Reimplemented from v8::internal::StoreIC.

Definition at line 567 of file ic.h.

567  {
569  }
StrictMode strict_mode() const
Definition: ic.h:465

References v8::internal::IC::isolate(), and v8::internal::LoadIC::pre_monomorphic_stub().

Referenced by Clear().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pre_monomorphic_stub() [2/2]

static Handle<Code> v8::internal::KeyedStoreIC::pre_monomorphic_stub ( Isolate isolate,
StrictMode  strict_mode 
)
inlinestaticprotected

Definition at line 570 of file ic.h.

571  {
572  if (strict_mode == STRICT) {
573  return isolate->builtins()->KeyedStoreIC_PreMonomorphic_Strict();
574  } else {
575  return isolate->builtins()->KeyedStoreIC_PreMonomorphic();
576  }
577  }
Builtins * builtins()
Definition: isolate.h:947

References v8::internal::Isolate::builtins(), v8::internal::IC::isolate(), and v8::internal::STRICT.

+ Here is the call graph for this function:

◆ set_target()

void v8::internal::KeyedStoreIC::set_target ( Code code)
inlineprivate

Definition at line 147 of file ic-inl.h.

147  {
148  // Strict mode must be preserved across IC patching.
149  DCHECK(GetStrictMode(code->extra_ic_state()) == strict_mode());
150  IC::set_target(code);
151 }
void set_target(Code *code)
Definition: ic-inl.h:121

References DCHECK, v8::internal::Code::extra_ic_state(), v8::internal::StoreIC::GetStrictMode(), v8::internal::IC::set_target(), and v8::internal::StoreIC::strict_mode().

Referenced by Store().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sloppy_arguments_stub()

Handle<Code> v8::internal::KeyedStoreIC::sloppy_arguments_stub ( )
inlineprivate

Definition at line 586 of file ic.h.

586  {
587  return isolate()->builtins()->KeyedStoreIC_SloppyArguments();
588  }

References v8::internal::Isolate::builtins(), and v8::internal::IC::isolate().

Referenced by Store().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Store()

MaybeHandle< Object > v8::internal::KeyedStoreIC::Store ( Handle< Object object,
Handle< Object name,
Handle< Object value 
)

Definition at line 1783 of file ic.cc.

1785  {
1786  // TODO(verwaest): Let SetProperty do the migration, since storing a property
1787  // might deprecate the current map again, if value does not fit.
1788  if (MigrateDeprecated(object)) {
1789  Handle<Object> result;
1791  isolate(), result, Runtime::SetObjectProperty(isolate(), object, key,
1792  value, strict_mode()),
1793  Object);
1794  return result;
1795  }
1796 
1797  // Check for non-string values that can be converted into an
1798  // internalized string directly or is representable as a smi.
1799  key = TryConvertKey(key, isolate());
1800 
1801  Handle<Object> store_handle;
1802  Handle<Code> stub = generic_stub();
1803 
1804  if (key->IsInternalizedString()) {
1806  isolate(), store_handle,
1807  StoreIC::Store(object, Handle<String>::cast(key), value,
1809  Object);
1810  // TODO(jkummerow): Ideally we'd wrap this in "if (!is_target_set())",
1811  // but doing so causes Hydrogen crashes. Needs investigation.
1812  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
1813  "unhandled internalized string key");
1814  TRACE_IC("StoreIC", key);
1815  set_target(*stub);
1816  return store_handle;
1817  }
1818 
1819  bool use_ic =
1820  FLAG_use_ic && !object->IsStringWrapper() &&
1821  !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() &&
1822  !(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed());
1823  if (use_ic && !object->IsSmi()) {
1824  // Don't use ICs for maps of the objects in Array's prototype chain. We
1825  // expect to be able to trap element sets to objects with those maps in
1826  // the runtime to enable optimization of element hole access.
1827  Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
1828  if (heap_object->map()->IsMapInArrayPrototypeChain()) {
1829  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "map in array prototype");
1830  use_ic = false;
1831  }
1832  }
1833 
1834  if (use_ic) {
1835  DCHECK(!object->IsAccessCheckNeeded());
1836 
1837  if (object->IsJSObject()) {
1838  Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1839  bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null();
1840  if (receiver->elements()->map() ==
1841  isolate()->heap()->sloppy_arguments_elements_map()) {
1842  if (strict_mode() == SLOPPY) {
1843  stub = sloppy_arguments_stub();
1844  } else {
1845  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver");
1846  }
1847  } else if (key_is_smi_like &&
1848  !(target().is_identical_to(sloppy_arguments_stub()))) {
1849  // We should go generic if receiver isn't a dictionary, but our
1850  // prototype chain does have dictionary elements. This ensures that
1851  // other non-dictionary receivers in the polymorphic case benefit
1852  // from fast path keyed stores.
1853  if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
1854  KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
1855  stub = StoreElementStub(receiver, store_mode);
1856  } else {
1857  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype");
1858  }
1859  } else {
1860  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key");
1861  }
1862  } else {
1863  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver");
1864  }
1865  }
1866 
1867  if (store_handle.is_null()) {
1869  isolate(), store_handle,
1870  Runtime::SetObjectProperty(isolate(), object, key, value,
1871  strict_mode()),
1872  Object);
1873  }
1874 
1875  DCHECK(!is_target_set());
1876  Code* generic = *generic_stub();
1877  if (*stub == generic) {
1878  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
1879  }
1880  if (*stub == *slow_stub()) {
1881  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub");
1882  }
1883  DCHECK(!stub.is_null());
1884  set_target(*stub);
1885  TRACE_IC("StoreIC", key);
1886 
1887  return store_handle;
1888 }
static Handle< T > cast(Handle< S > that)
Definition: handles.h:116
bool is_target_set()
Definition: ic.h:147
void set_target(Code *code)
Definition: ic-inl.h:147
Handle< Code > sloppy_arguments_stub()
Definition: ic.h:586
KeyedAccessStoreMode GetStoreMode(Handle< JSObject > receiver, Handle< Object > key, Handle< Object > value)
Definition: ic.cc:1707
Handle< Code > StoreElementStub(Handle< JSObject > receiver, KeyedAccessStoreMode store_mode)
Definition: ic.cc:1547
static MUST_USE_RESULT MaybeHandle< Object > SetObjectProperty(Isolate *isolate, Handle< Object > object, Handle< Object > key, Handle< Object > value, StrictMode strict_mode)
Definition: runtime.cc:2181
Handle< Code > generic_stub() const
Definition: ic.cc:1370
Handle< Code > slow_stub() const
Definition: ic.cc:1385
MUST_USE_RESULT MaybeHandle< Object > Store(Handle< Object > object, Handle< Name > name, Handle< Object > value, JSReceiver::StoreFromKeyed store_mode=JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED)
Definition: ic.cc:1280
#define TRACE_GENERIC_IC(isolate, type, reason)
Definition: ic.cc:79
#define TRACE_IC(type, name)
Definition: ic.cc:137
#define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call, T)
Definition: isolate.h:135
KeyedAccessStoreMode
Definition: objects.h:153
kSerializedDataOffset Object
Definition: objects-inl.h:5322
static bool MigrateDeprecated(Handle< Object > object)
Definition: ic.cc:577
static Handle< Object > TryConvertKey(Handle< Object > key, Isolate *isolate)
Definition: ic.cc:1104

References ASSIGN_RETURN_ON_EXCEPTION, v8::internal::Handle< T >::cast(), DCHECK, v8::internal::StoreIC::generic_stub(), GetStoreMode(), v8::internal::Handle< T >::is_null(), v8::internal::IC::is_target_set(), v8::internal::IC::isolate(), v8::internal::Object::MAY_BE_STORE_FROM_KEYED, v8::internal::MigrateDeprecated(), set_target(), v8::internal::Runtime::SetObjectProperty(), v8::internal::SLOPPY, sloppy_arguments_stub(), v8::internal::StoreIC::slow_stub(), v8::internal::StoreIC::Store(), StoreElementStub(), v8::internal::StoreIC::strict_mode(), v8::internal::IC::target(), v8::internal::Object::ToSmi(), TRACE_GENERIC_IC, TRACE_IC, and v8::internal::TryConvertKey().

Referenced by v8::internal::RUNTIME_FUNCTION().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ StoreElementStub()

Handle< Code > v8::internal::KeyedStoreIC::StoreElementStub ( Handle< JSObject receiver,
KeyedAccessStoreMode  store_mode 
)
protected

Definition at line 1547 of file ic.cc.

1548  {
1549  // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1550  // via megamorphic stubs, since they don't have a map in their relocation info
1551  // and so the stubs can't be harvested for the object needed for a map check.
1552  if (target()->type() != Code::NORMAL) {
1553  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type");
1554  return generic_stub();
1555  }
1556 
1557  Handle<Map> receiver_map(receiver->map(), isolate());
1558  MapHandleList target_receiver_maps;
1559  TargetMaps(&target_receiver_maps);
1560  if (target_receiver_maps.length() == 0) {
1561  Handle<Map> monomorphic_map =
1562  ComputeTransitionedMap(receiver_map, store_mode);
1563  store_mode = GetNonTransitioningStoreMode(store_mode);
1565  monomorphic_map, strict_mode(), store_mode);
1566  }
1567 
1568  // There are several special cases where an IC that is MONOMORPHIC can still
1569  // transition to a different GetNonTransitioningStoreMode IC that handles a
1570  // superset of the original IC. Handle those here if the receiver map hasn't
1571  // changed or it has transitioned to a more general kind.
1572  KeyedAccessStoreMode old_store_mode =
1574  Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1575  if (state() == MONOMORPHIC) {
1576  Handle<Map> transitioned_receiver_map = receiver_map;
1577  if (IsTransitionStoreMode(store_mode)) {
1578  transitioned_receiver_map =
1579  ComputeTransitionedMap(receiver_map, store_mode);
1580  }
1581  if ((receiver_map.is_identical_to(previous_receiver_map) &&
1582  IsTransitionStoreMode(store_mode)) ||
1583  IsTransitionOfMonomorphicTarget(*previous_receiver_map,
1584  *transitioned_receiver_map)) {
1585  // If the "old" and "new" maps are in the same elements map family, or
1586  // if they at least come from the same origin for a transitioning store,
1587  // stay MONOMORPHIC and use the map for the most generic ElementsKind.
1588  store_mode = GetNonTransitioningStoreMode(store_mode);
1590  transitioned_receiver_map, strict_mode(), store_mode);
1591  } else if (*previous_receiver_map == receiver->map() &&
1592  old_store_mode == STANDARD_STORE &&
1593  (store_mode == STORE_AND_GROW_NO_TRANSITION ||
1595  store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
1596  // A "normal" IC that handles stores can switch to a version that can
1597  // grow at the end of the array, handle OOB accesses or copy COW arrays
1598  // and still stay MONOMORPHIC.
1600  receiver_map, strict_mode(), store_mode);
1601  }
1602  }
1603 
1604  DCHECK(state() != GENERIC);
1605 
1606  bool map_added =
1607  AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1608 
1609  if (IsTransitionStoreMode(store_mode)) {
1610  Handle<Map> transitioned_receiver_map =
1611  ComputeTransitionedMap(receiver_map, store_mode);
1612  map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
1613  transitioned_receiver_map);
1614  }
1615 
1616  if (!map_added) {
1617  // If the miss wasn't due to an unseen map, a polymorphic stub
1618  // won't help, use the generic stub.
1619  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "same map added twice");
1620  return generic_stub();
1621  }
1622 
1623  // If the maximum number of receiver maps has been exceeded, use the generic
1624  // version of the IC.
1625  if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1626  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "max polymorph exceeded");
1627  return generic_stub();
1628  }
1629 
1630  // Make sure all polymorphic handlers have the same store mode, otherwise the
1631  // generic stub must be used.
1632  store_mode = GetNonTransitioningStoreMode(store_mode);
1633  if (old_store_mode != STANDARD_STORE) {
1634  if (store_mode == STANDARD_STORE) {
1635  store_mode = old_store_mode;
1636  } else if (store_mode != old_store_mode) {
1637  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "store mode mismatch");
1638  return generic_stub();
1639  }
1640  }
1641 
1642  // If the store mode isn't the standard mode, make sure that all polymorphic
1643  // receivers are either external arrays, or all "normal" arrays. Otherwise,
1644  // use the generic stub.
1645  if (store_mode != STANDARD_STORE) {
1646  int external_arrays = 0;
1647  for (int i = 0; i < target_receiver_maps.length(); ++i) {
1648  if (target_receiver_maps[i]->has_external_array_elements() ||
1649  target_receiver_maps[i]->has_fixed_typed_array_elements()) {
1650  external_arrays++;
1651  }
1652  }
1653  if (external_arrays != 0 &&
1654  external_arrays != target_receiver_maps.length()) {
1655  TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
1656  "unsupported combination of external and normal arrays");
1657  return generic_stub();
1658  }
1659  }
1660 
1662  &target_receiver_maps, store_mode, strict_mode());
1663 }
State state() const
Definition: ic.h:66
bool IsTransitionOfMonomorphicTarget(Map *source_map, Map *target_map)
Definition: ic.cc:772
void TargetMaps(MapHandleList *list)
Definition: ic.h:208
ExtraICState extra_ic_state() const
Definition: ic.h:200
static KeyedAccessStoreMode GetKeyedAccessStoreMode(ExtraICState extra_state)
Definition: ic.h:543
Handle< Map > ComputeTransitionedMap(Handle< Map > map, KeyedAccessStoreMode store_mode)
Definition: ic.cc:1666
static Handle< Code > ComputeKeyedStorePolymorphic(MapHandleList *receiver_maps, KeyedAccessStoreMode store_mode, StrictMode strict_mode)
Definition: ic-compiler.cc:283
static Handle< Code > ComputeKeyedStoreMonomorphic(Handle< Map > receiver_map, StrictMode strict_mode, KeyedAccessStoreMode store_mode)
Definition: ic-compiler.cc:120
static KeyedAccessStoreMode GetNonTransitioningStoreMode(KeyedAccessStoreMode store_mode)
Definition: objects.h:216
static bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode)
Definition: objects.h:209
static bool AddOneReceiverMapIfMissing(MapHandleList *receiver_maps, Handle< Map > new_receiver_map)
Definition: ic.cc:635
const int kMaxKeyedPolymorphism
Definition: ic-state.h:14
List< Handle< Map > > MapHandleList
Definition: list.h:197

References v8::internal::AddOneReceiverMapIfMissing(), v8::internal::List< T, AllocationPolicy >::at(), v8::internal::PropertyICCompiler::ComputeKeyedStoreMonomorphic(), v8::internal::PropertyICCompiler::ComputeKeyedStorePolymorphic(), ComputeTransitionedMap(), DCHECK, v8::internal::IC::extra_ic_state(), v8::internal::GENERIC, v8::internal::StoreIC::generic_stub(), GetKeyedAccessStoreMode(), v8::internal::GetNonTransitioningStoreMode(), v8::internal::IC::isolate(), v8::internal::IC::IsTransitionOfMonomorphicTarget(), v8::internal::IsTransitionStoreMode(), v8::internal::kMaxKeyedPolymorphism, v8::internal::MONOMORPHIC, v8::internal::Code::NORMAL, v8::internal::STANDARD_STORE, v8::internal::IC::state(), v8::internal::STORE_AND_GROW_NO_TRANSITION, v8::internal::STORE_NO_TRANSITION_HANDLE_COW, v8::internal::STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS, v8::internal::StoreIC::strict_mode(), v8::internal::IC::target(), v8::internal::IC::TargetMaps(), and TRACE_GENERIC_IC.

Referenced by Store().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Friends And Related Function Documentation

◆ IC

friend class IC
friend

Definition at line 599 of file ic.h.


The documentation for this class was generated from the following files: