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

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

Issue 3144002: Copy-on-write arrays. (Closed)
Patch Set: Review fixes. Created 10 years, 4 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-debug.cc ('k') | src/parser.h » ('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 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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/objects-debug.cc ('k') | src/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698