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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « src/objects.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Review notes: 5 // Review notes:
6 // 6 //
7 // - The use of macros in these inline functions may seem superfluous 7 // - The use of macros in these inline functions may seem superfluous
8 // but it is absolutely needed to make sure gcc generates optimal 8 // but it is absolutely needed to make sure gcc generates optimal
9 // code. gcc is not happy when attempting to inline too deep. 9 // code. gcc is not happy when attempting to inline too deep.
10 // 10 //
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 if (Symbol::cast(this)->is_private()) return true; 750 if (Symbol::cast(this)->is_private()) return true;
751 } else { 751 } else {
752 if (filter & SKIP_STRINGS) return true; 752 if (filter & SKIP_STRINGS) return true;
753 } 753 }
754 return false; 754 return false;
755 } 755 }
756 756
757 Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object, 757 Handle<Object> Object::NewStorageFor(Isolate* isolate, Handle<Object> object,
758 Representation representation) { 758 Representation representation) {
759 if (!representation.IsDouble()) return object; 759 if (!representation.IsDouble()) return object;
760 double value; 760 Handle<HeapNumber> result = isolate->factory()->NewHeapNumber(MUTABLE);
761 if (object->IsUninitialized(isolate)) { 761 if (object->IsUninitialized(isolate)) {
762 value = bit_cast<double>(kHoleNanInt64); 762 result->set_value_as_bits(kHoleNanInt64);
763 } else if (object->IsMutableHeapNumber()) { 763 } else if (object->IsMutableHeapNumber()) {
764 value = HeapNumber::cast(*object)->value(); 764 // Ensure that all bits of the double value are preserved.
765 result->set_value_as_bits(HeapNumber::cast(*object)->value_as_bits());
765 } else { 766 } else {
766 value = object->Number(); 767 result->set_value(object->Number());
767 } 768 }
768 return isolate->factory()->NewHeapNumber(value, MUTABLE); 769 return result;
769 } 770 }
770 771
771 Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object, 772 Handle<Object> Object::WrapForRead(Isolate* isolate, Handle<Object> object,
772 Representation representation) { 773 Representation representation) {
773 DCHECK(!object->IsUninitialized(isolate)); 774 DCHECK(!object->IsUninitialized(isolate));
774 if (!representation.IsDouble()) { 775 if (!representation.IsDouble()) {
775 DCHECK(object->FitsRepresentation(representation)); 776 DCHECK(object->FitsRepresentation(representation));
776 return object; 777 return object;
777 } 778 }
778 return isolate->factory()->NewHeapNumber(HeapNumber::cast(*object)->value()); 779 return isolate->factory()->NewHeapNumber(HeapNumber::cast(*object)->value());
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 1551
1551 double HeapNumber::value() const { 1552 double HeapNumber::value() const {
1552 return READ_DOUBLE_FIELD(this, kValueOffset); 1553 return READ_DOUBLE_FIELD(this, kValueOffset);
1553 } 1554 }
1554 1555
1555 1556
1556 void HeapNumber::set_value(double value) { 1557 void HeapNumber::set_value(double value) {
1557 WRITE_DOUBLE_FIELD(this, kValueOffset, value); 1558 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1558 } 1559 }
1559 1560
1561 uint64_t HeapNumber::value_as_bits() const {
1562 return READ_UINT64_FIELD(this, kValueOffset);
1563 }
1564
1565 void HeapNumber::set_value_as_bits(uint64_t bits) {
1566 WRITE_UINT64_FIELD(this, kValueOffset, bits);
1567 }
1560 1568
1561 int HeapNumber::get_exponent() { 1569 int HeapNumber::get_exponent() {
1562 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >> 1570 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1563 kExponentShift) - kExponentBias; 1571 kExponentShift) - kExponentBias;
1564 } 1572 }
1565 1573
1566 1574
1567 int HeapNumber::get_sign() { 1575 int HeapNumber::get_sign() {
1568 return READ_INT_FIELD(this, kExponentOffset) & kSignMask; 1576 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1569 } 1577 }
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
2301 return properties()->get(index.outobject_array_index()); 2309 return properties()->get(index.outobject_array_index());
2302 } 2310 }
2303 } 2311 }
2304 2312
2305 2313
2306 double JSObject::RawFastDoublePropertyAt(FieldIndex index) { 2314 double JSObject::RawFastDoublePropertyAt(FieldIndex index) {
2307 DCHECK(IsUnboxedDoubleField(index)); 2315 DCHECK(IsUnboxedDoubleField(index));
2308 return READ_DOUBLE_FIELD(this, index.offset()); 2316 return READ_DOUBLE_FIELD(this, index.offset());
2309 } 2317 }
2310 2318
2319 uint64_t JSObject::RawFastDoublePropertyAsBitsAt(FieldIndex index) {
2320 DCHECK(IsUnboxedDoubleField(index));
2321 return READ_UINT64_FIELD(this, index.offset());
2322 }
2311 2323
2312 void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) { 2324 void JSObject::RawFastPropertyAtPut(FieldIndex index, Object* value) {
2313 if (index.is_inobject()) { 2325 if (index.is_inobject()) {
2314 int offset = index.offset(); 2326 int offset = index.offset();
2315 WRITE_FIELD(this, offset, value); 2327 WRITE_FIELD(this, offset, value);
2316 WRITE_BARRIER(GetHeap(), this, offset, value); 2328 WRITE_BARRIER(GetHeap(), this, offset, value);
2317 } else { 2329 } else {
2318 properties()->set(index.outobject_array_index(), value); 2330 properties()->set(index.outobject_array_index(), value);
2319 } 2331 }
2320 } 2332 }
2321 2333
2322 2334 void JSObject::RawFastDoublePropertyAsBitsAtPut(FieldIndex index,
2323 void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) { 2335 uint64_t bits) {
2324 WRITE_DOUBLE_FIELD(this, index.offset(), value); 2336 WRITE_UINT64_FIELD(this, index.offset(), bits);
2325 } 2337 }
2326 2338
2327
2328 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) { 2339 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
2329 if (IsUnboxedDoubleField(index)) { 2340 if (IsUnboxedDoubleField(index)) {
2330 DCHECK(value->IsMutableHeapNumber()); 2341 DCHECK(value->IsMutableHeapNumber());
2331 RawFastDoublePropertyAtPut(index, HeapNumber::cast(value)->value()); 2342 // Ensure that all bits of the double value are preserved.
2343 RawFastDoublePropertyAsBitsAtPut(index,
2344 HeapNumber::cast(value)->value_as_bits());
2332 } else { 2345 } else {
2333 RawFastPropertyAtPut(index, value); 2346 RawFastPropertyAtPut(index, value);
2334 } 2347 }
2335 } 2348 }
2336 2349
2337 void JSObject::WriteToField(int descriptor, PropertyDetails details, 2350 void JSObject::WriteToField(int descriptor, PropertyDetails details,
2338 Object* value) { 2351 Object* value) {
2339 DCHECK_EQ(kField, details.location()); 2352 DCHECK_EQ(kField, details.location());
2340 DCHECK_EQ(kData, details.kind()); 2353 DCHECK_EQ(kData, details.kind());
2341 DisallowHeapAllocation no_gc; 2354 DisallowHeapAllocation no_gc;
2342 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); 2355 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor);
2343 if (details.representation().IsDouble()) { 2356 if (details.representation().IsDouble()) {
2344 // Nothing more to be done. 2357 // Nothing more to be done.
2345 if (value->IsUninitialized(this->GetIsolate())) { 2358 if (value->IsUninitialized(this->GetIsolate())) {
2346 return; 2359 return;
2347 } 2360 }
2361 // Manipulating the signaling NaN used for the hole and uninitialized
2362 // double field sentinel in C++, e.g. with bit_cast or value()/set_value(),
2363 // will change its value on ia32 (the x87 stack is used to return values
2364 // and stores to the stack silently clear the signalling bit).
2365 uint64_t bits;
2366 if (value->IsSmi()) {
2367 bits = bit_cast<uint64_t>(static_cast<double>(Smi::cast(value)->value()));
2368 } else {
2369 DCHECK(value->IsHeapNumber());
2370 bits = HeapNumber::cast(value)->value_as_bits();
2371 }
2348 if (IsUnboxedDoubleField(index)) { 2372 if (IsUnboxedDoubleField(index)) {
2349 RawFastDoublePropertyAtPut(index, value->Number()); 2373 RawFastDoublePropertyAsBitsAtPut(index, bits);
2350 } else { 2374 } else {
2351 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); 2375 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index));
2352 DCHECK(box->IsMutableHeapNumber()); 2376 DCHECK(box->IsMutableHeapNumber());
2353 box->set_value(value->Number()); 2377 box->set_value_as_bits(bits);
2354 } 2378 }
2355 } else { 2379 } else {
2356 RawFastPropertyAtPut(index, value); 2380 RawFastPropertyAtPut(index, value);
2357 } 2381 }
2358 } 2382 }
2359 2383
2360 int JSObject::GetInObjectPropertyOffset(int index) { 2384 int JSObject::GetInObjectPropertyOffset(int index) {
2361 return map()->GetInObjectPropertyOffset(index); 2385 return map()->GetInObjectPropertyOffset(index);
2362 } 2386 }
2363 2387
(...skipping 6054 matching lines...) Expand 10 before | Expand all | Expand 10 after
8418 #undef WRITE_INT64_FIELD 8442 #undef WRITE_INT64_FIELD
8419 #undef READ_BYTE_FIELD 8443 #undef READ_BYTE_FIELD
8420 #undef WRITE_BYTE_FIELD 8444 #undef WRITE_BYTE_FIELD
8421 #undef NOBARRIER_READ_BYTE_FIELD 8445 #undef NOBARRIER_READ_BYTE_FIELD
8422 #undef NOBARRIER_WRITE_BYTE_FIELD 8446 #undef NOBARRIER_WRITE_BYTE_FIELD
8423 8447
8424 } // namespace internal 8448 } // namespace internal
8425 } // namespace v8 8449 } // namespace v8
8426 8450
8427 #endif // V8_OBJECTS_INL_H_ 8451 #endif // V8_OBJECTS_INL_H_
OLDNEW
« 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