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

Side by Side Diff: src/objects-inl.h

Issue 7089002: Implement core support for FixedDoubleArrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: tweaks Created 9 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 String::cast(this)->IsAsciiRepresentation(); 210 String::cast(this)->IsAsciiRepresentation();
211 } 211 }
212 212
213 213
214 bool Object::IsExternalTwoByteString() { 214 bool Object::IsExternalTwoByteString() {
215 if (!IsString()) return false; 215 if (!IsString()) return false;
216 return StringShape(String::cast(this)).IsExternal() && 216 return StringShape(String::cast(this)).IsExternal() &&
217 String::cast(this)->IsTwoByteRepresentation(); 217 String::cast(this)->IsTwoByteRepresentation();
218 } 218 }
219 219
220 bool Object::HasValidElements() {
221 // Dictionary is covered under FixedArray.
222 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
223 }
220 224
221 StringShape::StringShape(String* str) 225 StringShape::StringShape(String* str)
222 : type_(str->map()->instance_type()) { 226 : type_(str->map()->instance_type()) {
223 set_valid(); 227 set_valid();
224 ASSERT((type_ & kIsNotStringMask) == kStringTag); 228 ASSERT((type_ & kIsNotStringMask) == kStringTag);
225 } 229 }
226 230
227 231
228 StringShape::StringShape(Map* map) 232 StringShape::StringShape(Map* map)
229 : type_(map->instance_type()) { 233 : type_(map->instance_type()) {
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE; 486 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
483 } 487 }
484 488
485 489
486 bool Object::IsFixedArray() { 490 bool Object::IsFixedArray() {
487 return Object::IsHeapObject() 491 return Object::IsHeapObject()
488 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE; 492 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
489 } 493 }
490 494
491 495
496 bool Object::IsFixedDoubleArray() {
497 return Object::IsHeapObject()
498 && HeapObject::cast(this)->map()->instance_type() ==
499 FIXED_DOUBLE_ARRAY_TYPE;
500 }
501
502
492 bool Object::IsDescriptorArray() { 503 bool Object::IsDescriptorArray() {
493 return IsFixedArray(); 504 return IsFixedArray();
494 } 505 }
495 506
496 507
497 bool Object::IsDeoptimizationInputData() { 508 bool Object::IsDeoptimizationInputData() {
498 // Must be a fixed array. 509 // Must be a fixed array.
499 if (!IsFixedArray()) return false; 510 if (!IsFixedArray()) return false;
500 511
501 // There's no sure way to detect the difference between a fixed array and 512 // There's no sure way to detect the difference between a fixed array and
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 int HeapNumber::get_sign() { 1317 int HeapNumber::get_sign() {
1307 return READ_INT_FIELD(this, kExponentOffset) & kSignMask; 1318 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1308 } 1319 }
1309 1320
1310 1321
1311 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) 1322 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
1312 1323
1313 1324
1314 HeapObject* JSObject::elements() { 1325 HeapObject* JSObject::elements() {
1315 Object* array = READ_FIELD(this, kElementsOffset); 1326 Object* array = READ_FIELD(this, kElementsOffset);
1316 // In the assert below Dictionary is covered under FixedArray. 1327 ASSERT(array->HasValidElements());
1317 ASSERT(array->IsFixedArray() || array->IsExternalArray());
1318 return reinterpret_cast<HeapObject*>(array); 1328 return reinterpret_cast<HeapObject*>(array);
1319 } 1329 }
1320 1330
1321 1331
1322 void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) { 1332 void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
1323 ASSERT(map()->has_fast_elements() == 1333 ASSERT(map()->has_fast_elements() ==
1324 (value->map() == GetHeap()->fixed_array_map() || 1334 (value->map() == GetHeap()->fixed_array_map() ||
1325 value->map() == GetHeap()->fixed_cow_array_map())); 1335 value->map() == GetHeap()->fixed_cow_array_map()));
1326 // In the assert below Dictionary is covered under FixedArray. 1336 ASSERT(value->HasValidElements());
1327 ASSERT(value->IsFixedArray() || value->IsExternalArray());
1328 WRITE_FIELD(this, kElementsOffset, value); 1337 WRITE_FIELD(this, kElementsOffset, value);
1329 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode); 1338 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
1330 } 1339 }
1331 1340
1332 1341
1333 void JSObject::initialize_properties() { 1342 void JSObject::initialize_properties() {
1334 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 1343 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1335 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); 1344 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
1336 } 1345 }
1337 1346
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 1597
1589 void FixedArray::set(int index, Object* value) { 1598 void FixedArray::set(int index, Object* value) {
1590 ASSERT(map() != HEAP->fixed_cow_array_map()); 1599 ASSERT(map() != HEAP->fixed_cow_array_map());
1591 ASSERT(index >= 0 && index < this->length()); 1600 ASSERT(index >= 0 && index < this->length());
1592 int offset = kHeaderSize + index * kPointerSize; 1601 int offset = kHeaderSize + index * kPointerSize;
1593 WRITE_FIELD(this, offset, value); 1602 WRITE_FIELD(this, offset, value);
1594 WRITE_BARRIER(this, offset); 1603 WRITE_BARRIER(this, offset);
1595 } 1604 }
1596 1605
1597 1606
1607 int FixedDoubleArray::length() {
Mads Ager (chromium) 2011/06/06 07:58:23 For length you can use use the INT_ACCESSORS macro
danno 2011/06/08 12:09:43 Done.
1608 return READ_INT_FIELD(this, kLengthOffset);
1609 }
1610
1611
1612 void FixedDoubleArray::set_length(int length) {
1613 WRITE_INT_FIELD(this, kLengthOffset, length);
1614 }
1615
1616
1617 double FixedDoubleArray::get(int index) {
1618 ASSERT(index >= 0 && index < this->length());
1619 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1620 ASSERT(!is_the_hole_nan(result));
1621 return result;
1622 }
1623
1624
1625 void FixedDoubleArray::set(int index, double value) {
1626 ASSERT(map() != HEAP->fixed_cow_array_map());
1627 int offset = kHeaderSize + index * kDoubleSize;
1628 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1629 WRITE_DOUBLE_FIELD(this, offset, value);
1630 }
1631
1632
1633 void FixedDoubleArray::set_the_hole(int index) {
1634 ASSERT(map() != HEAP->fixed_cow_array_map());
1635 int offset = kHeaderSize + index * kDoubleSize;
1636 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1637 }
1638
1639
1640 bool FixedDoubleArray::is_the_hole(int index) {
1641 int offset = kHeaderSize + index * kDoubleSize;
1642 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1643 }
1644
1645
1646 void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1647 int old_length = from->length();
1648 ASSERT(old_length < length());
1649 memcpy(FIELD_ADDR(this, kHeaderSize),
Mads Ager (chromium) 2011/06/06 07:58:23 Use our own MemCopy?
danno 2011/06/08 12:09:43 Done.
1650 FIELD_ADDR(from, kHeaderSize),
1651 old_length * kDoubleSize);
1652 int offset = kHeaderSize + old_length * kDoubleSize;
1653 for (int current = from->length(); current < length(); ++current) {
1654 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1655 offset += kDoubleSize;
1656 }
1657 }
1658
1659
1660 void FixedDoubleArray::Initialize(FixedArray* from) {
1661 int old_length = from->length();
1662 ASSERT(old_length < length());
1663 Heap* heap = GetHeap();
1664 for (int i = 0; i < old_length; i++) {
1665 Object* hole_or_object = from->get(i);
1666 if (hole_or_object == heap->the_hole_value()) {
Mads Ager (chromium) 2011/06/06 07:58:23 hole_or_object->IsTheHole()
danno 2011/06/08 12:09:43 Done.
1667 set_the_hole(i);
1668 } else {
1669 set(i, hole_or_object->Number());
1670 }
1671 }
1672 int offset = kHeaderSize + old_length * kDoubleSize;
1673 for (int current = from->length(); current < length(); ++current) {
1674 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1675 offset += kDoubleSize;
1676 }
1677 }
1678
1679
1680 void FixedDoubleArray::Initialize(NumberDictionary* from) {
1681 int offset = kHeaderSize;
1682 for (int current = 0; current < length(); ++current) {
1683 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1684 offset += kDoubleSize;
1685 }
1686 for (int i = 0; i < from->Capacity(); i++) {
1687 Object* key = from->KeyAt(i);
1688 if (key->IsNumber()) {
1689 uint32_t entry = static_cast<uint32_t>(key->Number());
1690 set(entry, from->ValueAt(i)->Number());
1691 }
1692 }
1693 }
1694
1695
1598 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) { 1696 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
1599 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER; 1697 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
1600 return UPDATE_WRITE_BARRIER; 1698 return UPDATE_WRITE_BARRIER;
1601 } 1699 }
1602 1700
1603 1701
1604 void FixedArray::set(int index, 1702 void FixedArray::set(int index,
1605 Object* value, 1703 Object* value,
1606 WriteBarrierMode mode) { 1704 WriteBarrierMode mode) {
1607 ASSERT(map() != HEAP->fixed_cow_array_map()); 1705 ASSERT(map() != HEAP->fixed_cow_array_map());
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
1888 void NumberDictionary::set_requires_slow_elements() { 1986 void NumberDictionary::set_requires_slow_elements() {
1889 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask)); 1987 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
1890 } 1988 }
1891 1989
1892 1990
1893 // ------------------------------------ 1991 // ------------------------------------
1894 // Cast operations 1992 // Cast operations
1895 1993
1896 1994
1897 CAST_ACCESSOR(FixedArray) 1995 CAST_ACCESSOR(FixedArray)
1996 CAST_ACCESSOR(FixedDoubleArray)
1898 CAST_ACCESSOR(DescriptorArray) 1997 CAST_ACCESSOR(DescriptorArray)
1899 CAST_ACCESSOR(DeoptimizationInputData) 1998 CAST_ACCESSOR(DeoptimizationInputData)
1900 CAST_ACCESSOR(DeoptimizationOutputData) 1999 CAST_ACCESSOR(DeoptimizationOutputData)
1901 CAST_ACCESSOR(SymbolTable) 2000 CAST_ACCESSOR(SymbolTable)
1902 CAST_ACCESSOR(JSFunctionResultCache) 2001 CAST_ACCESSOR(JSFunctionResultCache)
1903 CAST_ACCESSOR(NormalizedMapCache) 2002 CAST_ACCESSOR(NormalizedMapCache)
1904 CAST_ACCESSOR(CompilationCacheTable) 2003 CAST_ACCESSOR(CompilationCacheTable)
1905 CAST_ACCESSOR(CodeCacheHashTable) 2004 CAST_ACCESSOR(CodeCacheHashTable)
1906 CAST_ACCESSOR(MapCache) 2005 CAST_ACCESSOR(MapCache)
1907 CAST_ACCESSOR(String) 2006 CAST_ACCESSOR(String)
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after
2410 return SeqAsciiString::SizeFor( 2509 return SeqAsciiString::SizeFor(
2411 reinterpret_cast<SeqAsciiString*>(this)->length()); 2510 reinterpret_cast<SeqAsciiString*>(this)->length());
2412 } 2511 }
2413 if (instance_type == BYTE_ARRAY_TYPE) { 2512 if (instance_type == BYTE_ARRAY_TYPE) {
2414 return reinterpret_cast<ByteArray*>(this)->ByteArraySize(); 2513 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2415 } 2514 }
2416 if (instance_type == STRING_TYPE) { 2515 if (instance_type == STRING_TYPE) {
2417 return SeqTwoByteString::SizeFor( 2516 return SeqTwoByteString::SizeFor(
2418 reinterpret_cast<SeqTwoByteString*>(this)->length()); 2517 reinterpret_cast<SeqTwoByteString*>(this)->length());
2419 } 2518 }
2519 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2520 return FixedDoubleArray::SizeFor(
2521 reinterpret_cast<FixedDoubleArray*>(this)->length());
2522 }
2420 ASSERT(instance_type == CODE_TYPE); 2523 ASSERT(instance_type == CODE_TYPE);
2421 return reinterpret_cast<Code*>(this)->CodeSize(); 2524 return reinterpret_cast<Code*>(this)->CodeSize();
2422 } 2525 }
2423 2526
2424 2527
2425 void Map::set_instance_size(int value) { 2528 void Map::set_instance_size(int value) {
2426 ASSERT_EQ(0, value & (kPointerSize - 1)); 2529 ASSERT_EQ(0, value & (kPointerSize - 1));
2427 value >>= kPointerSizeLog2; 2530 value >>= kPointerSizeLog2;
2428 ASSERT(0 <= value && value < 256); 2531 ASSERT(0 <= value && value < 256);
2429 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value)); 2532 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
2968 3071
2969 3072
2970 MaybeObject* Map::GetFastElementsMap() { 3073 MaybeObject* Map::GetFastElementsMap() {
2971 if (has_fast_elements()) return this; 3074 if (has_fast_elements()) return this;
2972 Object* obj; 3075 Object* obj;
2973 { MaybeObject* maybe_obj = CopyDropTransitions(); 3076 { MaybeObject* maybe_obj = CopyDropTransitions();
2974 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 3077 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2975 } 3078 }
2976 Map* new_map = Map::cast(obj); 3079 Map* new_map = Map::cast(obj);
2977 new_map->set_elements_kind(JSObject::FAST_ELEMENTS); 3080 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
2978 isolate()->counters()->map_slow_to_fast_elements()->Increment(); 3081 isolate()->counters()->map_to_fast_elements()->Increment();
2979 return new_map; 3082 return new_map;
2980 } 3083 }
2981 3084
3085
3086 MaybeObject* Map::GetFastDoubleElementsMap() {
3087 if (has_fast_double_elements()) return this;
3088 Object* obj;
3089 { MaybeObject* maybe_obj = CopyDropTransitions();
3090 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3091 }
3092 Map* new_map = Map::cast(obj);
3093 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3094 isolate()->counters()->map_to_fast_double_elements()->Increment();
3095 return new_map;
3096 }
3097
2982 3098
2983 MaybeObject* Map::GetSlowElementsMap() { 3099 MaybeObject* Map::GetSlowElementsMap() {
2984 if (!has_fast_elements()) return this; 3100 if (!has_fast_elements()) return this;
2985 Object* obj; 3101 Object* obj;
2986 { MaybeObject* maybe_obj = CopyDropTransitions(); 3102 { MaybeObject* maybe_obj = CopyDropTransitions();
2987 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 3103 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2988 } 3104 }
2989 Map* new_map = Map::cast(obj); 3105 Map* new_map = Map::cast(obj);
2990 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS); 3106 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
2991 isolate()->counters()->map_fast_to_slow_elements()->Increment(); 3107 isolate()->counters()->map_to_slow_elements()->Increment();
2992 return new_map; 3108 return new_map;
2993 } 3109 }
2994 3110
2995 3111
2996 DescriptorArray* Map::instance_descriptors() { 3112 DescriptorArray* Map::instance_descriptors() {
2997 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset); 3113 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
2998 if (object->IsSmi()) { 3114 if (object->IsSmi()) {
2999 return HEAP->empty_descriptor_array(); 3115 return HEAP->empty_descriptor_array();
3000 } else { 3116 } else {
3001 return DescriptorArray::cast(object); 3117 return DescriptorArray::cast(object);
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
3773 ASSERT(index >= kDataIndex); // Only implementation data can be set this way. 3889 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3774 FixedArray::cast(data())->set(index, value); 3890 FixedArray::cast(data())->set(index, value);
3775 } 3891 }
3776 3892
3777 3893
3778 JSObject::ElementsKind JSObject::GetElementsKind() { 3894 JSObject::ElementsKind JSObject::GetElementsKind() {
3779 ElementsKind kind = map()->elements_kind(); 3895 ElementsKind kind = map()->elements_kind();
3780 ASSERT((kind == FAST_ELEMENTS && 3896 ASSERT((kind == FAST_ELEMENTS &&
3781 (elements()->map() == GetHeap()->fixed_array_map() || 3897 (elements()->map() == GetHeap()->fixed_array_map() ||
3782 elements()->map() == GetHeap()->fixed_cow_array_map())) || 3898 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
3899 (kind == FAST_DOUBLE_ELEMENTS &&
3900 elements()->IsFixedDoubleArray()) ||
3783 (kind == DICTIONARY_ELEMENTS && 3901 (kind == DICTIONARY_ELEMENTS &&
3784 elements()->IsFixedArray() && 3902 elements()->IsFixedArray() &&
3785 elements()->IsDictionary()) || 3903 elements()->IsDictionary()) ||
3786 (kind > DICTIONARY_ELEMENTS)); 3904 (kind > DICTIONARY_ELEMENTS));
3787 return kind; 3905 return kind;
3788 } 3906 }
3789 3907
3790 3908
3791 bool JSObject::HasFastElements() { 3909 bool JSObject::HasFastElements() {
3792 return GetElementsKind() == FAST_ELEMENTS; 3910 return GetElementsKind() == FAST_ELEMENTS;
3793 } 3911 }
3794 3912
3795 3913
3914 bool JSObject::HasFastDoubleElements() {
3915 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
3916 }
3917
3918
3796 bool JSObject::HasDictionaryElements() { 3919 bool JSObject::HasDictionaryElements() {
3797 return GetElementsKind() == DICTIONARY_ELEMENTS; 3920 return GetElementsKind() == DICTIONARY_ELEMENTS;
3798 } 3921 }
3799 3922
3800 3923
3801 bool JSObject::HasExternalArrayElements() { 3924 bool JSObject::HasExternalArrayElements() {
3802 HeapObject* array = elements(); 3925 HeapObject* array = elements();
3803 ASSERT(array != NULL); 3926 ASSERT(array != NULL);
3804 return array->IsExternalArray(); 3927 return array->IsExternalArray();
3805 } 3928 }
(...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after
4298 #undef WRITE_INT_FIELD 4421 #undef WRITE_INT_FIELD
4299 #undef READ_SHORT_FIELD 4422 #undef READ_SHORT_FIELD
4300 #undef WRITE_SHORT_FIELD 4423 #undef WRITE_SHORT_FIELD
4301 #undef READ_BYTE_FIELD 4424 #undef READ_BYTE_FIELD
4302 #undef WRITE_BYTE_FIELD 4425 #undef WRITE_BYTE_FIELD
4303 4426
4304 4427
4305 } } // namespace v8::internal 4428 } } // namespace v8::internal
4306 4429
4307 #endif // V8_OBJECTS_INL_H_ 4430 #endif // V8_OBJECTS_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698