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

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: 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
2323 void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) { 2334 void JSObject::RawFastDoublePropertyAtPut(FieldIndex index, double value) {
2324 WRITE_DOUBLE_FIELD(this, index.offset(), value); 2335 WRITE_DOUBLE_FIELD(this, index.offset(), value);
2325 } 2336 }
2326 2337
2338 void JSObject::RawFastDoublePropertyAsBitsAtPut(FieldIndex index,
2339 uint64_t bits) {
2340 WRITE_UINT64_FIELD(this, index.offset(), bits);
2341 }
2327 2342
2328 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) { 2343 void JSObject::FastPropertyAtPut(FieldIndex index, Object* value) {
2329 if (IsUnboxedDoubleField(index)) { 2344 if (IsUnboxedDoubleField(index)) {
2330 DCHECK(value->IsMutableHeapNumber()); 2345 DCHECK(value->IsMutableHeapNumber());
2331 RawFastDoublePropertyAtPut(index, HeapNumber::cast(value)->value()); 2346 // Ensure that all bits of the double value are preserved.
2347 RawFastDoublePropertyAsBitsAtPut(index,
2348 HeapNumber::cast(value)->value_as_bits());
2332 } else { 2349 } else {
2333 RawFastPropertyAtPut(index, value); 2350 RawFastPropertyAtPut(index, value);
2334 } 2351 }
2335 } 2352 }
2336 2353
2337 void JSObject::WriteToField(int descriptor, PropertyDetails details, 2354 void JSObject::WriteToField(int descriptor, PropertyDetails details,
2338 Object* value) { 2355 Object* value) {
2339 DCHECK_EQ(kField, details.location()); 2356 DCHECK_EQ(kField, details.location());
2340 DCHECK_EQ(kData, details.kind()); 2357 DCHECK_EQ(kData, details.kind());
2341 DisallowHeapAllocation no_gc; 2358 DisallowHeapAllocation no_gc;
2342 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); 2359 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor);
2343 if (details.representation().IsDouble()) { 2360 if (details.representation().IsDouble()) {
2344 // Nothing more to be done. 2361 // Nothing more to be done.
2345 if (value->IsUninitialized(this->GetIsolate())) { 2362 if (value->IsUninitialized(this->GetIsolate())) {
2346 return; 2363 return;
2347 } 2364 }
2365 // Manipulating the signaling NaN used for the hole and uninitialized
2366 // double field sentinel in C++, e.g. with bit_cast or value()/set_value(),
2367 // will change its value on ia32 (the x87 stack is used to return values
2368 // and stores to the stack silently clear the signalling bit).
2369 // However, since this method is not used for pre-initializing double fields
2370 // with uninitialized sentinel (represented as kHoleNanInt64 bit pattern)
2371 // we use normal double setters here.
Jakob Kummerow 2017/01/23 15:07:10 How about: DCHECK(!value->IsHeapNumber() ||
Igor Sheludko 2017/01/23 16:29:49 The kHoleNanInt64 value can be constructed using t
2348 if (IsUnboxedDoubleField(index)) { 2372 if (IsUnboxedDoubleField(index)) {
2349 RawFastDoublePropertyAtPut(index, value->Number()); 2373 RawFastDoublePropertyAtPut(index, value->Number());
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(value->Number());
2354 } 2378 }
2355 } else { 2379 } else {
2356 RawFastPropertyAtPut(index, value); 2380 RawFastPropertyAtPut(index, value);
2357 } 2381 }
(...skipping 6060 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