| 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 |