[in-place weak refs] Replace PropertyCell handlers in FeedbackVector.
BUG=v8:7308 Change-Id: I7720dbc84ce3e614f025759224e2d8d7ffa7a952 Reviewed-on: https://chromium-review.googlesource.com/1052013 Commit-Queue: Marja Hölttä <marja@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#53178}
This commit is contained in:
parent
c79feb8aa3
commit
6c78bd9a1e
@ -1768,6 +1768,12 @@ TNode<HeapObject> CodeStubAssembler::ToWeakHeapObject(
|
||||
BitcastMaybeObjectToWord(value), IntPtrConstant(~kWeakHeapObjectMask))));
|
||||
}
|
||||
|
||||
TNode<HeapObject> CodeStubAssembler::ToWeakHeapObject(TNode<MaybeObject> value,
|
||||
Label* if_cleared) {
|
||||
GotoIf(IsClearedWeakHeapObject(value), if_cleared);
|
||||
return ToWeakHeapObject(value);
|
||||
}
|
||||
|
||||
TNode<BoolT> CodeStubAssembler::IsObject(TNode<MaybeObject> value) {
|
||||
return WordNotEqual(WordAnd(BitcastMaybeObjectToWord(value),
|
||||
IntPtrConstant(kHeapObjectTagMask)),
|
||||
|
@ -685,6 +685,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
||||
// Removes the weak bit + asserts it was set.
|
||||
TNode<HeapObject> ToWeakHeapObject(TNode<MaybeObject> value);
|
||||
|
||||
TNode<HeapObject> ToWeakHeapObject(TNode<MaybeObject> value,
|
||||
Label* if_cleared);
|
||||
|
||||
// IsObject == true when the MaybeObject is a strong HeapObject or a smi.
|
||||
TNode<BoolT> IsObject(TNode<MaybeObject> value);
|
||||
// This variant is for overzealous checking.
|
||||
|
@ -792,7 +792,7 @@ void AccessorAssembler::HandleStoreICHandlerCase(
|
||||
ICMode ic_mode, ElementSupport support_elements) {
|
||||
Label if_smi_handler(this), if_nonsmi_handler(this);
|
||||
Label if_proto_handler(this), if_element_handler(this), call_handler(this),
|
||||
store_transition(this), store_global(this);
|
||||
store_transition_or_global(this);
|
||||
|
||||
Branch(TaggedIsSmi(handler), &if_smi_handler, &if_nonsmi_handler);
|
||||
|
||||
@ -866,38 +866,48 @@ void AccessorAssembler::HandleStoreICHandlerCase(
|
||||
|
||||
BIND(&if_nonsmi_handler);
|
||||
{
|
||||
GotoIf(IsClearedWeakHeapObject(handler), miss);
|
||||
GotoIf(IsWeakOrClearedHeapObject(handler), &store_transition);
|
||||
Node* handler_map = LoadMap(ToStrongHeapObject(handler));
|
||||
GotoIf(IsWeakCellMap(handler_map), &store_global);
|
||||
GotoIf(IsWeakOrClearedHeapObject(handler), &store_transition_or_global);
|
||||
TNode<HeapObject> strong_handler = ToStrongHeapObject(handler);
|
||||
TNode<Map> handler_map = LoadMap(strong_handler);
|
||||
Branch(IsCodeMap(handler_map), &call_handler, &if_proto_handler);
|
||||
|
||||
BIND(&if_proto_handler);
|
||||
{
|
||||
HandleStoreICProtoHandler(p, CAST(strong_handler), miss, ic_mode,
|
||||
support_elements);
|
||||
}
|
||||
|
||||
// |handler| is a heap object. Must be code, call it.
|
||||
BIND(&call_handler);
|
||||
{
|
||||
StoreWithVectorDescriptor descriptor(isolate());
|
||||
TailCallStub(descriptor, strong_handler, p->context, p->receiver, p->name,
|
||||
p->value, p->slot, p->vector);
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&if_proto_handler);
|
||||
HandleStoreICProtoHandler(p, handler, miss, ic_mode, support_elements);
|
||||
|
||||
// |handler| is a heap object. Must be code, call it.
|
||||
BIND(&call_handler);
|
||||
{
|
||||
StoreWithVectorDescriptor descriptor(isolate());
|
||||
TailCallStub(descriptor, handler, p->context, p->receiver, p->name,
|
||||
p->value, p->slot, p->vector);
|
||||
}
|
||||
|
||||
BIND(&store_transition);
|
||||
{
|
||||
TNode<Map> map = CAST(ToWeakHeapObject(handler));
|
||||
HandleStoreICTransitionMapHandlerCase(p, map, miss, false);
|
||||
Return(p->value);
|
||||
}
|
||||
|
||||
BIND(&store_global);
|
||||
BIND(&store_transition_or_global);
|
||||
{
|
||||
// Load value or miss if the {handler} weak cell is cleared.
|
||||
TNode<PropertyCell> property_cell =
|
||||
CAST(LoadWeakCellValue(CAST(ToStrongHeapObject(handler)), miss));
|
||||
ExitPoint direct_exit(this);
|
||||
StoreGlobalIC_PropertyCellCase(property_cell, p->value, &direct_exit, miss);
|
||||
CSA_ASSERT(this, IsWeakOrClearedHeapObject(handler));
|
||||
TNode<HeapObject> map_or_property_cell = ToWeakHeapObject(handler, miss);
|
||||
|
||||
Label store_global(this), store_transition(this);
|
||||
Branch(IsMap(map_or_property_cell), &store_transition, &store_global);
|
||||
|
||||
BIND(&store_global);
|
||||
{
|
||||
TNode<PropertyCell> property_cell = CAST(map_or_property_cell);
|
||||
ExitPoint direct_exit(this);
|
||||
StoreGlobalIC_PropertyCellCase(property_cell, p->value, &direct_exit,
|
||||
miss);
|
||||
}
|
||||
BIND(&store_transition);
|
||||
{
|
||||
TNode<Map> map = CAST(map_or_property_cell);
|
||||
HandleStoreICTransitionMapHandlerCase(p, map, miss, false);
|
||||
Return(p->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1190,8 +1200,8 @@ void AccessorAssembler::HandleStoreAccessor(const StoreICParameters* p,
|
||||
}
|
||||
|
||||
void AccessorAssembler::HandleStoreICProtoHandler(
|
||||
const StoreICParameters* p, Node* handler, Label* miss, ICMode ic_mode,
|
||||
ElementSupport support_elements) {
|
||||
const StoreICParameters* p, TNode<StoreHandler> handler, Label* miss,
|
||||
ICMode ic_mode, ElementSupport support_elements) {
|
||||
Comment("HandleStoreICProtoHandler");
|
||||
|
||||
OnCodeHandler on_code_handler;
|
||||
@ -2841,7 +2851,9 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) {
|
||||
GotoIfNot(IsWeakCell(handler), &if_handler);
|
||||
|
||||
TNode<HeapObject> value = CAST(LoadWeakCellValue(CAST(handler), &miss));
|
||||
GotoIfNot(IsMap(value), &if_handler);
|
||||
TNode<Map> value_map = LoadMap(value);
|
||||
GotoIfNot(Word32Or(IsMetaMap(value_map), IsPropertyCellMap(value_map)),
|
||||
&if_handler);
|
||||
|
||||
TNode<MaybeObject> weak_handler = MakeWeak(value);
|
||||
HandleStoreICHandlerCase(p, weak_handler, &miss, ICMode::kNonGlobalIC);
|
||||
|
@ -204,8 +204,9 @@ class AccessorAssembler : public CodeStubAssembler {
|
||||
|
||||
// StoreIC implementation.
|
||||
|
||||
void HandleStoreICProtoHandler(const StoreICParameters* p, Node* handler,
|
||||
Label* miss, ICMode ic_mode,
|
||||
void HandleStoreICProtoHandler(const StoreICParameters* p,
|
||||
TNode<StoreHandler> handler, Label* miss,
|
||||
ICMode ic_mode,
|
||||
ElementSupport support_elements);
|
||||
void HandleStoreICSmiHandlerCase(Node* handler_word, Node* holder,
|
||||
Node* value, Label* miss);
|
||||
|
@ -269,9 +269,9 @@ Handle<Object> StoreHandler::StoreThroughPrototype(
|
||||
}
|
||||
|
||||
// static
|
||||
Handle<Object> StoreHandler::StoreGlobal(Isolate* isolate,
|
||||
Handle<PropertyCell> cell) {
|
||||
return isolate->factory()->NewWeakCell(cell);
|
||||
MaybeObjectHandle StoreHandler::StoreGlobal(Isolate* isolate,
|
||||
Handle<PropertyCell> cell) {
|
||||
return MaybeObjectHandle::Weak(cell);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -280,8 +280,8 @@ class StoreHandler final : public DataHandler {
|
||||
|
||||
// Creates a handler for storing a property to the property cell of a global
|
||||
// object.
|
||||
static Handle<Object> StoreGlobal(Isolate* isolate,
|
||||
Handle<PropertyCell> cell);
|
||||
static MaybeObjectHandle StoreGlobal(Isolate* isolate,
|
||||
Handle<PropertyCell> cell);
|
||||
|
||||
// Creates a Smi-handler for storing a property to a global proxy object.
|
||||
static inline Handle<Smi> StoreGlobalProxy(Isolate* isolate);
|
||||
|
@ -39,13 +39,14 @@ Address IC::raw_constant_pool() const {
|
||||
}
|
||||
}
|
||||
|
||||
bool IC::IsHandler(MaybeObject* object) {
|
||||
bool IC::IsHandler(MaybeObject* object, bool from_stub_cache) {
|
||||
HeapObject* heap_object;
|
||||
return (object->IsSmi() && (object != nullptr)) ||
|
||||
(object->ToWeakHeapObject(&heap_object) && heap_object->IsMap()) ||
|
||||
(object->ToWeakHeapObject(&heap_object) &&
|
||||
(heap_object->IsMap() || heap_object->IsPropertyCell())) ||
|
||||
(object->ToStrongHeapObject(&heap_object) &&
|
||||
(heap_object->IsDataHandler() ||
|
||||
(heap_object->IsWeakCell() &&
|
||||
(from_stub_cache && heap_object->IsWeakCell() &&
|
||||
(WeakCell::cast(heap_object)->cleared() ||
|
||||
WeakCell::cast(heap_object)->value()->IsMap() ||
|
||||
WeakCell::cast(heap_object)->value()->IsPropertyCell())) ||
|
||||
|
15
src/ic/ic.cc
15
src/ic/ic.cc
@ -734,11 +734,16 @@ StubCache* IC::stub_cache() {
|
||||
void IC::UpdateMegamorphicCache(Handle<Map> map, Handle<Name> name,
|
||||
const MaybeObjectHandle& handler) {
|
||||
HeapObject* heap_object;
|
||||
if (handler->ToWeakHeapObject(&heap_object) && heap_object->IsMap()) {
|
||||
if (handler->ToWeakHeapObject(&heap_object)) {
|
||||
// TODO(marja): remove this conversion once megamorphic stub cache supports
|
||||
// weak handlers.
|
||||
Handle<Object> weak_cell =
|
||||
Map::WeakCellForMap(handle(Map::cast(heap_object)));
|
||||
Handle<Object> weak_cell;
|
||||
if (heap_object->IsMap()) {
|
||||
weak_cell = Map::WeakCellForMap(handle(Map::cast(heap_object)));
|
||||
} else {
|
||||
weak_cell = isolate_->factory()->NewWeakCell(
|
||||
handle(PropertyCell::cast(heap_object)));
|
||||
}
|
||||
stub_cache()->Set(*name, *map, *weak_cell);
|
||||
} else {
|
||||
stub_cache()->Set(*name, *map, handler->ToObject());
|
||||
@ -1500,8 +1505,8 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) {
|
||||
DCHECK_EQ(*lookup->GetReceiver(), *holder);
|
||||
DCHECK_EQ(*store_target, *holder);
|
||||
#endif
|
||||
return MaybeObjectHandle(
|
||||
StoreHandler::StoreGlobal(isolate(), lookup->transition_cell()));
|
||||
return StoreHandler::StoreGlobal(isolate(),
|
||||
lookup->transition_cell());
|
||||
}
|
||||
|
||||
Handle<Smi> smi_handler = StoreHandler::StoreGlobalProxy(isolate());
|
||||
|
@ -64,7 +64,8 @@ class IC {
|
||||
IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind());
|
||||
}
|
||||
|
||||
static inline bool IsHandler(MaybeObject* object);
|
||||
static inline bool IsHandler(MaybeObject* object,
|
||||
bool from_stub_cache = false);
|
||||
|
||||
// Nofity the IC system that a feedback has changed.
|
||||
static void OnFeedbackChanged(Isolate* isolate, FeedbackVector* vector,
|
||||
|
@ -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(MaybeObject::FromObject(handler)));
|
||||
if (handler) DCHECK(IC::IsHandler(MaybeObject::FromObject(handler), true));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user