[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:
Marja Hölttä 2018-05-15 09:33:12 +02:00 committed by Commit Bot
parent c79feb8aa3
commit 6c78bd9a1e
10 changed files with 77 additions and 48 deletions

View File

@ -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)),

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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())) ||

View File

@ -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());

View File

@ -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,

View File

@ -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;
}