#include "src/ic/ic.h"
#include <optional>
#include <tuple>
#include "src/api/api-arguments-inl.h"
#include "src/ast/ast.h"
#include "src/base/logging.h"
#include "src/builtins/accessors.h"
#include "src/common/assert-scope.h"
#include "src/common/globals.h"
#include "src/execution/arguments-inl.h"
#include "src/execution/execution.h"
#include "src/execution/frames-inl.h"
#include "src/execution/isolate-inl.h"
#include "src/execution/isolate.h"
#include "src/execution/protectors-inl.h"
#include "src/execution/tiering-manager.h"
#include "src/handles/handles-inl.h"
#include "src/handles/maybe-handles.h"
#include "src/ic/call-optimization.h"
#include "src/ic/handler-configuration-inl.h"
#include "src/ic/handler-configuration.h"
#include "src/ic/ic-inl.h"
#include "src/ic/ic-stats.h"
#include "src/ic/stub-cache.h"
#include "src/numbers/conversions.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/field-type.h"
#include "src/objects/instance-type.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/megadom-handler.h"
#include "src/objects/property-descriptor.h"
#include "src/objects/prototype.h"
#include "src/runtime/runtime.h"
#include "src/tracing/trace-event.h"
#include "src/tracing/tracing-category-observer.h"
#include "src/utils/ostreams.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/struct-types.h"
#endif
namespace v8 {
namespace internal {
constexpr InlineCacheState NO_FEEDBACK = …;
constexpr InlineCacheState UNINITIALIZED = …;
constexpr InlineCacheState MONOMORPHIC = …;
constexpr InlineCacheState RECOMPUTE_HANDLER = …;
constexpr InlineCacheState POLYMORPHIC = …;
constexpr InlineCacheState MEGAMORPHIC = …;
constexpr InlineCacheState MEGADOM = …;
constexpr InlineCacheState GENERIC = …;
char IC::TransitionMarkFromState(IC::State state) { … }
namespace {
const char* GetModifier(KeyedAccessLoadMode mode) { … }
const char* GetModifier(KeyedAccessStoreMode mode) { … }
}
void IC::TraceIC(const char* type, DirectHandle<Object> name) { … }
void IC::TraceIC(const char* type, DirectHandle<Object> name, State old_state,
State new_state) { … }
IC::IC(Isolate* isolate, Handle<FeedbackVector> vector, FeedbackSlot slot,
FeedbackSlotKind kind)
: … { … }
static void LookupForRead(LookupIterator* it, bool is_has_property) { … }
bool IC::ShouldRecomputeHandler(DirectHandle<String> name) { … }
bool IC::RecomputeHandlerForName(DirectHandle<Object> name) { … }
void IC::UpdateState(DirectHandle<Object> lookup_start_object,
Handle<Object> name) { … }
MaybeHandle<Object> IC::TypeError(MessageTemplate index, Handle<Object> object,
Handle<Object> key) { … }
MaybeHandle<Object> IC::ReferenceError(Handle<Name> name) { … }
void IC::OnFeedbackChanged(const char* reason) { … }
void IC::OnFeedbackChanged(Isolate* isolate, Tagged<FeedbackVector> vector,
FeedbackSlot slot, const char* reason) { … }
namespace {
bool MigrateDeprecated(Isolate* isolate, Handle<Object> object) { … }
}
bool IC::ConfigureVectorState(IC::State new_state, DirectHandle<Object> key) { … }
void IC::ConfigureVectorState(Handle<Name> name, DirectHandle<Map> map,
Handle<Object> handler) { … }
void IC::ConfigureVectorState(Handle<Name> name, DirectHandle<Map> map,
const MaybeObjectHandle& handler) { … }
void IC::ConfigureVectorState(Handle<Name> name, MapHandlesSpan maps,
MaybeObjectHandles* handlers) { … }
void IC::ConfigureVectorState(
Handle<Name> name, std::vector<MapAndHandler> const& maps_and_handlers) { … }
MaybeHandle<Object> LoadIC::Load(Handle<Object> object, Handle<Name> name,
bool update_feedback,
Handle<Object> receiver) { … }
MaybeHandle<Object> LoadGlobalIC::Load(Handle<Name> name,
bool update_feedback) { … }
namespace {
bool AddOneReceiverMapIfMissing(MapHandles* receiver_maps,
Handle<Map> new_receiver_map) { … }
bool AddOneReceiverMapIfMissing(
std::vector<MapAndHandler>* receiver_maps_and_handlers,
Handle<Map> new_receiver_map) { … }
Handle<NativeContext> GetAccessorContext(
const CallOptimization& call_optimization, Tagged<Map> holder_map,
Isolate* isolate) { … }
}
bool IC::UpdateMegaDOMIC(const MaybeObjectHandle& handler,
DirectHandle<Name> name) { … }
bool IC::UpdatePolymorphicIC(Handle<Name> name,
const MaybeObjectHandle& handler) { … }
void IC::UpdateMonomorphicIC(const MaybeObjectHandle& handler,
Handle<Name> name) { … }
void IC::CopyICToMegamorphicCache(DirectHandle<Name> name) { … }
bool IC::IsTransitionOfMonomorphicTarget(Tagged<Map> source_map,
Tagged<Map> target_map) { … }
void IC::SetCache(Handle<Name> name, Handle<Object> handler) { … }
void IC::SetCache(Handle<Name> name, const MaybeObjectHandle& handler) { … }
void LoadIC::UpdateCaches(LookupIterator* lookup) { … }
StubCache* IC::stub_cache() { … }
void IC::UpdateMegamorphicCache(DirectHandle<Map> map, DirectHandle<Name> name,
const MaybeObjectHandle& handler) { … }
MaybeObjectHandle LoadIC::ComputeHandler(LookupIterator* lookup) { … }
KeyedAccessLoadMode KeyedLoadIC::GetKeyedAccessLoadModeFor(
DirectHandle<Map> receiver_map) const { … }
bool AllowedHandlerChange(KeyedAccessLoadMode old_mode,
KeyedAccessLoadMode new_mode) { … }
void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver,
const KeyedAccessLoadMode new_load_mode) { … }
namespace {
bool AllowConvertHoleElementToUndefined(Isolate* isolate,
DirectHandle<Map> receiver_map) { … }
bool IsOutOfBoundsAccess(DirectHandle<Object> receiver, size_t index) { … }
bool AllowReadingHoleElement(ElementsKind elements_kind) { … }
KeyedAccessLoadMode GetNewKeyedLoadMode(Isolate* isolate,
Handle<HeapObject> receiver,
size_t index, bool is_found) { … }
KeyedAccessLoadMode GetUpdatedLoadModeForMap(Isolate* isolate,
DirectHandle<Map> map,
KeyedAccessLoadMode load_mode) { … }
}
Handle<Object> KeyedLoadIC::LoadElementHandler(
DirectHandle<Map> receiver_map, KeyedAccessLoadMode new_load_mode) { … }
void KeyedLoadIC::LoadElementPolymorphicHandlers(
MapHandles* receiver_maps, MaybeObjectHandles* handlers,
KeyedAccessLoadMode new_load_mode) { … }
namespace {
enum KeyType { … };
KeyType TryConvertKey(Handle<Object> key, Isolate* isolate, intptr_t* index_out,
Handle<Name>* name_out) { … }
bool IntPtrKeyToSize(intptr_t index, DirectHandle<HeapObject> receiver,
size_t* out) { … }
bool CanCache(DirectHandle<Object> receiver, InlineCacheState state) { … }
}
MaybeHandle<Object> KeyedLoadIC::RuntimeLoad(Handle<Object> object,
Handle<Object> key,
bool* is_found) { … }
MaybeHandle<Object> KeyedLoadIC::LoadName(Handle<Object> object,
DirectHandle<Object> key,
Handle<Name> name) { … }
MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
Handle<Object> key) { … }
bool StoreIC::LookupForWrite(LookupIterator* it, DirectHandle<Object> value,
StoreOrigin store_origin) { … }
MaybeHandle<Object> StoreGlobalIC::Store(Handle<Name> name,
Handle<Object> value) { … }
namespace {
Maybe<bool> DefineOwnDataProperty(LookupIterator* it,
LookupIterator::State original_state,
Handle<JSAny> value,
Maybe<ShouldThrow> should_throw,
StoreOrigin store_origin) { … }
}
MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
Handle<Object> value,
StoreOrigin store_origin) { … }
void StoreIC::UpdateCaches(LookupIterator* lookup, DirectHandle<Object> value,
StoreOrigin store_origin) { … }
MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { … }
void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
KeyedAccessStoreMode store_mode,
Handle<Map> new_receiver_map) { … }
Handle<Object> KeyedStoreIC::StoreElementHandler(
DirectHandle<Map> receiver_map, KeyedAccessStoreMode store_mode,
MaybeHandle<UnionOf<Smi, Cell>> prev_validity_cell) { … }
void KeyedStoreIC::StoreElementPolymorphicHandlers(
std::vector<MapAndHandler>* receiver_maps_and_handlers,
KeyedAccessStoreMode store_mode) { … }
namespace {
bool MayHaveTypedArrayInPrototypeChain(DirectHandle<JSObject> object) { … }
KeyedAccessStoreMode GetStoreMode(DirectHandle<JSObject> receiver,
size_t index) { … }
}
MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
Handle<Object> key,
Handle<Object> value) { … }
namespace {
Maybe<bool> StoreOwnElement(Isolate* isolate, Handle<JSArray> array,
Handle<Object> index, Handle<Object> value) { … }
}
MaybeHandle<Object> StoreInArrayLiteralIC::Store(Handle<JSArray> array,
Handle<Object> index,
Handle<Object> value) { … }
RUNTIME_FUNCTION(Runtime_LoadIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_LoadNoFeedbackIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_LoadWithReceiverNoFeedbackIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_LoadGlobalIC_Slow) { … }
RUNTIME_FUNCTION(Runtime_LoadWithReceiverIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_KeyedLoadIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_StoreIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_DefineNamedOwnIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_DefineNamedOwnIC_Slow) { … }
RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_StoreGlobalICNoFeedback_Miss) { … }
RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Slow) { … }
RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_DefineKeyedOwnIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { … }
RUNTIME_FUNCTION(Runtime_DefineKeyedOwnIC_Slow) { … }
RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Slow) { … }
RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { … }
namespace {
enum class FastCloneObjectMode { … };
FastCloneObjectMode GetCloneModeForMapPreCheck(DirectHandle<Map> map,
bool null_proto_literal,
Isolate* isolate) { … }
FastCloneObjectMode GetCloneModeForMap(DirectHandle<Map> map,
bool null_proto_literal,
Isolate* isolate) { … }
bool CanCacheCloneTargetMapTransition(
DirectHandle<Map> source_map, std::optional<DirectHandle<Map>> target_map,
bool null_proto_literal, Isolate* isolate) { … }
bool CanFastCloneObjectToObjectLiteral(DirectHandle<Map> source_map,
DirectHandle<Map> target_map,
DirectHandle<Map> override_map,
bool null_proto_literal,
Isolate* isolate) { … }
}
static MaybeHandle<JSObject> CloneObjectSlowPath(Isolate* isolate,
Handle<Object> source,
int flags) { … }
RUNTIME_FUNCTION(Runtime_CloneObjectIC_Slow) { … }
namespace {
template <SideStepTransition::Kind kind>
Tagged<Object> GetCloneTargetMap(Isolate* isolate, DirectHandle<Map> source_map,
DirectHandle<Map> override_map) { … }
template <SideStepTransition::Kind kind>
void SetCloneTargetMap(Isolate* isolate, Handle<Map> source_map,
DirectHandle<Map> new_target_map,
DirectHandle<Map> override_map) { … }
template <SideStepTransition::Kind kind>
void SetCloneTargetMapUnsupported(Isolate* isolate, Handle<Map> source_map,
DirectHandle<Map> override_map) { … }
}
RUNTIME_FUNCTION(Runtime_CloneObjectIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_StoreCallbackProperty) { … }
namespace {
bool MaybeCanCloneObjectForObjectAssign(Handle<JSReceiver> source,
DirectHandle<Map> source_map,
Handle<JSReceiver> target,
Isolate* isolate) { … }
}
RUNTIME_FUNCTION(Runtime_ObjectAssignTryFastcase) { … }
RUNTIME_FUNCTION(Runtime_LoadPropertyWithInterceptor) { … }
RUNTIME_FUNCTION(Runtime_StorePropertyWithInterceptor) { … }
RUNTIME_FUNCTION(Runtime_LoadElementWithInterceptor) { … }
RUNTIME_FUNCTION(Runtime_KeyedHasIC_Miss) { … }
RUNTIME_FUNCTION(Runtime_HasElementWithInterceptor) { … }
}
}