Commit 46134ff4 authored by ishell's avatar ishell Committed by Commit bot

[crankshaft][runtime] Initialize uninitialized double fields with hole NaN value instead of 0.0.

... and ensure that we do a full store when we overwrite uninitialized values.

This cleanup is necessary for checking that constant field tracking works as expected (once landed).

BUG=v8:5495

Review-Url: https://codereview.chromium.org/2631123002
Cr-Commit-Position: refs/heads/master@{#42369}
parent bbcb33c7
......@@ -5501,6 +5501,7 @@ void HOptimizedGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
if (info.CanAccessMonomorphic()) {
HValue* checked_literal = Add<HCheckMaps>(literal, map);
DCHECK(!info.IsAccessorConstant());
info.MarkAsInitializingStore();
store = BuildMonomorphicAccess(
&info, literal, checked_literal, value,
BailoutId::None(), BailoutId::None());
......@@ -5743,9 +5744,8 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
}
// This is a normal store.
instr = New<HStoreNamedField>(
checked_object->ActualValue(), field_access, value,
transition_to_field ? INITIALIZING_STORE : STORE_TO_INITIALIZED_ENTRY);
instr = New<HStoreNamedField>(checked_object->ActualValue(), field_access,
value, info->StoreMode());
}
if (transition_to_field) {
......
......@@ -2456,7 +2456,19 @@ class HOptimizedGraphBuilder : public HGraphBuilder,
field_type_(HType::Tagged()),
access_(HObjectAccess::ForMap()),
lookup_type_(NOT_FOUND),
details_(PropertyDetails::Empty()) {}
details_(PropertyDetails::Empty()),
store_mode_(STORE_TO_INITIALIZED_ENTRY) {}
// Ensure the full store is performed.
void MarkAsInitializingStore() {
DCHECK_EQ(STORE, access_type_);
store_mode_ = INITIALIZING_STORE;
}
StoreFieldOrKeyedMode StoreMode() {
DCHECK_EQ(STORE, access_type_);
return store_mode_;
}
// Checkes whether this PropertyAccessInfo can be handled as a monomorphic
// load named. It additionally fills in the fields necessary to generate the
......@@ -2572,6 +2584,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder,
transition_ = handle(target);
number_ = transition_->LastAdded();
details_ = transition_->instance_descriptors()->GetDetails(number_);
MarkAsInitializingStore();
}
void NotFound() {
lookup_type_ = NOT_FOUND;
......@@ -2618,6 +2631,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder,
Handle<Map> transition_;
int number_;
PropertyDetails details_;
StoreFieldOrKeyedMode store_mode_;
};
HValue* BuildMonomorphicAccess(PropertyAccessInfo* info, HValue* object,
......
......@@ -436,6 +436,12 @@ class V8_EXPORT_PRIVATE Factory final {
MutableMode mode = IMMUTABLE,
PretenureFlag pretenure = NOT_TENURED);
Handle<HeapNumber> NewMutableHeapNumber(
PretenureFlag pretenure = NOT_TENURED) {
double hole_nan = bit_cast<double>(kHoleNanInt64);
return NewHeapNumber(hole_nan, MUTABLE, pretenure);
}
#define SIMD128_NEW_DECL(TYPE, Type, type, lane_count, lane_type) \
Handle<Type> New##Type(lane_type lanes[lane_count], \
PretenureFlag pretenure = NOT_TENURED);
......
......@@ -482,6 +482,7 @@ void JsonParser<seq_one_byte>::CommitStateToJsonObject(
int length = properties->length();
for (int i = 0; i < length; i++) {
Handle<Object> value = (*properties)[i];
// Initializing store.
json_object->WriteToField(i, *value);
}
}
......
......@@ -746,13 +746,10 @@ bool Object::FilterKey(PropertyFilter filter) {
Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object,
Representation representation) {
if (representation.IsSmi() && object->IsUninitialized(isolate)) {
return handle(Smi::kZero, isolate);
}
if (!representation.IsDouble()) return object;
double value;
if (object->IsUninitialized(isolate)) {
value = 0;
value = bit_cast<double>(kHoleNanInt64);
} else if (object->IsMutableHeapNumber()) {
value = HeapNumber::cast(*object)->value();
} else {
......
......@@ -3529,7 +3529,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
FieldIndex::ForDescriptor(*new_map, new_map->LastAdded());
DCHECK(details.representation().IsDouble());
DCHECK(!new_map->IsUnboxedDoubleField(index));
Handle<Object> value = isolate->factory()->NewHeapNumber(0, MUTABLE);
Handle<Object> value = isolate->factory()->NewMutableHeapNumber();
object->RawFastPropertyAtPut(index, *value);
object->synchronized_set_map(*new_map);
return;
......@@ -3545,7 +3545,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
// Properly initialize newly added property.
Handle<Object> value;
if (details.representation().IsDouble()) {
value = isolate->factory()->NewHeapNumber(0, MUTABLE);
value = isolate->factory()->NewMutableHeapNumber();
} else {
value = isolate->factory()->uninitialized_value();
}
......@@ -3605,7 +3605,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
// must already be prepared for data of certain type.
DCHECK(!details.representation().IsNone());
if (details.representation().IsDouble()) {
value = isolate->factory()->NewHeapNumber(0, MUTABLE);
value = isolate->factory()->NewMutableHeapNumber();
} else {
value = isolate->factory()->uninitialized_value();
}
......@@ -3625,9 +3625,8 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
} else {
value = handle(object->RawFastPropertyAt(index), isolate);
if (!old_representation.IsDouble() && representation.IsDouble()) {
if (old_representation.IsNone()) {
value = handle(Smi::kZero, isolate);
}
DCHECK_IMPLIES(old_representation.IsNone(),
value->IsUninitialized(isolate));
value = Object::NewStorageFor(isolate, value, representation);
} else if (old_representation.IsDouble() &&
!representation.IsDouble()) {
......@@ -3647,7 +3646,7 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
DCHECK_EQ(kData, details.kind());
Handle<Object> value;
if (details.representation().IsDouble()) {
value = isolate->factory()->NewHeapNumber(0, MUTABLE);
value = isolate->factory()->NewMutableHeapNumber();
} else {
value = isolate->factory()->uninitialized_value();
}
......
......@@ -1595,6 +1595,7 @@ static void CommitProperties(Handle<JSObject> object, Handle<Map> map,
DisallowHeapAllocation no_gc;
DescriptorArray* descriptors = object->map()->instance_descriptors();
for (unsigned i = 0; i < properties.size(); i++) {
// Initializing store.
object->WriteToField(i, descriptors->GetDetails(i), *properties[i]);
}
}
......
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