Commit 1684cd8b authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[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/1055449Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53151}
parent 8ec92f51
...@@ -668,15 +668,11 @@ bool FeedbackNexus::ConfigureLexicalVarMode(int script_context_index, ...@@ -668,15 +668,11 @@ bool FeedbackNexus::ConfigureLexicalVarMode(int script_context_index,
return true; return true;
} }
void FeedbackNexus::ConfigureHandlerMode(Handle<Object> handler) { void FeedbackNexus::ConfigureHandlerMode(const MaybeObjectHandle& handler) {
DCHECK(IsGlobalICKind(kind())); DCHECK(IsGlobalICKind(kind()));
DCHECK(IC::IsHandler(*handler)); DCHECK(IC::IsHandler(*handler));
SetFeedback(GetIsolate()->heap()->empty_weak_cell()); SetFeedback(GetIsolate()->heap()->empty_weak_cell());
if (handler->IsMap()) {
SetFeedbackExtra(HeapObjectReference::Weak(HeapObject::cast(*handler)));
} else {
SetFeedbackExtra(*handler); SetFeedbackExtra(*handler);
}
} }
int FeedbackNexus::GetCallCount() { int FeedbackNexus::GetCallCount() {
...@@ -722,7 +718,7 @@ float FeedbackNexus::ComputeCallFrequency() { ...@@ -722,7 +718,7 @@ float FeedbackNexus::ComputeCallFrequency() {
void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name, void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
Handle<Map> receiver_map, Handle<Map> receiver_map,
Handle<Object> handler) { const MaybeObjectHandle& handler) {
DCHECK(handler.is_null() || IC::IsHandler(*handler)); DCHECK(handler.is_null() || IC::IsHandler(*handler));
Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map); Handle<WeakCell> cell = Map::WeakCellForMap(receiver_map);
if (kind() == FeedbackSlotKind::kStoreDataPropertyInLiteral) { if (kind() == FeedbackSlotKind::kStoreDataPropertyInLiteral) {
...@@ -731,27 +727,19 @@ void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name, ...@@ -731,27 +727,19 @@ void FeedbackNexus::ConfigureMonomorphic(Handle<Name> name,
} else { } else {
if (name.is_null()) { if (name.is_null()) {
SetFeedback(*cell); SetFeedback(*cell);
if (handler->IsMap()) {
SetFeedbackExtra(HeapObjectReference::Weak(*handler));
} else {
SetFeedbackExtra(*handler); SetFeedbackExtra(*handler);
}
} else { } else {
Handle<WeakFixedArray> array = EnsureExtraArrayOfSize(2); Handle<WeakFixedArray> array = EnsureExtraArrayOfSize(2);
SetFeedback(*name); SetFeedback(*name);
array->Set(0, HeapObjectReference::Strong(*cell)); array->Set(0, HeapObjectReference::Strong(*cell));
if (handler->IsMap()) { array->Set(1, *handler);
array->Set(1, HeapObjectReference::Weak(*handler));
} else {
array->Set(1, MaybeObject::FromObject(*handler));
}
} }
} }
} }
void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name, void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
MapHandles const& maps, MapHandles const& maps,
ObjectHandles* handlers) { MaybeObjectHandles* handlers) {
DCHECK_EQ(handlers->size(), maps.size()); DCHECK_EQ(handlers->size(), maps.size());
int receiver_count = static_cast<int>(maps.size()); int receiver_count = static_cast<int>(maps.size());
DCHECK_GT(receiver_count, 1); DCHECK_GT(receiver_count, 1);
...@@ -770,13 +758,7 @@ void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name, ...@@ -770,13 +758,7 @@ void FeedbackNexus::ConfigurePolymorphic(Handle<Name> name,
Handle<WeakCell> cell = Map::WeakCellForMap(map); Handle<WeakCell> cell = Map::WeakCellForMap(map);
array->Set(current * 2, HeapObjectReference::Strong(*cell)); array->Set(current * 2, HeapObjectReference::Strong(*cell));
DCHECK(IC::IsHandler(*handlers->at(current))); DCHECK(IC::IsHandler(*handlers->at(current)));
if (handlers->at(current)->IsMap()) { array->Set(current * 2 + 1, *handlers->at(current));
array->Set(current * 2 + 1,
HeapObjectReference::Weak(*handlers->at(current)));
} else {
array->Set(current * 2 + 1,
MaybeObject::FromObject(*handlers->at(current)));
}
} }
} }
...@@ -819,7 +801,7 @@ int FeedbackNexus::ExtractMaps(MapHandles* maps) const { ...@@ -819,7 +801,7 @@ int FeedbackNexus::ExtractMaps(MapHandles* maps) const {
return 0; return 0;
} }
MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const { MaybeObjectHandle FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) || DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind())); IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()));
...@@ -841,8 +823,7 @@ MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const { ...@@ -841,8 +823,7 @@ MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
Map* array_map = Map::cast(cell->value()); Map* array_map = Map::cast(cell->value());
if (array_map == *map && if (array_map == *map &&
!array->Get(i + increment - 1)->IsClearedWeakHeapObject()) { !array->Get(i + increment - 1)->IsClearedWeakHeapObject()) {
// This converts a weak reference to a strong reference. MaybeObject* handler = array->Get(i + increment - 1);
Object* handler = array->Get(i + increment - 1)->GetHeapObjectOrSmi();
DCHECK(IC::IsHandler(handler)); DCHECK(IC::IsHandler(handler));
return handle(handler, isolate); return handle(handler, isolate);
} }
...@@ -853,18 +834,18 @@ MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const { ...@@ -853,18 +834,18 @@ MaybeHandle<Object> FeedbackNexus::FindHandlerForMap(Handle<Map> map) const {
if (!cell->cleared()) { if (!cell->cleared()) {
Map* cell_map = Map::cast(cell->value()); Map* cell_map = Map::cast(cell->value());
if (cell_map == *map && !GetFeedbackExtra()->IsClearedWeakHeapObject()) { if (cell_map == *map && !GetFeedbackExtra()->IsClearedWeakHeapObject()) {
// This converts a weak reference to a strong reference. MaybeObject* handler = GetFeedbackExtra();
Object* handler = GetFeedbackExtra()->GetHeapObjectOrSmi();
DCHECK(IC::IsHandler(handler)); DCHECK(IC::IsHandler(handler));
return handle(handler, isolate); 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()) || DCHECK(IsLoadICKind(kind()) || IsStoreICKind(kind()) ||
IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) || IsKeyedLoadICKind(kind()) || IsKeyedStoreICKind(kind()) ||
IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) || IsStoreOwnICKind(kind()) || IsStoreDataPropertyInLiteralKind(kind()) ||
...@@ -887,8 +868,7 @@ bool FeedbackNexus::FindHandlers(ObjectHandles* code_list, int length) const { ...@@ -887,8 +868,7 @@ bool FeedbackNexus::FindHandlers(ObjectHandles* code_list, int length) const {
// Be sure to skip handlers whose maps have been cleared. // Be sure to skip handlers whose maps have been cleared.
if (!cell->cleared() && if (!cell->cleared() &&
!array->Get(i + increment - 1)->IsClearedWeakHeapObject()) { !array->Get(i + increment - 1)->IsClearedWeakHeapObject()) {
// This converts a weak reference to a strong reference. MaybeObject* handler = array->Get(i + increment - 1);
Object* handler = array->Get(i + increment - 1)->GetHeapObjectOrSmi();
DCHECK(IC::IsHandler(handler)); DCHECK(IC::IsHandler(handler));
code_list->push_back(handle(handler, isolate)); code_list->push_back(handle(handler, isolate));
count++; count++;
...@@ -898,10 +878,8 @@ bool FeedbackNexus::FindHandlers(ObjectHandles* code_list, int length) const { ...@@ -898,10 +878,8 @@ bool FeedbackNexus::FindHandlers(ObjectHandles* code_list, int length) const {
WeakCell* cell = WeakCell::cast(feedback); WeakCell* cell = WeakCell::cast(feedback);
MaybeObject* extra = GetFeedbackExtra(); MaybeObject* extra = GetFeedbackExtra();
if (!cell->cleared() && !extra->IsClearedWeakHeapObject()) { if (!cell->cleared() && !extra->IsClearedWeakHeapObject()) {
// This converts a weak reference to a strong reference. DCHECK(IC::IsHandler(extra));
Object* handler = extra->GetHeapObjectOrSmi(); code_list->push_back(handle(extra, isolate));
DCHECK(IC::IsHandler(handler));
code_list->push_back(handle(handler, isolate));
count++; count++;
} }
} }
...@@ -921,13 +899,13 @@ Name* FeedbackNexus::FindFirstName() const { ...@@ -921,13 +899,13 @@ Name* FeedbackNexus::FindFirstName() const {
KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const { KeyedAccessLoadMode FeedbackNexus::GetKeyedAccessLoadMode() const {
DCHECK(IsKeyedLoadICKind(kind())); DCHECK(IsKeyedLoadICKind(kind()));
MapHandles maps; MapHandles maps;
ObjectHandles handlers; MaybeObjectHandles handlers;
if (GetKeyType() == PROPERTY) return STANDARD_LOAD; if (GetKeyType() == PROPERTY) return STANDARD_LOAD;
ExtractMaps(&maps); ExtractMaps(&maps);
FindHandlers(&handlers, static_cast<int>(maps.size())); FindHandlers(&handlers, static_cast<int>(maps.size()));
for (Handle<Object> const& handler : handlers) { for (MaybeObjectHandle const& handler : handlers) {
KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler); KeyedAccessLoadMode mode = LoadHandler::GetKeyedAccessLoadMode(*handler);
if (mode != STANDARD_LOAD) return mode; if (mode != STANDARD_LOAD) return mode;
} }
...@@ -939,26 +917,27 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const { ...@@ -939,26 +917,27 @@ KeyedAccessStoreMode FeedbackNexus::GetKeyedAccessStoreMode() const {
DCHECK(IsKeyedStoreICKind(kind()) || IsStoreInArrayLiteralICKind(kind())); DCHECK(IsKeyedStoreICKind(kind()) || IsStoreInArrayLiteralICKind(kind()));
KeyedAccessStoreMode mode = STANDARD_STORE; KeyedAccessStoreMode mode = STANDARD_STORE;
MapHandles maps; MapHandles maps;
ObjectHandles handlers; MaybeObjectHandles handlers;
if (GetKeyType() == PROPERTY) return mode; if (GetKeyType() == PROPERTY) return mode;
ExtractMaps(&maps); ExtractMaps(&maps);
FindHandlers(&handlers, static_cast<int>(maps.size())); 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. // The first handler that isn't the slow handler will have the bits we need.
Handle<Code> handler; Handle<Code> handler;
if (maybe_code_handler->IsStoreHandler()) { if (maybe_code_handler.object()->IsStoreHandler()) {
Handle<StoreHandler> data_handler = 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())); handler = handle(Code::cast(data_handler->smi_handler()));
} else if (maybe_code_handler->IsSmi()) { } else if (maybe_code_handler.object()->IsSmi()) {
// Skip proxy handlers. // Skip proxy handlers.
DCHECK_EQ(*maybe_code_handler, *StoreHandler::StoreProxy(GetIsolate())); DCHECK_EQ(*(maybe_code_handler.object()),
*StoreHandler::StoreProxy(GetIsolate()));
continue; continue;
} else { } else {
// Element store without prototype chain check. // 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; if (handler->is_builtin()) continue;
} }
CodeStub::Major major_key = CodeStub::MajorKeyFromKey(handler->stub_key()); CodeStub::Major major_key = CodeStub::MajorKeyFromKey(handler->stub_key());
......
...@@ -129,7 +129,7 @@ inline LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind) { ...@@ -129,7 +129,7 @@ inline LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind) {
std::ostream& operator<<(std::ostream& os, FeedbackSlotKind kind); std::ostream& operator<<(std::ostream& os, FeedbackSlotKind kind);
typedef std::vector<Handle<Object>> ObjectHandles; typedef std::vector<MaybeObjectHandle> MaybeObjectHandles;
class FeedbackMetadata; class FeedbackMetadata;
...@@ -595,8 +595,8 @@ class FeedbackNexus final { ...@@ -595,8 +595,8 @@ class FeedbackNexus final {
InlineCacheState StateFromFeedback() const; InlineCacheState StateFromFeedback() const;
int ExtractMaps(MapHandles* maps) const; int ExtractMaps(MapHandles* maps) const;
MaybeHandle<Object> FindHandlerForMap(Handle<Map> map) const; MaybeObjectHandle FindHandlerForMap(Handle<Map> map) const;
bool FindHandlers(ObjectHandles* code_list, int length = -1) const; bool FindHandlers(MaybeObjectHandles* code_list, int length = -1) const;
bool IsCleared() const { bool IsCleared() const {
InlineCacheState state = StateFromFeedback(); InlineCacheState state = StateFromFeedback();
...@@ -615,10 +615,10 @@ class FeedbackNexus final { ...@@ -615,10 +615,10 @@ class FeedbackNexus final {
inline Isolate* GetIsolate() const; inline Isolate* GetIsolate() const;
void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map, void ConfigureMonomorphic(Handle<Name> name, Handle<Map> receiver_map,
Handle<Object> handler); const MaybeObjectHandle& handler);
void ConfigurePolymorphic(Handle<Name> name, MapHandles const& maps, void ConfigurePolymorphic(Handle<Name> name, MapHandles const& maps,
ObjectHandles* handlers); MaybeObjectHandles* handlers);
BinaryOperationHint GetBinaryOperationFeedback() const; BinaryOperationHint GetBinaryOperationFeedback() const;
CompareOperationHint GetCompareOperationFeedback() const; CompareOperationHint GetCompareOperationFeedback() const;
...@@ -657,7 +657,7 @@ class FeedbackNexus final { ...@@ -657,7 +657,7 @@ class FeedbackNexus final {
// Returns false if given combination of indices is not allowed. // Returns false if given combination of indices is not allowed.
bool ConfigureLexicalVarMode(int script_context_index, bool ConfigureLexicalVarMode(int script_context_index,
int context_slot_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. // Bit positions in a smi that encodes lexical environment variable access.
#define LEXICAL_MODE_BIT_FIELDS(V, _) \ #define LEXICAL_MODE_BIT_FIELDS(V, _) \
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/isolate.h" #include "src/isolate.h"
#include "src/msan.h" #include "src/msan.h"
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/objects/maybe-object-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -44,6 +45,65 @@ inline std::ostream& operator<<(std::ostream& os, Handle<T> handle) { ...@@ -44,6 +45,65 @@ inline std::ostream& operator<<(std::ostream& os, Handle<T> handle) {
return os << Brief(*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() { HandleScope::~HandleScope() {
#ifdef DEBUG #ifdef DEBUG
......
...@@ -235,6 +235,43 @@ class MaybeHandle final { ...@@ -235,6 +235,43 @@ class MaybeHandle final {
friend class MaybeHandle; 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. // A stack-allocated class that governs a number of local handles.
......
...@@ -162,10 +162,10 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate, ...@@ -162,10 +162,10 @@ Handle<Object> LoadHandler::LoadFullChain(Isolate* isolate,
} }
// static // static
KeyedAccessLoadMode LoadHandler::GetKeyedAccessLoadMode(Object* handler) { KeyedAccessLoadMode LoadHandler::GetKeyedAccessLoadMode(MaybeObject* handler) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
if (handler->IsSmi()) { 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); Kind const kind = KindBits::decode(raw_handler);
if ((kind == kElement || kind == kIndexedString) && if ((kind == kElement || kind == kIndexedString) &&
AllowOutOfBoundsBits::decode(raw_handler)) { AllowOutOfBoundsBits::decode(raw_handler)) {
...@@ -195,7 +195,7 @@ Handle<Object> StoreHandler::StoreElementTransition( ...@@ -195,7 +195,7 @@ Handle<Object> StoreHandler::StoreElementTransition(
return handler; return handler;
} }
Handle<Object> StoreHandler::StoreTransition(Isolate* isolate, MaybeObjectHandle StoreHandler::StoreTransition(Isolate* isolate,
Handle<Map> transition_map) { Handle<Map> transition_map) {
bool is_dictionary_map = transition_map->is_dictionary_map(); bool is_dictionary_map = transition_map->is_dictionary_map();
#ifdef DEBUG #ifdef DEBUG
...@@ -229,14 +229,14 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate, ...@@ -229,14 +229,14 @@ Handle<Object> StoreHandler::StoreTransition(Isolate* isolate,
int config = KindBits::encode(kNormal) | LookupOnReceiverBits::encode(true); int config = KindBits::encode(kNormal) | LookupOnReceiverBits::encode(true);
handler->set_smi_handler(Smi::FromInt(config)); handler->set_smi_handler(Smi::FromInt(config));
handler->set_validity_cell(*validity_cell); handler->set_validity_cell(*validity_cell);
return handler; return MaybeObjectHandle(handler);
} else { } else {
// Ensure the transition map contains a valid prototype validity cell. // Ensure the transition map contains a valid prototype validity cell.
if (!validity_cell.is_null()) { if (!validity_cell.is_null()) {
transition_map->set_prototype_validity_cell(*validity_cell); 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 { ...@@ -175,7 +175,7 @@ class LoadHandler final : public DataHandler {
KeyedAccessLoadMode load_mode); KeyedAccessLoadMode load_mode);
// Decodes the KeyedAccessLoadMode from a {handler}. // 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 // A set of bit fields representing Smi handlers for stores and a HeapObject
...@@ -249,7 +249,7 @@ class StoreHandler final : public DataHandler { ...@@ -249,7 +249,7 @@ class StoreHandler final : public DataHandler {
PropertyConstness constness, PropertyConstness constness,
Representation representation); Representation representation);
static Handle<Object> StoreTransition(Isolate* isolate, static MaybeObjectHandle StoreTransition(Isolate* isolate,
Handle<Map> transition_map); Handle<Map> transition_map);
// Creates a Smi-handler for storing a native data property on a fast object. // Creates a Smi-handler for storing a native data property on a fast object.
......
...@@ -39,15 +39,17 @@ Address IC::raw_constant_pool() const { ...@@ -39,15 +39,17 @@ Address IC::raw_constant_pool() const {
} }
} }
bool IC::IsHandler(MaybeObject* object) {
bool IC::IsHandler(Object* object) { HeapObject* heap_object;
return (object->IsSmi() && (object != nullptr)) || object->IsDataHandler() || return (object->IsSmi() && (object != nullptr)) ||
object->IsMap() || (object->ToWeakHeapObject(&heap_object) && heap_object->IsMap()) ||
(object->IsWeakCell() && (object->ToStrongHeapObject(&heap_object) &&
(WeakCell::cast(object)->cleared() || (heap_object->IsDataHandler() ||
WeakCell::cast(object)->value()->IsMap() || (heap_object->IsWeakCell() &&
WeakCell::cast(object)->value()->IsPropertyCell())) || (WeakCell::cast(heap_object)->cleared() ||
object->IsCode(); WeakCell::cast(heap_object)->value()->IsMap() ||
WeakCell::cast(heap_object)->value()->IsPropertyCell())) ||
heap_object->IsCode()));
} }
bool IC::AddressIsDeoptimizedCode() const { bool IC::AddressIsDeoptimizedCode() const {
......
This diff is collapsed.
...@@ -64,7 +64,7 @@ class IC { ...@@ -64,7 +64,7 @@ class IC {
IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind()); IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind());
} }
static inline bool IsHandler(Object* object); static inline bool IsHandler(MaybeObject* object);
// Nofity the IC system that a feedback has changed. // Nofity the IC system that a feedback has changed.
static void OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector, static void OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector,
...@@ -101,9 +101,11 @@ class IC { ...@@ -101,9 +101,11 @@ class IC {
// Configure the vector for MONOMORPHIC. // Configure the vector for MONOMORPHIC.
void ConfigureVectorState(Handle<Name> name, Handle<Map> map, void ConfigureVectorState(Handle<Name> name, Handle<Map> map,
Handle<Object> handler); Handle<Object> handler);
void ConfigureVectorState(Handle<Name> name, Handle<Map> map,
const MaybeObjectHandle& handler);
// Configure the vector for POLYMORPHIC. // Configure the vector for POLYMORPHIC.
void ConfigureVectorState(Handle<Name> name, MapHandles const& maps, void ConfigureVectorState(Handle<Name> name, MapHandles const& maps,
ObjectHandles* handlers); MaybeObjectHandles* handlers);
char TransitionMarkFromState(IC::State state); char TransitionMarkFromState(IC::State state);
void TraceIC(const char* type, Handle<Object> name); void TraceIC(const char* type, Handle<Object> name);
...@@ -116,16 +118,17 @@ class IC { ...@@ -116,16 +118,17 @@ class IC {
void TraceHandlerCacheHitStats(LookupIterator* lookup); void TraceHandlerCacheHitStats(LookupIterator* lookup);
void UpdateMonomorphicIC(Handle<Object> handler, Handle<Name> name); void UpdateMonomorphicIC(const MaybeObjectHandle& handler, Handle<Name> name);
bool UpdatePolymorphicIC(Handle<Name> name, Handle<Object> code); bool UpdatePolymorphicIC(Handle<Name> name, const MaybeObjectHandle& handler);
void UpdateMegamorphicCache(Handle<Map> map, Handle<Name> name, void UpdateMegamorphicCache(Handle<Map> map, Handle<Name> name,
Handle<Object> code); const MaybeObjectHandle& handler);
StubCache* stub_cache(); StubCache* stub_cache();
void CopyICToMegamorphicCache(Handle<Name> name); void CopyICToMegamorphicCache(Handle<Name> name);
bool IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map); 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_; } FeedbackSlotKind kind() const { return kind_; }
bool IsGlobalIC() const { return IsLoadGlobalIC() || IsStoreGlobalIC(); } bool IsGlobalIC() const { return IsLoadGlobalIC() || IsStoreGlobalIC(); }
bool IsLoadIC() const { return IsLoadICKind(kind_); } bool IsLoadIC() const { return IsLoadICKind(kind_); }
...@@ -199,7 +202,7 @@ class IC { ...@@ -199,7 +202,7 @@ class IC {
State state_; State state_;
FeedbackSlotKind kind_; FeedbackSlotKind kind_;
Handle<Map> receiver_map_; Handle<Map> receiver_map_;
MaybeHandle<Object> maybe_handler_; MaybeObjectHandle maybe_handler_;
MapHandles target_maps_; MapHandles target_maps_;
bool target_maps_set_; bool target_maps_set_;
...@@ -288,7 +291,7 @@ class KeyedLoadIC : public LoadIC { ...@@ -288,7 +291,7 @@ class KeyedLoadIC : public LoadIC {
KeyedAccessLoadMode load_mode); KeyedAccessLoadMode load_mode);
void LoadElementPolymorphicHandlers(MapHandles* receiver_maps, void LoadElementPolymorphicHandlers(MapHandles* receiver_maps,
ObjectHandles* handlers, MaybeObjectHandles* handlers,
KeyedAccessLoadMode load_mode); KeyedAccessLoadMode load_mode);
// Returns true if the receiver_map has a kElement or kIndexedString // Returns true if the receiver_map has a kElement or kIndexedString
...@@ -328,7 +331,7 @@ class StoreIC : public IC { ...@@ -328,7 +331,7 @@ class StoreIC : public IC {
JSReceiver::StoreFromKeyed store_mode); JSReceiver::StoreFromKeyed store_mode);
private: private:
Handle<Object> ComputeHandler(LookupIterator* lookup); MaybeObjectHandle ComputeHandler(LookupIterator* lookup);
friend class IC; friend class IC;
}; };
...@@ -385,7 +388,7 @@ class KeyedStoreIC : public StoreIC { ...@@ -385,7 +388,7 @@ class KeyedStoreIC : public StoreIC {
KeyedAccessStoreMode store_mode); KeyedAccessStoreMode store_mode);
void StoreElementPolymorphicHandlers(MapHandles* receiver_maps, void StoreElementPolymorphicHandlers(MapHandles* receiver_maps,
ObjectHandles* handlers, MaybeObjectHandles* handlers,
KeyedAccessStoreMode store_mode); KeyedAccessStoreMode store_mode);
friend class IC; friend class IC;
......
...@@ -65,7 +65,7 @@ bool CommonStubCacheChecks(StubCache* stub_cache, Name* name, Map* map, ...@@ -65,7 +65,7 @@ bool CommonStubCacheChecks(StubCache* stub_cache, Name* name, Map* map,
DCHECK(!name->GetHeap()->InNewSpace(handler)); DCHECK(!name->GetHeap()->InNewSpace(handler));
DCHECK(name->IsUniqueName()); DCHECK(name->IsUniqueName());
DCHECK(name->HasHashCode()); DCHECK(name->HasHashCode());
if (handler) DCHECK(IC::IsHandler(handler)); if (handler) DCHECK(IC::IsHandler(MaybeObject::FromObject(handler)));
return true; return true;
} }
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef V8_OBJECTS_MAYBE_OBJECT_INL_H_ #ifndef V8_OBJECTS_MAYBE_OBJECT_INL_H_
#define V8_OBJECTS_MAYBE_OBJECT_INL_H_ #define V8_OBJECTS_MAYBE_OBJECT_INL_H_
#include "src/objects/maybe-object.h"
#include "include/v8.h" #include "include/v8.h"
#include "src/globals.h" #include "src/globals.h"
......
...@@ -803,7 +803,7 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) { ...@@ -803,7 +803,7 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
if (nexus.ic_state() == UNINITIALIZED) { if (nexus.ic_state() == UNINITIALIZED) {
if (name->IsUniqueName()) { if (name->IsUniqueName()) {
nexus.ConfigureMonomorphic(name, handle(object->map()), nexus.ConfigureMonomorphic(name, handle(object->map()),
Handle<Code>::null()); MaybeObjectHandle());
} else { } else {
nexus.ConfigureMegamorphic(PROPERTY); nexus.ConfigureMegamorphic(PROPERTY);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment