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