template <>
HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
StoreGlobalStub* stub = casted_stub();
- Handle<Object> placeholer_value(Smi::FromInt(0), isolate());
- Handle<PropertyCell> placeholder_cell =
- isolate()->factory()->NewPropertyCell(placeholer_value);
HParameter* value = GetParameter(StoreDescriptor::kValueIndex);
if (stub->check_global()) {
// Check that the map of the global has not changed: use a placeholder map
map_check.End();
}
- HValue* cell = Add<HConstant>(placeholder_cell);
+ HValue* weak_cell = Add<HConstant>(isolate()->factory()->NewWeakCell(
+ StoreGlobalStub::property_cell_placeholder(isolate())));
+ HValue* cell = Add<HLoadNamedField>(weak_cell, nullptr,
+ HObjectAccess::ForWeakCellValue());
HObjectAccess access(HObjectAccess::ForCellPayload(isolate()));
HValue* cell_contents = Add<HLoadNamedField>(cell, nullptr, access);
builder.Then();
builder.Deopt("Unexpected cell contents in global store");
builder.Else();
- Add<HStoreNamedField>(cell, access, value);
+ HStoreNamedField* store = Add<HStoreNamedField>(cell, access, value);
+ store->MarkReceiverAsCell();
builder.End();
}
CheckGlobalBits::encode(check_global));
}
- static Handle<HeapObject> global_placeholder(Isolate* isolate) {
+ static Handle<HeapObject> property_cell_placeholder(Isolate* isolate) {
return isolate->factory()->uninitialized_value();
}
Code::FindAndReplacePattern pattern;
pattern.Add(isolate()->factory()->meta_map(),
Map::WeakCellForMap(Handle<Map>(global->map())));
- pattern.Add(isolate()->factory()->global_property_cell_map(), cell);
+ pattern.Add(Handle<Map>(property_cell_placeholder(isolate())->map()),
+ isolate()->factory()->NewWeakCell(cell));
return CodeStub::GetCodeCopy(pattern);
} else {
Code::FindAndReplacePattern pattern;
- pattern.Add(isolate()->factory()->global_property_cell_map(), cell);
+ pattern.Add(Handle<Map>(property_cell_placeholder(isolate())->map()),
+ isolate()->factory()->NewWeakCell(cell));
return CodeStub::GetCodeCopy(pattern);
}
}
SetChangesFlag(kMaps);
}
+ void MarkReceiverAsCell() {
+ bit_field_ = ReceiverIsCellField::update(bit_field_, true);
+ }
+
+ bool receiver_is_cell() const {
+ return ReceiverIsCellField::decode(bit_field_);
+ }
+
bool NeedsWriteBarrier() const {
DCHECK(!field_representation().IsDouble() ||
(FLAG_unbox_double_fields && access_.IsInobject()) ||
if (field_representation().IsSmi()) return false;
if (field_representation().IsInteger32()) return false;
if (field_representation().IsExternal()) return false;
+ if (receiver_is_cell()) return false;
return StoringValueNeedsWriteBarrier(value()) &&
ReceiverObjectNeedsWriteBarrier(object(), value(), dominator());
}
class HasTransitionField : public BitField<bool, 0, 1> {};
class StoreModeField : public BitField<StoreFieldOrKeyedMode, 1, 1> {};
+ class ReceiverIsCellField : public BitField<bool, 2, 1> {};
HObjectAccess access_;
HValue* dominator_;
// function replaces the corresponding placeholder in the code with the
// object-to-replace. The function assumes that pairs in the pattern come in
// the same order as the placeholders in the code.
+ // If the placeholder is a weak cell, then the value of weak cell is matched
+ // against the map-to-find.
void FindAndReplace(const FindAndReplacePattern& pattern);
// The entire code object including its header is copied verbatim to the