| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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_ |
| OLD | NEW |