OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 1149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1160 Object* array = READ_FIELD(this, kElementsOffset); | 1160 Object* array = READ_FIELD(this, kElementsOffset); |
1161 // In the assert below Dictionary is covered under FixedArray. | 1161 // In the assert below Dictionary is covered under FixedArray. |
1162 ASSERT(array->IsFixedArray() || array->IsPixelArray() || | 1162 ASSERT(array->IsFixedArray() || array->IsPixelArray() || |
1163 array->IsExternalArray()); | 1163 array->IsExternalArray()); |
1164 return reinterpret_cast<HeapObject*>(array); | 1164 return reinterpret_cast<HeapObject*>(array); |
1165 } | 1165 } |
1166 | 1166 |
1167 | 1167 |
1168 void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) { | 1168 void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) { |
1169 ASSERT(map()->has_fast_elements() == | 1169 ASSERT(map()->has_fast_elements() == |
1170 (value->map() == Heap::fixed_array_map())); | 1170 (value->map() == Heap::fixed_array_map() || |
| 1171 value->map() == Heap::fixed_cow_array_map())); |
1171 // In the assert below Dictionary is covered under FixedArray. | 1172 // In the assert below Dictionary is covered under FixedArray. |
1172 ASSERT(value->IsFixedArray() || value->IsPixelArray() || | 1173 ASSERT(value->IsFixedArray() || value->IsPixelArray() || |
1173 value->IsExternalArray()); | 1174 value->IsExternalArray()); |
1174 WRITE_FIELD(this, kElementsOffset, value); | 1175 WRITE_FIELD(this, kElementsOffset, value); |
1175 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode); | 1176 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode); |
1176 } | 1177 } |
1177 | 1178 |
1178 | 1179 |
1179 void JSObject::initialize_properties() { | 1180 void JSObject::initialize_properties() { |
1180 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array())); | 1181 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array())); |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 } | 1391 } |
1391 | 1392 |
1392 | 1393 |
1393 Object* FixedArray::get(int index) { | 1394 Object* FixedArray::get(int index) { |
1394 ASSERT(index >= 0 && index < this->length()); | 1395 ASSERT(index >= 0 && index < this->length()); |
1395 return READ_FIELD(this, kHeaderSize + index * kPointerSize); | 1396 return READ_FIELD(this, kHeaderSize + index * kPointerSize); |
1396 } | 1397 } |
1397 | 1398 |
1398 | 1399 |
1399 void FixedArray::set(int index, Smi* value) { | 1400 void FixedArray::set(int index, Smi* value) { |
| 1401 ASSERT(map() != Heap::fixed_cow_array_map()); |
1400 ASSERT(reinterpret_cast<Object*>(value)->IsSmi()); | 1402 ASSERT(reinterpret_cast<Object*>(value)->IsSmi()); |
1401 int offset = kHeaderSize + index * kPointerSize; | 1403 int offset = kHeaderSize + index * kPointerSize; |
1402 WRITE_FIELD(this, offset, value); | 1404 WRITE_FIELD(this, offset, value); |
1403 } | 1405 } |
1404 | 1406 |
1405 | 1407 |
1406 void FixedArray::set(int index, Object* value) { | 1408 void FixedArray::set(int index, Object* value) { |
| 1409 ASSERT(map() != Heap::fixed_cow_array_map()); |
1407 ASSERT(index >= 0 && index < this->length()); | 1410 ASSERT(index >= 0 && index < this->length()); |
1408 int offset = kHeaderSize + index * kPointerSize; | 1411 int offset = kHeaderSize + index * kPointerSize; |
1409 WRITE_FIELD(this, offset, value); | 1412 WRITE_FIELD(this, offset, value); |
1410 WRITE_BARRIER(this, offset); | 1413 WRITE_BARRIER(this, offset); |
1411 } | 1414 } |
1412 | 1415 |
1413 | 1416 |
1414 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) { | 1417 WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) { |
1415 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER; | 1418 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER; |
1416 return UPDATE_WRITE_BARRIER; | 1419 return UPDATE_WRITE_BARRIER; |
1417 } | 1420 } |
1418 | 1421 |
1419 | 1422 |
1420 void FixedArray::set(int index, | 1423 void FixedArray::set(int index, |
1421 Object* value, | 1424 Object* value, |
1422 WriteBarrierMode mode) { | 1425 WriteBarrierMode mode) { |
| 1426 ASSERT(map() != Heap::fixed_cow_array_map()); |
1423 ASSERT(index >= 0 && index < this->length()); | 1427 ASSERT(index >= 0 && index < this->length()); |
1424 int offset = kHeaderSize + index * kPointerSize; | 1428 int offset = kHeaderSize + index * kPointerSize; |
1425 WRITE_FIELD(this, offset, value); | 1429 WRITE_FIELD(this, offset, value); |
1426 CONDITIONAL_WRITE_BARRIER(this, offset, mode); | 1430 CONDITIONAL_WRITE_BARRIER(this, offset, mode); |
1427 } | 1431 } |
1428 | 1432 |
1429 | 1433 |
1430 void FixedArray::fast_set(FixedArray* array, int index, Object* value) { | 1434 void FixedArray::fast_set(FixedArray* array, int index, Object* value) { |
| 1435 ASSERT(array->map() != Heap::raw_unchecked_fixed_cow_array_map()); |
1431 ASSERT(index >= 0 && index < array->length()); | 1436 ASSERT(index >= 0 && index < array->length()); |
1432 ASSERT(!Heap::InNewSpace(value)); | 1437 ASSERT(!Heap::InNewSpace(value)); |
1433 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); | 1438 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value); |
1434 } | 1439 } |
1435 | 1440 |
1436 | 1441 |
1437 void FixedArray::set_undefined(int index) { | 1442 void FixedArray::set_undefined(int index) { |
| 1443 ASSERT(map() != Heap::fixed_cow_array_map()); |
1438 ASSERT(index >= 0 && index < this->length()); | 1444 ASSERT(index >= 0 && index < this->length()); |
1439 ASSERT(!Heap::InNewSpace(Heap::undefined_value())); | 1445 ASSERT(!Heap::InNewSpace(Heap::undefined_value())); |
1440 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, | 1446 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, |
1441 Heap::undefined_value()); | 1447 Heap::undefined_value()); |
1442 } | 1448 } |
1443 | 1449 |
1444 | 1450 |
1445 void FixedArray::set_null(int index) { | 1451 void FixedArray::set_null(int index) { |
| 1452 ASSERT(map() != Heap::fixed_cow_array_map()); |
1446 ASSERT(index >= 0 && index < this->length()); | 1453 ASSERT(index >= 0 && index < this->length()); |
1447 ASSERT(!Heap::InNewSpace(Heap::null_value())); | 1454 ASSERT(!Heap::InNewSpace(Heap::null_value())); |
1448 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value()); | 1455 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value()); |
1449 } | 1456 } |
1450 | 1457 |
1451 | 1458 |
1452 void FixedArray::set_the_hole(int index) { | 1459 void FixedArray::set_the_hole(int index) { |
| 1460 ASSERT(map() != Heap::fixed_cow_array_map()); |
1453 ASSERT(index >= 0 && index < this->length()); | 1461 ASSERT(index >= 0 && index < this->length()); |
1454 ASSERT(!Heap::InNewSpace(Heap::the_hole_value())); | 1462 ASSERT(!Heap::InNewSpace(Heap::the_hole_value())); |
1455 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value()); | 1463 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value()); |
1456 } | 1464 } |
1457 | 1465 |
1458 | 1466 |
| 1467 void FixedArray::set_unchecked(int index, Smi* value) { |
| 1468 ASSERT(reinterpret_cast<Object*>(value)->IsSmi()); |
| 1469 int offset = kHeaderSize + index * kPointerSize; |
| 1470 WRITE_FIELD(this, offset, value); |
| 1471 } |
| 1472 |
| 1473 |
| 1474 void FixedArray::set_null_unchecked(int index) { |
| 1475 ASSERT(index >= 0 && index < this->length()); |
| 1476 ASSERT(!Heap::InNewSpace(Heap::null_value())); |
| 1477 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value()); |
| 1478 } |
| 1479 |
| 1480 |
1459 Object** FixedArray::data_start() { | 1481 Object** FixedArray::data_start() { |
1460 return HeapObject::RawField(this, kHeaderSize); | 1482 return HeapObject::RawField(this, kHeaderSize); |
1461 } | 1483 } |
1462 | 1484 |
1463 | 1485 |
1464 bool DescriptorArray::IsEmpty() { | 1486 bool DescriptorArray::IsEmpty() { |
1465 ASSERT(this == Heap::empty_descriptor_array() || | 1487 ASSERT(this == Heap::empty_descriptor_array() || |
1466 this->length() > 2); | 1488 this->length() > 2); |
1467 return this == Heap::empty_descriptor_array(); | 1489 return this == Heap::empty_descriptor_array(); |
1468 } | 1490 } |
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2391 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode); | 2413 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode); |
2392 } | 2414 } |
2393 | 2415 |
2394 | 2416 |
2395 Object* Map::GetFastElementsMap() { | 2417 Object* Map::GetFastElementsMap() { |
2396 if (has_fast_elements()) return this; | 2418 if (has_fast_elements()) return this; |
2397 Object* obj = CopyDropTransitions(); | 2419 Object* obj = CopyDropTransitions(); |
2398 if (obj->IsFailure()) return obj; | 2420 if (obj->IsFailure()) return obj; |
2399 Map* new_map = Map::cast(obj); | 2421 Map* new_map = Map::cast(obj); |
2400 new_map->set_has_fast_elements(true); | 2422 new_map->set_has_fast_elements(true); |
| 2423 Counters::map_slow_to_fast_elements.Increment(); |
2401 return new_map; | 2424 return new_map; |
2402 } | 2425 } |
2403 | 2426 |
2404 | 2427 |
2405 Object* Map::GetSlowElementsMap() { | 2428 Object* Map::GetSlowElementsMap() { |
2406 if (!has_fast_elements()) return this; | 2429 if (!has_fast_elements()) return this; |
2407 Object* obj = CopyDropTransitions(); | 2430 Object* obj = CopyDropTransitions(); |
2408 if (obj->IsFailure()) return obj; | 2431 if (obj->IsFailure()) return obj; |
2409 Map* new_map = Map::cast(obj); | 2432 Map* new_map = Map::cast(obj); |
2410 new_map->set_has_fast_elements(false); | 2433 new_map->set_has_fast_elements(false); |
| 2434 Counters::map_fast_to_slow_elements.Increment(); |
2411 return new_map; | 2435 return new_map; |
2412 } | 2436 } |
2413 | 2437 |
2414 | 2438 |
2415 ACCESSORS(Map, instance_descriptors, DescriptorArray, | 2439 ACCESSORS(Map, instance_descriptors, DescriptorArray, |
2416 kInstanceDescriptorsOffset) | 2440 kInstanceDescriptorsOffset) |
2417 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) | 2441 ACCESSORS(Map, code_cache, Object, kCodeCacheOffset) |
2418 ACCESSORS(Map, constructor, Object, kConstructorOffset) | 2442 ACCESSORS(Map, constructor, Object, kConstructorOffset) |
2419 | 2443 |
2420 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) | 2444 ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset) |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2921 | 2945 |
2922 | 2946 |
2923 void JSRegExp::SetDataAt(int index, Object* value) { | 2947 void JSRegExp::SetDataAt(int index, Object* value) { |
2924 ASSERT(TypeTag() != NOT_COMPILED); | 2948 ASSERT(TypeTag() != NOT_COMPILED); |
2925 ASSERT(index >= kDataIndex); // Only implementation data can be set this way. | 2949 ASSERT(index >= kDataIndex); // Only implementation data can be set this way. |
2926 FixedArray::cast(data())->set(index, value); | 2950 FixedArray::cast(data())->set(index, value); |
2927 } | 2951 } |
2928 | 2952 |
2929 | 2953 |
2930 JSObject::ElementsKind JSObject::GetElementsKind() { | 2954 JSObject::ElementsKind JSObject::GetElementsKind() { |
| 2955 if (map()->has_fast_elements()) { |
| 2956 ASSERT(elements()->map() == Heap::fixed_array_map() || |
| 2957 elements()->map() == Heap::fixed_cow_array_map()); |
| 2958 return FAST_ELEMENTS; |
| 2959 } |
2931 HeapObject* array = elements(); | 2960 HeapObject* array = elements(); |
2932 if (array->IsFixedArray()) { | 2961 if (array->IsFixedArray()) { |
2933 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray. | 2962 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a |
2934 if (array->map() == Heap::fixed_array_map()) { | 2963 // FixedArray, but FAST_ELEMENTS is already handled above. |
2935 ASSERT(map()->has_fast_elements()); | |
2936 return FAST_ELEMENTS; | |
2937 } | |
2938 ASSERT(array->IsDictionary()); | 2964 ASSERT(array->IsDictionary()); |
2939 ASSERT(!map()->has_fast_elements()); | |
2940 return DICTIONARY_ELEMENTS; | 2965 return DICTIONARY_ELEMENTS; |
2941 } | 2966 } |
2942 ASSERT(!map()->has_fast_elements()); | |
2943 if (array->IsExternalArray()) { | 2967 if (array->IsExternalArray()) { |
2944 switch (array->map()->instance_type()) { | 2968 switch (array->map()->instance_type()) { |
2945 case EXTERNAL_BYTE_ARRAY_TYPE: | 2969 case EXTERNAL_BYTE_ARRAY_TYPE: |
2946 return EXTERNAL_BYTE_ELEMENTS; | 2970 return EXTERNAL_BYTE_ELEMENTS; |
2947 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: | 2971 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: |
2948 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS; | 2972 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS; |
2949 case EXTERNAL_SHORT_ARRAY_TYPE: | 2973 case EXTERNAL_SHORT_ARRAY_TYPE: |
2950 return EXTERNAL_SHORT_ELEMENTS; | 2974 return EXTERNAL_SHORT_ELEMENTS; |
2951 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: | 2975 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: |
2952 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS; | 2976 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3035 } | 3059 } |
3036 | 3060 |
3037 | 3061 |
3038 bool JSObject::AllowsSetElementsLength() { | 3062 bool JSObject::AllowsSetElementsLength() { |
3039 bool result = elements()->IsFixedArray(); | 3063 bool result = elements()->IsFixedArray(); |
3040 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements())); | 3064 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements())); |
3041 return result; | 3065 return result; |
3042 } | 3066 } |
3043 | 3067 |
3044 | 3068 |
| 3069 Object* JSObject::EnsureWritableFastElements() { |
| 3070 ASSERT(HasFastElements()); |
| 3071 FixedArray* elems = FixedArray::cast(elements()); |
| 3072 if (elems->map() != Heap::fixed_cow_array_map()) return elems; |
| 3073 Object* writable_elems = Heap::CopyFixedArray(elems); |
| 3074 if (writable_elems->IsFailure()) return writable_elems; |
| 3075 FixedArray::cast(writable_elems)->set_map(Heap::fixed_array_map()); |
| 3076 set_elements(FixedArray::cast(writable_elems)); |
| 3077 Counters::cow_arrays_converted.Increment(); |
| 3078 return writable_elems; |
| 3079 } |
| 3080 |
| 3081 |
3045 StringDictionary* JSObject::property_dictionary() { | 3082 StringDictionary* JSObject::property_dictionary() { |
3046 ASSERT(!HasFastProperties()); | 3083 ASSERT(!HasFastProperties()); |
3047 return StringDictionary::cast(properties()); | 3084 return StringDictionary::cast(properties()); |
3048 } | 3085 } |
3049 | 3086 |
3050 | 3087 |
3051 NumberDictionary* JSObject::element_dictionary() { | 3088 NumberDictionary* JSObject::element_dictionary() { |
3052 ASSERT(HasDictionaryElements()); | 3089 ASSERT(HasDictionaryElements()); |
3053 return NumberDictionary::cast(elements()); | 3090 return NumberDictionary::cast(elements()); |
3054 } | 3091 } |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3384 #undef WRITE_INT_FIELD | 3421 #undef WRITE_INT_FIELD |
3385 #undef READ_SHORT_FIELD | 3422 #undef READ_SHORT_FIELD |
3386 #undef WRITE_SHORT_FIELD | 3423 #undef WRITE_SHORT_FIELD |
3387 #undef READ_BYTE_FIELD | 3424 #undef READ_BYTE_FIELD |
3388 #undef WRITE_BYTE_FIELD | 3425 #undef WRITE_BYTE_FIELD |
3389 | 3426 |
3390 | 3427 |
3391 } } // namespace v8::internal | 3428 } } // namespace v8::internal |
3392 | 3429 |
3393 #endif // V8_OBJECTS_INL_H_ | 3430 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |