Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(802)

Unified Diff: src/objects-inl.h

Issue 2652553003: Access double fields in C++ as uint64_t fields to preserve signaling bit of a NaN. (Closed)
Patch Set: More fixes Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index c09dfe4db879fb451b3aa09f97a92909e60bb0b1..6ec82ad9c514496ad48f89ba7634d7aa61a8d228 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -757,15 +757,16 @@ bool Object::FilterKey(PropertyFilter filter) {
Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object,
Representation representation) {
if (!representation.IsDouble()) return object;
- double value;
+ Handle<HeapNumber> result = isolate->factory()->NewHeapNumber(MUTABLE);
if (object->IsUninitialized(isolate)) {
- value = bit_cast<double>(kHoleNanInt64);
+ result->set_value_as_bits(kHoleNanInt64);
} else if (object->IsMutableHeapNumber()) {
- value = HeapNumber::cast(*object)->value();
+ // Ensure that all bits of the double value are preserved.
+ result->set_value_as_bits(HeapNumber::cast(*object)->value_as_bits());
} else {
- value = object->Number();
+ result->set_value(object->Number());
}
- return isolate->factory()->NewHeapNumber(value, MUTABLE);
+ return result;
}
Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object,
@@ -1557,6 +1558,13 @@ void HeapNumber::set_value(double value) {
WRITE_DOUBLE_FIELD(this, kValueOffset, value);
}
+uint64_t HeapNumber::value_as_bits() const {
+ return READ_UINT64_FIELD(this, kValueOffset);
+}
+
+void HeapNumber::set_value_as_bits(uint64_t bits) {
+ WRITE_UINT64_FIELD(this, kValueOffset, bits);
+}
int HeapNumber::get_exponent() {
return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
@@ -2308,6 +2316,10 @@ double JSObject::RawFastDoublePropertyAt(FieldIndex index) {
return READ_DOUBLE_FIELD(this, index.offset());
}
+uint64_t JSObject::RawFastDoublePropertyAsBitsAt(FieldIndex index) {
+ DCHECK(IsUnboxedDoubleField(index));
+ return READ_UINT64_FIELD(this, index.offset());
+}
void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) {
if (index.is_inobject()) {
@@ -2319,16 +2331,17 @@ void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) {
}
}
-
-void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) {
- WRITE_DOUBLE_FIELD(this, index.offset(), value);
+void JSObject::RawFastDoublePropertyAsBitsAtPut(FieldIndex index,
+ uint64_t bits) {
+ WRITE_UINT64_FIELD(this, index.offset(), bits);
}
-
void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
if (IsUnboxedDoubleField(index)) {
DCHECK(value->IsMutableHeapNumber());
- RawFastDoublePropertyAtPut(index, HeapNumber::cast(value)->value());
+ // Ensure that all bits of the double value are preserved.
+ RawFastDoublePropertyAsBitsAtPut(index,
+ HeapNumber::cast(value)->value_as_bits());
} else {
RawFastPropertyAtPut(index, value);
}
@@ -2345,12 +2358,23 @@ void JSObject::WriteToField(int descriptor, PropertyDetails details,
if (value->IsUninitialized(this->GetIsolate())) {
return;
}
+ // Manipulating the signaling NaN used for the hole and uninitialized
+ // double field sentinel in C++, e.g. with bit_cast or value()/set_value(),
+ // will change its value on ia32 (the x87 stack is used to return values
+ // and stores to the stack silently clear the signalling bit).
+ uint64_t bits;
+ if (value->IsSmi()) {
+ bits = bit_cast<uint64_t>(static_cast<double>(Smi::cast(value)->value()));
+ } else {
+ DCHECK(value->IsHeapNumber());
+ bits = HeapNumber::cast(value)->value_as_bits();
+ }
if (IsUnboxedDoubleField(index)) {
- RawFastDoublePropertyAtPut(index, value->Number());
+ RawFastDoublePropertyAsBitsAtPut(index, bits);
} else {
HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
DCHECK(box->IsMutableHeapNumber());
- box->set_value(value->Number());
+ box->set_value_as_bits(bits);
}
} else {
RawFastPropertyAtPut(index, value);
« no previous file with comments | « src/objects.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698