[in-place weak refs] Add MaybeObjectHandle.
This gets rid of the weakness hacks which were needed for remembering that maps as handlers are weak, and other handles are strong. BUG=v8:7308 Change-Id: I7fd3252ba67350803e2207dc12bbdf6abbae7e23 Reviewed-on: https://chromium-review.googlesource.com/1055449 Reviewed-by: Igor Sheludko <ishell@chromium.org> Commit-Queue: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/master@{#53151}
This commit is contained in:
parent
8ec92f5118
commit
1684cd8bd5
@ -668,15 +668,11 @@ bool FeedbackNexus::ConfigureLexicalVarMode(int script_context_index,
|
||||
return true;
|
||||
}
|
||||
|
||||
void FeedbackNexus::ConfigureHandlerMode(Handle<Object> handler) {
|
||||
void FeedbackNexus::ConfigureHandlerMode(const MaybeObjectHandle& handler) {
|
||||
DCHECK(IsGlobalICKind(kind()));
|
||||
DCHECK(IC::IsHandler(*handler));
|
||||
SetFeedback(GetIsolate()->heap()->empty_weak_cell());
|
||||
if (handler->IsMap()) {
|
||||
SetFeedbackExtra(HeapObjectReference::Weak(HeapObject::cast(*handler)));
|
||||
} else {
|
||||
SetFeedbackExtra(*handler);
|
||||
}
|
||||
SetFeedbackExtra(*handler);
|
||||
}
|
||||
|
||||
int FeedbackNexus::GetCallCount() {
|
||||
@ -722,7 +718,7 @@ float FeedbackNexus::ComputeCallFrequency() {
|
||||
|
||||
void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
|
||||
Handle<Map> receiver_map,
|
||||
Handle<Object> handler) {
|
||||
const MaybeObjectHandle& handler) {
|
||||
DCHECK(handler.is_null() || IC::IsHandler(*handler));
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
|
||||
if (kind() == FeedbackSlotKind::kStoreDataPropertyInLiteral) {
|
||||
@ -731,27 +727,19 @@ void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
|
||||
} else {
|
||||
if (name.is_null()) {
|
||||
SetFeedback(*cell);
|
||||
if (handler->IsMap()) {
|
||||
SetFeedbackExtra(HeapObjectReference::Weak(*handler));
|
||||
} else {
|
||||
SetFeedbackExtra(*handler);
|
||||
}
|
||||
SetFeedbackExtra(*handler);
|
||||
} else {
|
||||
Handle<WeakFixedArray> array = EnsureExtraArrayOfSize(2);
|
||||
SetFeedback(*name);
|
||||
array->Set(0, HeapObjectReference::Strong(*cell));
|
||||
if (handler->IsMap()) {
|
||||
array->Set(1, HeapObjectReference::Weak(*handler));
|
||||
} else {
|
||||
array->Set(1, MaybeObject::FromObject(*handler));
|
||||
}
|
||||
array->Set(1, *handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
|
||||
MapHandles const& maps,
|
||||
ObjectHandles* handlers) {
|
||||
MaybeObjectHandles* handlers) {
|
||||
DCHECK_EQ(handlers->size(), maps.size());
|
||||
int receiver_count = static_cast<int>(maps.size());
|
||||
DCHECK_GT(receiver_count, 1);
|
||||
@ -770,13 +758,7 @@ void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
|
||||
Handle<WeakCell> cell = Map::WeakCellForMap(map);
|
||||
array->Set(current * 2, HeapObjectReference::Strong(*cell));
|
||||
DCHECK(IC::IsHandler(*handlers->at(current)));
|
||||
if (handlers->at(current)->IsMap()) {
|
||||
array->Set(current * 2 + 1,
|
||||
HeapObjectReference::Weak(*handlers->at(current)));
|
||||
} else {
|
||||
array->Set(current * 2 + 1,
|
||||
MaybeObject::FromObject(*handlers->at(current)));
|
||||
}
|
||||
array->Set(current * 2 + 1, *handlers->at(current));
|
||||
}
|
||||
}
|
||||
|
||||
@ -819,7 +801,7 @@ int FeedbackNexus::ExtractMaps(MapHandles* maps) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
|
||||
MaybeObjectHandle FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
|
||||
DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
|
||||
IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
|
||||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()));
|
||||
@ -841,8 +823,7 @@ MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
|
||||
Map* array_map = Map::cast(cell->value());
|
||||
if (array_map == *map &&
|
||||
!array->Get(i + increment - 1)->IsClearedWeakHeapObject()) {
|
||||
// This converts a weak reference to a strong reference.
|
||||
Object* handler = array->Get(i + increment - 1)->GetHeapObjectOrSmi();
|
||||
MaybeObject* handler = array->Get(i + increment - 1);
|
||||
DCHECK(IC::IsHandler(handler));
|
||||
return handle(handler, isolate);
|
||||
}
|
||||
@ -853,18 +834,18 @@ MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
|
||||
if (!cell->cleared()) {
|
||||
Map* cell_map = Map::cast(cell->value());
|
||||
if (cell_map == *map && !GetFeedbackExtra()->IsClearedWeakHeapObject()) {
|
||||
// This converts a weak reference to a strong reference.
|
||||
Object* handler = GetFeedbackExtra()->GetHeapObjectOrSmi();
|
||||
MaybeObject* handler = GetFeedbackExtra();
|
||||
DCHECK(IC::IsHandler(handler));
|
||||
return handle(handler, isolate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MaybeHandle<Code>();
|
||||
return MaybeObjectHandle();
|
||||
}
|
||||
|
||||
bool FeedbackNexus::FindHandlers(ObjectHandles* code_list, int length) const {
|
||||
bool FeedbackNexus::FindHandlers(MaybeObjectHandles* code_list,
|
||||
int length) const {
|
||||
DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
|
||||
IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
|
||||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
|
||||
@ -887,8 +868,7 @@ bool FeedbackNexus::FindHandlers(ObjectHandles* code_list, int length) const {
|
||||
// Be sure to skip handlers whose maps have been cleared.
|
||||
if (!cell->cleared() &&
|
||||
!array->Get(i + increment - 1)->IsClearedWeakHeapObject()) {
|
||||
// This converts a weak reference to a strong reference.
|
||||
Object* handler = array->Get(i + increment - 1)->GetHeapObjectOrSmi();
|
||||
MaybeObject* handler = array->Get(i + increment - 1);
|
||||
DCHECK(IC::IsHandler(handler));
|
||||
code_list->push_back(handle(handler, isolate));
|
||||
count++;
|
||||
@ -898,10 +878,8 @@ bool FeedbackNexus::FindHandlers(ObjectHandles* code_list, int length) const {
|
||||
WeakCell* cell = WeakCell::cast(feedback);
|
||||
MaybeObject* extra = GetFeedbackExtra();
|
||||
if (!cell->cleared() && !extra->IsClearedWeakHeapObject()) {
|
||||
// This converts a weak reference to a strong reference.
|
||||
Object* handler = extra->GetHeapObjectOrSmi();
|
||||
DCHECK(IC::IsHandler(handler));
|
||||
code_list->push_back(handle(handler, isolate));
|
||||
DCHECK(IC::IsHandler(extra));
|
||||
code_list->push_back(handle(extra, isolate));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@ -921,13 +899,13 @@ Name* FeedbackNexus::FindFirstName() const {
|
||||
KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const {
|
||||
DCHECK(IsKeyedLoadICKind(kind()));
|
||||
MapHandles maps;
|
||||
ObjectHandles handlers;
|
||||
MaybeObjectHandles handlers;
|
||||
|
||||
if (GetKeyType() == PROPERTY) return STANDARD_LOAD;
|
||||
|
||||
ExtractMaps(&maps);
|
||||
FindHandlers(&handlers, static_cast<int>(maps.size()));
|
||||
for (Handle<Object> const& handler : handlers) {
|
||||
for (MaybeObjectHandle const& handler : handlers) {
|
||||
KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler);
|
||||
if (mode != STANDARD_LOAD) return mode;
|
||||
}
|
||||
@ -939,26 +917,27 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
|
||||
DCHECK(IsKeyedStoreICKind(kind()) || IsStoreInArrayLiteralICKind(kind()));
|
||||
KeyedAccessStoreMode mode = STANDARD_STORE;
|
||||
MapHandles maps;
|
||||
ObjectHandles handlers;
|
||||
MaybeObjectHandles handlers;
|
||||
|
||||
if (GetKeyType() == PROPERTY) return mode;
|
||||
|
||||
ExtractMaps(&maps);
|
||||
FindHandlers(&handlers, static_cast<int>(maps.size()));
|
||||
for (const Handle<Object>& maybe_code_handler : handlers) {
|
||||
for (const MaybeObjectHandle& maybe_code_handler : handlers) {
|
||||
// The first handler that isn't the slow handler will have the bits we need.
|
||||
Handle<Code> handler;
|
||||
if (maybe_code_handler->IsStoreHandler()) {
|
||||
if (maybe_code_handler.object()->IsStoreHandler()) {
|
||||
Handle<StoreHandler> data_handler =
|
||||
Handle<StoreHandler>::cast(maybe_code_handler);
|
||||
Handle<StoreHandler>::cast(maybe_code_handler.object());
|
||||
handler = handle(Code::cast(data_handler->smi_handler()));
|
||||
} else if (maybe_code_handler->IsSmi()) {
|
||||
} else if (maybe_code_handler.object()->IsSmi()) {
|
||||
// Skip proxy handlers.
|
||||
DCHECK_EQ(*maybe_code_handler, *StoreHandler::StoreProxy(GetIsolate()));
|
||||
DCHECK_EQ(*(maybe_code_handler.object()),
|
||||
*StoreHandler::StoreProxy(GetIsolate()));
|
||||
continue;
|
||||
} else {
|
||||
// Element store without prototype chain check.
|
||||
handler = Handle<Code>::cast(maybe_code_handler);
|
||||
handler = Handle<Code>::cast(maybe_code_handler.object());
|
||||
if (handler->is_builtin()) continue;
|
||||
}
|
||||
CodeStub::Major major_key = CodeStub::MajorKeyFromKey(handler->stub_key());
|
||||
|
@ -129,7 +129,7 @@ inline LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind) {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, FeedbackSlotKind kind);
|
||||
|
||||
typedef std::vector<Handle<Object>> ObjectHandles;
|
||||
typedef std::vector<MaybeObjectHandle> MaybeObjectHandles;
|
||||
|
||||
class FeedbackMetadata;
|
||||
|
||||
@ -595,8 +595,8 @@ class FeedbackNexus final {
|
||||
|
||||
InlineCacheState StateFromFeedback() const;
|
||||
int ExtractMaps(MapHandles* maps) const;
|
||||
MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const;
|
||||
bool FindHandlers(ObjectHandles* code_list, int length = -1) const;
|
||||
MaybeObjectHandle FindHandlerForMap(Handle<Map> map) const;
|
||||
bool FindHandlers(MaybeObjectHandles* code_list, int length = -1) const;
|
||||
|
||||
bool IsCleared() const {
|
||||
InlineCacheState state = StateFromFeedback();
|
||||
@ -615,10 +615,10 @@ class FeedbackNexus final {
|
||||
inline Isolate* GetIsolate() const;
|
||||
|
||||
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
|
||||
Handle<Object> handler);
|
||||
const MaybeObjectHandle& handler);
|
||||
|
||||
void ConfigurePolymorphic(Handle<Name> name, MapHandles const& maps,
|
||||
ObjectHandles* handlers);
|
||||
MaybeObjectHandles* handlers);
|
||||
|
||||
BinaryOperationHint GetBinaryOperationFeedback() const;
|
||||
CompareOperationHint GetCompareOperationFeedback() const;
|
||||
@ -657,7 +657,7 @@ class FeedbackNexus final {
|
||||
// Returns false if given combination of indices is not allowed.
|
||||
bool ConfigureLexicalVarMode(int script_context_index,
|
||||
int context_slot_index);
|
||||
void ConfigureHandlerMode(Handle<Object> handler);
|
||||
void ConfigureHandlerMode(const MaybeObjectHandle& handler);
|
||||
|
||||
// Bit positions in a smi that encodes lexical environment variable access.
|
||||
#define LEXICAL_MODE_BIT_FIELDS(V, _) \
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "src/isolate.h"
|
||||
#include "src/msan.h"
|
||||
#include "src/objects-inl.h"
|
||||
#include "src/objects/maybe-object-inl.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
@ -44,6 +45,65 @@ inline std::ostream& operator<<(std::ostream& os, Handle<T> handle) {
|
||||
return os << Brief(*handle);
|
||||
}
|
||||
|
||||
MaybeObjectHandle::MaybeObjectHandle()
|
||||
: reference_type_(HeapObjectReferenceType::STRONG),
|
||||
handle_(Handle<Object>::null()) {}
|
||||
|
||||
MaybeObjectHandle::MaybeObjectHandle(MaybeObject* object, Isolate* isolate) {
|
||||
HeapObject* heap_object;
|
||||
DCHECK(!object->IsClearedWeakHeapObject());
|
||||
if (object->ToWeakHeapObject(&heap_object)) {
|
||||
handle_ = handle(heap_object, isolate);
|
||||
reference_type_ = HeapObjectReferenceType::WEAK;
|
||||
} else {
|
||||
handle_ = handle(object->ToObject(), isolate);
|
||||
reference_type_ = HeapObjectReferenceType::STRONG;
|
||||
}
|
||||
}
|
||||
|
||||
MaybeObjectHandle::MaybeObjectHandle(Handle<Object> object)
|
||||
: reference_type_(HeapObjectReferenceType::STRONG), handle_(object) {}
|
||||
|
||||
MaybeObjectHandle::MaybeObjectHandle(Object* object, Isolate* isolate)
|
||||
: reference_type_(HeapObjectReferenceType::STRONG),
|
||||
handle_(object, isolate) {}
|
||||
|
||||
MaybeObjectHandle::MaybeObjectHandle(Object* object,
|
||||
HeapObjectReferenceType reference_type,
|
||||
Isolate* isolate)
|
||||
: reference_type_(reference_type), handle_(handle(object, isolate)) {}
|
||||
|
||||
MaybeObjectHandle::MaybeObjectHandle(Handle<Object> object,
|
||||
HeapObjectReferenceType reference_type)
|
||||
: reference_type_(reference_type), handle_(object) {}
|
||||
|
||||
MaybeObjectHandle MaybeObjectHandle::Weak(Handle<Object> object) {
|
||||
return MaybeObjectHandle(object, HeapObjectReferenceType::WEAK);
|
||||
}
|
||||
|
||||
MaybeObject* MaybeObjectHandle::operator*() const {
|
||||
if (reference_type_ == HeapObjectReferenceType::WEAK) {
|
||||
return HeapObjectReference::Weak(*handle_.ToHandleChecked());
|
||||
} else {
|
||||
return MaybeObject::FromObject(*handle_.ToHandleChecked());
|
||||
}
|
||||
}
|
||||
|
||||
MaybeObject* MaybeObjectHandle::operator->() const {
|
||||
if (reference_type_ == HeapObjectReferenceType::WEAK) {
|
||||
return HeapObjectReference::Weak(*handle_.ToHandleChecked());
|
||||
} else {
|
||||
return MaybeObject::FromObject(*handle_.ToHandleChecked());
|
||||
}
|
||||
}
|
||||
|
||||
Handle<Object> MaybeObjectHandle::object() const {
|
||||
return handle_.ToHandleChecked();
|
||||
}
|
||||
|
||||
inline MaybeObjectHandle handle(MaybeObject* object, Isolate* isolate) {
|
||||
return MaybeObjectHandle(object, isolate);
|
||||
}
|
||||
|
||||
HandleScope::~HandleScope() {
|
||||
#ifdef DEBUG
|
||||
|
@ -235,6 +235,43 @@ class MaybeHandle final {
|
||||
friend class MaybeHandle;
|
||||
};
|
||||
|
||||
// A handle which contains a potentially weak pointer. Keeps it alive (strongly)
|
||||
// while the MaybeObjectHandle is alive.
|
||||
class MaybeObjectHandle {
|
||||
public:
|
||||
inline MaybeObjectHandle();
|
||||
inline MaybeObjectHandle(MaybeObject* object, Isolate* isolate);
|
||||
inline MaybeObjectHandle(Object* object, Isolate* isolate);
|
||||
inline explicit MaybeObjectHandle(Handle<Object> object);
|
||||
|
||||
static inline MaybeObjectHandle Weak(Object* object, Isolate* isolate);
|
||||
static inline MaybeObjectHandle Weak(Handle<Object> object);
|
||||
|
||||
inline MaybeObject* operator*() const;
|
||||
inline MaybeObject* operator->() const;
|
||||
inline Handle<Object> object() const;
|
||||
|
||||
bool is_identical_to(const MaybeObjectHandle& other) const {
|
||||
Handle<Object> this_handle;
|
||||
Handle<Object> other_handle;
|
||||
return reference_type_ == other.reference_type_ &&
|
||||
handle_.ToHandle(&this_handle) ==
|
||||
other.handle_.ToHandle(&other_handle) &&
|
||||
this_handle.is_identical_to(other_handle);
|
||||
}
|
||||
|
||||
bool is_null() const { return handle_.is_null(); }
|
||||
|
||||
private:
|
||||
inline MaybeObjectHandle(Object* object,
|
||||
HeapObjectReferenceType reference_type,
|
||||
Isolate* isolate);
|
||||
inline MaybeObjectHandle(Handle<Object> object,
|
||||
HeapObjectReferenceType reference_type);
|
||||
|
||||
HeapObjectReferenceType reference_type_;
|
||||
MaybeHandle<Object> handle_;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// A stack-allocated class that governs a number of local handles.
|
||||
|
@ -162,10 +162,10 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate,
|
||||
}
|
||||
|
||||
// static
|
||||
KeyedAccessLoadMode LoadHandler::GetKeyedAccessLoadMode(Object* handler) {
|
||||
KeyedAccessLoadMode LoadHandler::GetKeyedAccessLoadMode(MaybeObject* handler) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
if (handler->IsSmi()) {
|
||||
int const raw_handler = Smi::cast(handler)->value();
|
||||
int const raw_handler = Smi::cast(handler->ToSmi())->value();
|
||||
Kind const kind = KindBits::decode(raw_handler);
|
||||
if ((kind == kElement || kind == kIndexedString) &&
|
||||
AllowOutOfBoundsBits::decode(raw_handler)) {
|
||||
@ -195,8 +195,8 @@ Handle<Object> StoreHandler::StoreElementTransition(
|
||||
return handler;
|
||||
}
|
||||
|
||||
Handle<Object> StoreHandler::StoreTransition(Isolate* isolate,
|
||||
Handle<Map> transition_map) {
|
||||
MaybeObjectHandle StoreHandler::StoreTransition(Isolate* isolate,
|
||||
Handle<Map> transition_map) {
|
||||
bool is_dictionary_map = transition_map->is_dictionary_map();
|
||||
#ifdef DEBUG
|
||||
if (!is_dictionary_map) {
|
||||
@ -229,14 +229,14 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate,
|
||||
int config = KindBits::encode(kNormal) | LookupOnReceiverBits::encode(true);
|
||||
handler->set_smi_handler(Smi::FromInt(config));
|
||||
handler->set_validity_cell(*validity_cell);
|
||||
return handler;
|
||||
return MaybeObjectHandle(handler);
|
||||
|
||||
} else {
|
||||
// Ensure the transition map contains a valid prototype validity cell.
|
||||
if (!validity_cell.is_null()) {
|
||||
transition_map->set_prototype_validity_cell(*validity_cell);
|
||||
}
|
||||
return transition_map;
|
||||
return MaybeObjectHandle::Weak(transition_map);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ class LoadHandler final : public DataHandler {
|
||||
KeyedAccessLoadMode load_mode);
|
||||
|
||||
// Decodes the KeyedAccessLoadMode from a {handler}.
|
||||
static KeyedAccessLoadMode GetKeyedAccessLoadMode(Object* handler);
|
||||
static KeyedAccessLoadMode GetKeyedAccessLoadMode(MaybeObject* handler);
|
||||
};
|
||||
|
||||
// A set of bit fields representing Smi handlers for stores and a HeapObject
|
||||
@ -249,8 +249,8 @@ class StoreHandler final : public DataHandler {
|
||||
PropertyConstness constness,
|
||||
Representation representation);
|
||||
|
||||
static Handle<Object> StoreTransition(Isolate* isolate,
|
||||
Handle<Map> transition_map);
|
||||
static MaybeObjectHandle StoreTransition(Isolate* isolate,
|
||||
Handle<Map> transition_map);
|
||||
|
||||
// Creates a Smi-handler for storing a native data property on a fast object.
|
||||
static inline Handle<Smi> StoreNativeDataProperty(Isolate* isolate,
|
||||
|
@ -39,15 +39,17 @@ Address IC::raw_constant_pool() const {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool IC::IsHandler(Object* object) {
|
||||
return (object->IsSmi() && (object != nullptr)) || object->IsDataHandler() ||
|
||||
object->IsMap() ||
|
||||
(object->IsWeakCell() &&
|
||||
(WeakCell::cast(object)->cleared() ||
|
||||
WeakCell::cast(object)->value()->IsMap() ||
|
||||
WeakCell::cast(object)->value()->IsPropertyCell())) ||
|
||||
object->IsCode();
|
||||
bool IC::IsHandler(MaybeObject* object) {
|
||||
HeapObject* heap_object;
|
||||
return (object->IsSmi() && (object != nullptr)) ||
|
||||
(object->ToWeakHeapObject(&heap_object) && heap_object->IsMap()) ||
|
||||
(object->ToStrongHeapObject(&heap_object) &&
|
||||
(heap_object->IsDataHandler() ||
|
||||
(heap_object->IsWeakCell() &&
|
||||
(WeakCell::cast(heap_object)->cleared() ||
|
||||
WeakCell::cast(heap_object)->value()->IsMap() ||
|
||||
WeakCell::cast(heap_object)->value()->IsPropertyCell())) ||
|
||||
heap_object->IsCode()));
|
||||
}
|
||||
|
||||
bool IC::AddressIsDeoptimizedCode() const {
|
||||
|
123
src/ic/ic.cc
123
src/ic/ic.cc
@ -401,6 +401,11 @@ bool IC::ConfigureVectorState(IC::State new_state, Handle<Object> key) {
|
||||
|
||||
void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
|
||||
Handle<Object> handler) {
|
||||
ConfigureVectorState(name, map, MaybeObjectHandle(handler));
|
||||
}
|
||||
|
||||
void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
|
||||
const MaybeObjectHandle& handler) {
|
||||
if (IsGlobalIC()) {
|
||||
nexus()->ConfigureHandlerMode(handler);
|
||||
} else {
|
||||
@ -415,7 +420,7 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map,
|
||||
}
|
||||
|
||||
void IC::ConfigureVectorState(Handle<Name> name, MapHandles const& maps,
|
||||
ObjectHandles* handlers) {
|
||||
MaybeObjectHandles* handlers) {
|
||||
DCHECK(!IsGlobalIC());
|
||||
// Non-keyed ICs don't track the name explicitly.
|
||||
if (!is_keyed()) name = Handle<Name>::null();
|
||||
@ -535,14 +540,15 @@ static bool AddOneReceiverMapIfMissing(MapHandles* receiver_maps,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Object> handler) {
|
||||
bool IC::UpdatePolymorphicIC(Handle<Name> name,
|
||||
const MaybeObjectHandle& handler) {
|
||||
DCHECK(IsHandler(*handler));
|
||||
if (is_keyed() && state() != RECOMPUTE_HANDLER) {
|
||||
if (nexus()->FindFirstName() != *name) return false;
|
||||
}
|
||||
Handle<Map> map = receiver_map();
|
||||
MapHandles maps;
|
||||
ObjectHandles handlers;
|
||||
MaybeObjectHandles handlers;
|
||||
|
||||
TargetMaps(&maps);
|
||||
int number_of_maps = static_cast<int>(maps.size());
|
||||
@ -604,7 +610,8 @@ bool IC::UpdatePolymorphicIC(Handle<Name> name, Handle<Object> handler) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void IC::UpdateMonomorphicIC(Handle<Object> handler, Handle<Name> name) {
|
||||
void IC::UpdateMonomorphicIC(const MaybeObjectHandle& handler,
|
||||
Handle<Name> name) {
|
||||
DCHECK(IsHandler(*handler));
|
||||
ConfigureVectorState(name, receiver_map(), handler);
|
||||
}
|
||||
@ -612,7 +619,7 @@ void IC::UpdateMonomorphicIC(Handle<Object> handler, Handle<Name> name) {
|
||||
|
||||
void IC::CopyICToMegamorphicCache(Handle<Name> name) {
|
||||
MapHandles maps;
|
||||
ObjectHandles handlers;
|
||||
MaybeObjectHandles handlers;
|
||||
TargetMaps(&maps);
|
||||
if (!nexus()->FindHandlers(&handlers, static_cast<int>(maps.size()))) return;
|
||||
for (int i = 0; i < static_cast<int>(maps.size()); i++) {
|
||||
@ -638,6 +645,10 @@ bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) {
|
||||
}
|
||||
|
||||
void IC::PatchCache(Handle<Name> name, Handle<Object> handler) {
|
||||
PatchCache(name, MaybeObjectHandle(handler));
|
||||
}
|
||||
|
||||
void IC::PatchCache(Handle<Name> name, const MaybeObjectHandle& handler) {
|
||||
DCHECK(IsHandler(*handler));
|
||||
// Currently only load and store ICs support non-code handlers.
|
||||
DCHECK(IsAnyLoad() || IsAnyStore());
|
||||
@ -721,13 +732,17 @@ StubCache* IC::stub_cache() {
|
||||
}
|
||||
|
||||
void IC::UpdateMegamorphicCache(Handle<Map> map, Handle<Name> name,
|
||||
Handle<Object> handler) {
|
||||
if (handler->IsMap()) {
|
||||
const MaybeObjectHandle& handler) {
|
||||
HeapObject* heap_object;
|
||||
if (handler->ToWeakHeapObject(&heap_object) && heap_object->IsMap()) {
|
||||
// TODO(marja): remove this conversion once megamorphic stub cache supports
|
||||
// weak handlers.
|
||||
handler = Map::WeakCellForMap(Handle<Map>::cast(handler));
|
||||
Handle<Object> weak_cell =
|
||||
Map::WeakCellForMap(handle(Map::cast(heap_object)));
|
||||
stub_cache()->Set(*name, *map, *weak_cell);
|
||||
} else {
|
||||
stub_cache()->Set(*name, *map, handler->ToObject());
|
||||
}
|
||||
stub_cache()->Set(*name, *map, *handler);
|
||||
}
|
||||
|
||||
void IC::TraceHandlerCacheHitStats(LookupIterator* lookup) {
|
||||
@ -997,9 +1012,9 @@ static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
|
||||
}
|
||||
|
||||
bool KeyedLoadIC::CanChangeToAllowOutOfBounds(Handle<Map> receiver_map) {
|
||||
Handle<Object> handler;
|
||||
return nexus()->FindHandlerForMap(receiver_map).ToHandle(&handler) &&
|
||||
LoadHandler::GetKeyedAccessLoadMode(*handler) == STANDARD_LOAD;
|
||||
const MaybeObjectHandle& handler = nexus()->FindHandlerForMap(receiver_map);
|
||||
if (handler.is_null()) return false;
|
||||
return LoadHandler::GetKeyedAccessLoadMode(*handler) == STANDARD_LOAD;
|
||||
}
|
||||
|
||||
void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver,
|
||||
@ -1066,7 +1081,7 @@ void KeyedLoadIC::UpdateLoadElement(Handle<HeapObject> receiver,
|
||||
return;
|
||||
}
|
||||
|
||||
ObjectHandles handlers;
|
||||
MaybeObjectHandles handlers;
|
||||
handlers.reserve(target_receiver_maps.size());
|
||||
LoadElementPolymorphicHandlers(&target_receiver_maps, &handlers, load_mode);
|
||||
DCHECK_LE(1, target_receiver_maps.size());
|
||||
@ -1124,7 +1139,7 @@ Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map,
|
||||
}
|
||||
|
||||
void KeyedLoadIC::LoadElementPolymorphicHandlers(
|
||||
MapHandles* receiver_maps, ObjectHandles* handlers,
|
||||
MapHandles* receiver_maps, MaybeObjectHandles* handlers,
|
||||
KeyedAccessLoadMode load_mode) {
|
||||
// Filter out deprecated maps to ensure their instances get migrated.
|
||||
receiver_maps->erase(
|
||||
@ -1143,7 +1158,8 @@ void KeyedLoadIC::LoadElementPolymorphicHandlers(
|
||||
receiver_map->NotifyLeafMapLayoutChange();
|
||||
}
|
||||
}
|
||||
handlers->push_back(LoadElementHandler(receiver_map, load_mode));
|
||||
handlers->push_back(
|
||||
MaybeObjectHandle(LoadElementHandler(receiver_map, load_mode)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1447,7 +1463,7 @@ void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
|
||||
return;
|
||||
}
|
||||
|
||||
Handle<Object> handler;
|
||||
MaybeObjectHandle handler;
|
||||
if (LookupForWrite(lookup, value, store_mode)) {
|
||||
if (IsStoreGlobalIC()) {
|
||||
if (lookup->state() == LookupIterator::DATA &&
|
||||
@ -1462,14 +1478,15 @@ void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
|
||||
handler = ComputeHandler(lookup);
|
||||
} else {
|
||||
set_slow_stub_reason("LookupForWrite said 'false'");
|
||||
handler = slow_stub();
|
||||
// TODO(marja): change slow_stub to return MaybeObjectHandle.
|
||||
handler = MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
|
||||
PatchCache(lookup->name(), handler);
|
||||
TraceIC("StoreIC", lookup->name());
|
||||
}
|
||||
|
||||
Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
switch (lookup->state()) {
|
||||
case LookupIterator::TRANSITION: {
|
||||
Handle<JSObject> store_target = lookup->GetStoreTarget<JSObject>();
|
||||
@ -1483,8 +1500,8 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
DCHECK_EQ(*lookup->GetReceiver(), *holder);
|
||||
DCHECK_EQ(*store_target, *holder);
|
||||
#endif
|
||||
return StoreHandler::StoreGlobal(isolate(),
|
||||
lookup->transition_cell());
|
||||
return MaybeObjectHandle(
|
||||
StoreHandler::StoreGlobal(isolate(), lookup->transition_cell()));
|
||||
}
|
||||
|
||||
Handle<Smi> smi_handler = StoreHandler::StoreGlobalProxy(isolate());
|
||||
@ -1492,7 +1509,7 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
isolate()->factory()->NewWeakCell(lookup->transition_cell());
|
||||
Handle<Object> handler = StoreHandler::StoreThroughPrototype(
|
||||
isolate(), receiver_map(), store_target, smi_handler, cell);
|
||||
return handler;
|
||||
return MaybeObjectHandle(handler);
|
||||
}
|
||||
// Dictionary-to-fast transitions are not expected and not supported.
|
||||
DCHECK_IMPLIES(!lookup->transition_map()->is_dictionary_map(),
|
||||
@ -1510,7 +1527,7 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined(isolate()));
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreInterceptorStub);
|
||||
StoreInterceptorStub stub(isolate());
|
||||
return stub.GetCode();
|
||||
return MaybeObjectHandle(stub.GetCode());
|
||||
}
|
||||
|
||||
case LookupIterator::ACCESSOR: {
|
||||
@ -1522,7 +1539,7 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
if (!holder->HasFastProperties()) {
|
||||
set_slow_stub_reason("accessor on slow map");
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
Handle<Object> accessors = lookup->GetAccessors();
|
||||
if (accessors->IsAccessorInfo()) {
|
||||
@ -1530,29 +1547,31 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
if (v8::ToCData<Address>(info->setter()) == kNullAddress) {
|
||||
set_slow_stub_reason("setter == kNullAddress");
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
if (AccessorInfo::cast(*accessors)->is_special_data_property() &&
|
||||
!lookup->HolderIsReceiverOrHiddenPrototype()) {
|
||||
set_slow_stub_reason("special data property in prototype chain");
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
if (!AccessorInfo::IsCompatibleReceiverMap(isolate(), info,
|
||||
receiver_map())) {
|
||||
set_slow_stub_reason("incompatible receiver type");
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
|
||||
Handle<Smi> smi_handler = StoreHandler::StoreNativeDataProperty(
|
||||
isolate(), lookup->GetAccessorIndex());
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNativeDataPropertyDH);
|
||||
if (receiver.is_identical_to(holder)) return smi_handler;
|
||||
if (receiver.is_identical_to(holder)) {
|
||||
return MaybeObjectHandle(smi_handler);
|
||||
}
|
||||
TRACE_HANDLER_STATS(isolate(),
|
||||
StoreIC_StoreNativeDataPropertyOnPrototypeDH);
|
||||
return StoreHandler::StoreThroughPrototype(isolate(), receiver_map(),
|
||||
holder, smi_handler);
|
||||
return MaybeObjectHandle(StoreHandler::StoreThroughPrototype(
|
||||
isolate(), receiver_map(), holder, smi_handler));
|
||||
|
||||
} else if (accessors->IsAccessorPair()) {
|
||||
Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
|
||||
@ -1560,14 +1579,14 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
if (!setter->IsJSFunction() && !setter->IsFunctionTemplateInfo()) {
|
||||
set_slow_stub_reason("setter not a function");
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
|
||||
if (setter->IsFunctionTemplateInfo() &&
|
||||
FunctionTemplateInfo::cast(*setter)->BreakAtEntry()) {
|
||||
// Do not install an IC if the api function has a breakpoint.
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
|
||||
CallOptimization call_optimization(setter);
|
||||
@ -1588,31 +1607,33 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
Handle<WeakCell> data_cell = isolate()->factory()->NewWeakCell(
|
||||
call_optimization.api_call_info());
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreApiSetterOnPrototypeDH);
|
||||
return StoreHandler::StoreThroughPrototype(
|
||||
return MaybeObjectHandle(StoreHandler::StoreThroughPrototype(
|
||||
isolate(), receiver_map(), holder, smi_handler, data_cell,
|
||||
context_cell);
|
||||
context_cell));
|
||||
}
|
||||
set_slow_stub_reason("incompatible receiver");
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
} else if (setter->IsFunctionTemplateInfo()) {
|
||||
set_slow_stub_reason("setter non-simple template");
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
|
||||
Handle<Smi> smi_handler =
|
||||
StoreHandler::StoreAccessor(isolate(), lookup->GetAccessorIndex());
|
||||
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreAccessorDH);
|
||||
if (receiver.is_identical_to(holder)) return smi_handler;
|
||||
if (receiver.is_identical_to(holder)) {
|
||||
return MaybeObjectHandle(smi_handler);
|
||||
}
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreAccessorOnPrototypeDH);
|
||||
|
||||
return StoreHandler::StoreThroughPrototype(isolate(), receiver_map(),
|
||||
holder, smi_handler);
|
||||
return MaybeObjectHandle(StoreHandler::StoreThroughPrototype(
|
||||
isolate(), receiver_map(), holder, smi_handler));
|
||||
}
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
|
||||
case LookupIterator::DATA: {
|
||||
@ -1626,12 +1647,12 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
if (lookup->is_dictionary_holder()) {
|
||||
if (holder->IsJSGlobalObject()) {
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreGlobalDH);
|
||||
return StoreHandler::StoreGlobal(isolate(),
|
||||
lookup->GetPropertyCell());
|
||||
return MaybeObjectHandle(
|
||||
StoreHandler::StoreGlobal(isolate(), lookup->GetPropertyCell()));
|
||||
}
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_StoreNormalDH);
|
||||
DCHECK(holder.is_identical_to(receiver));
|
||||
return StoreHandler::StoreNormal(isolate());
|
||||
return MaybeObjectHandle(StoreHandler::StoreNormal(isolate()));
|
||||
}
|
||||
|
||||
// -------------- Fields --------------
|
||||
@ -1645,22 +1666,22 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
// we must store the value unconditionally even to kConst fields.
|
||||
constness = kMutable;
|
||||
}
|
||||
return StoreHandler::StoreField(isolate(), descriptor, index, constness,
|
||||
lookup->representation());
|
||||
return MaybeObjectHandle(StoreHandler::StoreField(
|
||||
isolate(), descriptor, index, constness, lookup->representation()));
|
||||
}
|
||||
|
||||
// -------------- Constant properties --------------
|
||||
DCHECK_EQ(kDescriptor, lookup->property_details().location());
|
||||
set_slow_stub_reason("constant property");
|
||||
TRACE_HANDLER_STATS(isolate(), StoreIC_SlowStub);
|
||||
return slow_stub();
|
||||
return MaybeObjectHandle(slow_stub());
|
||||
}
|
||||
case LookupIterator::JSPROXY: {
|
||||
Handle<JSReceiver> receiver =
|
||||
Handle<JSReceiver>::cast(lookup->GetReceiver());
|
||||
Handle<JSProxy> holder = lookup->GetHolder<JSProxy>();
|
||||
return StoreHandler::StoreProxy(isolate(), receiver_map(), holder,
|
||||
receiver);
|
||||
return MaybeObjectHandle(StoreHandler::StoreProxy(
|
||||
isolate(), receiver_map(), holder, receiver));
|
||||
}
|
||||
|
||||
case LookupIterator::INTEGER_INDEXED_EXOTIC:
|
||||
@ -1668,7 +1689,7 @@ Handle<Object> StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
case LookupIterator::NOT_FOUND:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return Handle<Code>::null();
|
||||
return MaybeObjectHandle();
|
||||
}
|
||||
|
||||
void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
|
||||
@ -1786,7 +1807,7 @@ void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map,
|
||||
}
|
||||
}
|
||||
|
||||
ObjectHandles handlers;
|
||||
MaybeObjectHandles handlers;
|
||||
handlers.reserve(target_receiver_maps.size());
|
||||
StoreElementPolymorphicHandlers(&target_receiver_maps, &handlers, store_mode);
|
||||
if (target_receiver_maps.size() == 0) {
|
||||
@ -1878,7 +1899,7 @@ Handle<Object> KeyedStoreIC::StoreElementHandler(
|
||||
}
|
||||
|
||||
void KeyedStoreIC::StoreElementPolymorphicHandlers(
|
||||
MapHandles* receiver_maps, ObjectHandles* handlers,
|
||||
MapHandles* receiver_maps, MaybeObjectHandles* handlers,
|
||||
KeyedAccessStoreMode store_mode) {
|
||||
DCHECK(store_mode == STANDARD_STORE ||
|
||||
store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW ||
|
||||
@ -1930,7 +1951,7 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers(
|
||||
}
|
||||
}
|
||||
DCHECK(!handler.is_null());
|
||||
handlers->push_back(handler);
|
||||
handlers->push_back(MaybeObjectHandle(handler));
|
||||
}
|
||||
}
|
||||
|
||||
|
23
src/ic/ic.h
23
src/ic/ic.h
@ -64,7 +64,7 @@ class IC {
|
||||
IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind());
|
||||
}
|
||||
|
||||
static inline bool IsHandler(Object* object);
|
||||
static inline bool IsHandler(MaybeObject* object);
|
||||
|
||||
// Nofity the IC system that a feedback has changed.
|
||||
static void OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector,
|
||||
@ -101,9 +101,11 @@ class IC {
|
||||
// Configure the vector for MONOMORPHIC.
|
||||
void ConfigureVectorState(Handle<Name> name, Handle<Map> map,
|
||||
Handle<Object> handler);
|
||||
void ConfigureVectorState(Handle<Name> name, Handle<Map> map,
|
||||
const MaybeObjectHandle& handler);
|
||||
// Configure the vector for POLYMORPHIC.
|
||||
void ConfigureVectorState(Handle<Name> name, MapHandles const& maps,
|
||||
ObjectHandles* handlers);
|
||||
MaybeObjectHandles* handlers);
|
||||
|
||||
char TransitionMarkFromState(IC::State state);
|
||||
void TraceIC(const char* type, Handle<Object> name);
|
||||
@ -116,16 +118,17 @@ class IC {
|
||||
|
||||
void TraceHandlerCacheHitStats(LookupIterator* lookup);
|
||||
|
||||
void UpdateMonomorphicIC(Handle<Object> handler, Handle<Name> name);
|
||||
bool UpdatePolymorphicIC(Handle<Name> name, Handle<Object> code);
|
||||
void UpdateMonomorphicIC(const MaybeObjectHandle& handler, Handle<Name> name);
|
||||
bool UpdatePolymorphicIC(Handle<Name> name, const MaybeObjectHandle& handler);
|
||||
void UpdateMegamorphicCache(Handle<Map> map, Handle<Name> name,
|
||||
Handle<Object> code);
|
||||
const MaybeObjectHandle& handler);
|
||||
|
||||
StubCache* stub_cache();
|
||||
|
||||
void CopyICToMegamorphicCache(Handle<Name> name);
|
||||
bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map);
|
||||
void PatchCache(Handle<Name> name, Handle<Object> code);
|
||||
void PatchCache(Handle<Name> name, Handle<Object> handler);
|
||||
void PatchCache(Handle<Name> name, const MaybeObjectHandle& handler);
|
||||
FeedbackSlotKind kind() const { return kind_; }
|
||||
bool IsGlobalIC() const { return IsLoadGlobalIC() || IsStoreGlobalIC(); }
|
||||
bool IsLoadIC() const { return IsLoadICKind(kind_); }
|
||||
@ -199,7 +202,7 @@ class IC {
|
||||
State state_;
|
||||
FeedbackSlotKind kind_;
|
||||
Handle<Map> receiver_map_;
|
||||
MaybeHandle<Object> maybe_handler_;
|
||||
MaybeObjectHandle maybe_handler_;
|
||||
|
||||
MapHandles target_maps_;
|
||||
bool target_maps_set_;
|
||||
@ -288,7 +291,7 @@ class KeyedLoadIC : public LoadIC {
|
||||
KeyedAccessLoadMode load_mode);
|
||||
|
||||
void LoadElementPolymorphicHandlers(MapHandles* receiver_maps,
|
||||
ObjectHandles* handlers,
|
||||
MaybeObjectHandles* handlers,
|
||||
KeyedAccessLoadMode load_mode);
|
||||
|
||||
// Returns true if the receiver_map has a kElement or kIndexedString
|
||||
@ -328,7 +331,7 @@ class StoreIC : public IC {
|
||||
JSReceiver::StoreFromKeyed store_mode);
|
||||
|
||||
private:
|
||||
Handle<Object> ComputeHandler(LookupIterator* lookup);
|
||||
MaybeObjectHandle ComputeHandler(LookupIterator* lookup);
|
||||
|
||||
friend class IC;
|
||||
};
|
||||
@ -385,7 +388,7 @@ class KeyedStoreIC : public StoreIC {
|
||||
KeyedAccessStoreMode store_mode);
|
||||
|
||||
void StoreElementPolymorphicHandlers(MapHandles* receiver_maps,
|
||||
ObjectHandles* handlers,
|
||||
MaybeObjectHandles* handlers,
|
||||
KeyedAccessStoreMode store_mode);
|
||||
|
||||
friend class IC;
|
||||
|
@ -65,7 +65,7 @@ bool CommonStubCacheChecks(StubCache* stub_cache, Name* name, Map* map,
|
||||
DCHECK(!name->GetHeap()->InNewSpace(handler));
|
||||
DCHECK(name->IsUniqueName());
|
||||
DCHECK(name->HasHashCode());
|
||||
if (handler) DCHECK(IC::IsHandler(handler));
|
||||
if (handler) DCHECK(IC::IsHandler(MaybeObject::FromObject(handler)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef V8_OBJECTS_MAYBE_OBJECT_INL_H_
|
||||
#define V8_OBJECTS_MAYBE_OBJECT_INL_H_
|
||||
|
||||
#include "src/objects/maybe-object.h"
|
||||
|
||||
#include "include/v8.h"
|
||||
#include "src/globals.h"
|
||||
|
||||
|
@ -803,7 +803,7 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
|
||||
if (nexus.ic_state() == UNINITIALIZED) {
|
||||
if (name->IsUniqueName()) {
|
||||
nexus.ConfigureMonomorphic(name, handle(object->map()),
|
||||
Handle<Code>::null());
|
||||
MaybeObjectHandle());
|
||||
} else {
|
||||
nexus.ConfigureMegamorphic(PROPERTY);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user