OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 | 121 |
122 #define BOOL_ACCESSORS(holder, field, name, offset) \ | 122 #define BOOL_ACCESSORS(holder, field, name, offset) \ |
123 bool holder::name() { \ | 123 bool holder::name() { \ |
124 return BooleanBit::get(field(), offset); \ | 124 return BooleanBit::get(field(), offset); \ |
125 } \ | 125 } \ |
126 void holder::set_##name(bool value) { \ | 126 void holder::set_##name(bool value) { \ |
127 set_##field(BooleanBit::set(field(), offset, value)); \ | 127 set_##field(BooleanBit::set(field(), offset, value)); \ |
128 } | 128 } |
129 | 129 |
130 | 130 |
131 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, | |
132 ElementsKind to_kind) { | |
133 if (to_kind == FAST_ELEMENTS) { | |
134 return from_kind == FAST_SMI_ONLY_ELEMENTS || | |
135 from_kind == FAST_DOUBLE_ELEMENTS; | |
136 } else { | |
137 return to_kind == FAST_DOUBLE_ELEMENTS && | |
138 from_kind == FAST_SMI_ONLY_ELEMENTS; | |
139 } | |
140 } | |
141 | |
142 | |
143 bool Object::IsFixedArrayBase() { | 131 bool Object::IsFixedArrayBase() { |
144 return IsFixedArray() || IsFixedDoubleArray(); | 132 return IsFixedArray() || IsFixedDoubleArray(); |
145 } | 133 } |
146 | 134 |
147 | 135 |
148 bool Object::IsInstanceOf(FunctionTemplateInfo* expected) { | 136 bool Object::IsInstanceOf(FunctionTemplateInfo* expected) { |
149 // There is a constraint on the object; check. | 137 // There is a constraint on the object; check. |
150 if (!this->IsJSObject()) return false; | 138 if (!this->IsJSObject()) return false; |
151 // Fetch the constructor function of the object. | 139 // Fetch the constructor function of the object. |
152 Object* cons_obj = JSObject::cast(this)->map()->constructor(); | 140 Object* cons_obj = JSObject::cast(this)->map()->constructor(); |
(...skipping 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1237 } | 1225 } |
1238 return true; | 1226 return true; |
1239 } | 1227 } |
1240 | 1228 |
1241 | 1229 |
1242 FixedArrayBase* JSObject::elements() { | 1230 FixedArrayBase* JSObject::elements() { |
1243 Object* array = READ_FIELD(this, kElementsOffset); | 1231 Object* array = READ_FIELD(this, kElementsOffset); |
1244 return static_cast<FixedArrayBase*>(array); | 1232 return static_cast<FixedArrayBase*>(array); |
1245 } | 1233 } |
1246 | 1234 |
1247 void JSObject::ValidateSmiOnlyElements() { | 1235 |
1236 void JSObject::ValidateElements() { | |
1248 #if DEBUG | 1237 #if DEBUG |
1249 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { | 1238 if (FLAG_enable_slow_asserts) { |
1250 Heap* heap = GetHeap(); | 1239 ElementsAccessor* accessor = GetElementsAccessor(); |
1251 // Don't use elements, since integrity checks will fail if there | 1240 accessor->Validate(this); |
1252 // are filler pointers in the array. | |
1253 FixedArray* fixed_array = | |
1254 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset)); | |
1255 Map* map = fixed_array->map(); | |
1256 // Arrays that have been shifted in place can't be verified. | |
1257 if (map != heap->raw_unchecked_one_pointer_filler_map() && | |
1258 map != heap->raw_unchecked_two_pointer_filler_map() && | |
1259 map != heap->free_space_map()) { | |
1260 for (int i = 0; i < fixed_array->length(); i++) { | |
1261 Object* current = fixed_array->get(i); | |
1262 ASSERT(current->IsSmi() || current->IsTheHole()); | |
1263 } | |
1264 } | |
1265 } | 1241 } |
1266 #endif | 1242 #endif |
1267 } | 1243 } |
1268 | 1244 |
1269 | 1245 |
1270 MaybeObject* JSObject::EnsureCanContainHeapObjectElements() { | 1246 MaybeObject* JSObject::EnsureCanContainHeapObjectElements() { |
1271 #if DEBUG | 1247 ValidateElements(); |
1272 ValidateSmiOnlyElements(); | 1248 ElementsKind elements_kind = map()->elements_kind(); |
1273 #endif | 1249 if (!IsFastObjectElementsKind(elements_kind)) { |
1274 if ((map()->elements_kind() != FAST_ELEMENTS)) { | 1250 if (IsFastHoleyElementsKind(elements_kind)) { |
1275 return TransitionElementsKind(FAST_ELEMENTS); | 1251 return TransitionElementsKind(FAST_HOLEY_ELEMENTS); |
1252 } else { | |
1253 return TransitionElementsKind(FAST_ELEMENTS); | |
1254 } | |
1276 } | 1255 } |
1277 return this; | 1256 return this; |
1278 } | 1257 } |
1279 | 1258 |
1280 | 1259 |
1281 MaybeObject* JSObject::EnsureCanContainElements(Object** objects, | 1260 MaybeObject* JSObject::EnsureCanContainElements(Object** objects, |
1282 uint32_t count, | 1261 uint32_t count, |
1283 EnsureElementsMode mode) { | 1262 EnsureElementsMode mode) { |
1284 ElementsKind current_kind = map()->elements_kind(); | 1263 ElementsKind current_kind = map()->elements_kind(); |
1285 ElementsKind target_kind = current_kind; | 1264 ElementsKind target_kind = current_kind; |
1286 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS); | 1265 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS); |
1287 if (current_kind == FAST_ELEMENTS) return this; | 1266 bool is_holey = IsFastHoleyElementsKind(current_kind); |
1288 | 1267 if (current_kind == FAST_HOLEY_ELEMENTS) return this; |
1289 Heap* heap = GetHeap(); | 1268 Heap* heap = GetHeap(); |
1290 Object* the_hole = heap->the_hole_value(); | 1269 Object* the_hole = heap->the_hole_value(); |
1291 Object* heap_number_map = heap->heap_number_map(); | 1270 Object* heap_number_map = heap->heap_number_map(); |
1292 for (uint32_t i = 0; i < count; ++i) { | 1271 for (uint32_t i = 0; i < count; ++i) { |
1293 Object* current = *objects++; | 1272 Object* current = *objects++; |
1294 if (!current->IsSmi() && current != the_hole) { | 1273 if (current == the_hole) { |
1274 is_holey = true; | |
1275 target_kind = GetHoleyElementsKind(target_kind); | |
1276 } else if (!current->IsSmi()) { | |
1295 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && | 1277 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && |
1296 HeapObject::cast(current)->map() == heap_number_map) { | 1278 HeapObject::cast(current)->map() == heap_number_map && |
1297 target_kind = FAST_DOUBLE_ELEMENTS; | 1279 IsFastSmiElementsKind(target_kind)) { |
1280 if (is_holey) { | |
1281 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS; | |
1282 } else { | |
1283 target_kind = FAST_DOUBLE_ELEMENTS; | |
1284 } | |
1298 } else { | 1285 } else { |
1299 target_kind = FAST_ELEMENTS; | 1286 if (!current->IsNumber()) { |
1300 break; | 1287 if (is_holey) { |
1288 target_kind = FAST_HOLEY_ELEMENTS; | |
1289 break; | |
1290 } else { | |
1291 target_kind = FAST_ELEMENTS; | |
1292 } | |
1293 } | |
1301 } | 1294 } |
1302 } | 1295 } |
1303 } | 1296 } |
1304 | 1297 |
1305 if (target_kind != current_kind) { | 1298 if (target_kind != current_kind) { |
1306 return TransitionElementsKind(target_kind); | 1299 return TransitionElementsKind(target_kind); |
1307 } | 1300 } |
1308 return this; | 1301 return this; |
1309 } | 1302 } |
1310 | 1303 |
1311 | 1304 |
1312 MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements, | 1305 MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements, |
1306 uint32_t length, | |
1313 EnsureElementsMode mode) { | 1307 EnsureElementsMode mode) { |
1314 if (elements->map() != GetHeap()->fixed_double_array_map()) { | 1308 if (elements->map() != GetHeap()->fixed_double_array_map()) { |
1315 ASSERT(elements->map() == GetHeap()->fixed_array_map() || | 1309 ASSERT(elements->map() == GetHeap()->fixed_array_map() || |
1316 elements->map() == GetHeap()->fixed_cow_array_map()); | 1310 elements->map() == GetHeap()->fixed_cow_array_map()); |
1317 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) { | 1311 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) { |
1318 mode = DONT_ALLOW_DOUBLE_ELEMENTS; | 1312 mode = DONT_ALLOW_DOUBLE_ELEMENTS; |
1319 } | 1313 } |
1320 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress(); | 1314 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress(); |
1321 return EnsureCanContainElements(objects, elements->length(), mode); | 1315 return EnsureCanContainElements(objects, length, mode); |
1322 } | 1316 } |
1323 | 1317 |
1324 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS); | 1318 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS); |
1325 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) { | 1319 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) { |
1320 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS); | |
1321 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) { | |
1322 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements); | |
1323 for (uint32_t i = 0; i < length; ++i) { | |
1324 if (double_array->is_the_hole(i)) { | |
1325 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS); | |
1326 } | |
1327 } | |
1326 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS); | 1328 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS); |
1327 } | 1329 } |
1328 | 1330 |
1329 return this; | 1331 return this; |
1330 } | 1332 } |
1331 | 1333 |
1332 | 1334 |
1333 MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate, | 1335 MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate, |
1334 ElementsKind to_kind) { | 1336 ElementsKind to_kind) { |
1335 Map* current_map = map(); | 1337 Map* current_map = map(); |
1336 ElementsKind from_kind = current_map->elements_kind(); | 1338 ElementsKind from_kind = current_map->elements_kind(); |
1337 | |
1338 if (from_kind == to_kind) return current_map; | 1339 if (from_kind == to_kind) return current_map; |
1339 | 1340 |
1340 Context* global_context = isolate->context()->global_context(); | 1341 Context* global_context = isolate->context()->global_context(); |
1341 if (current_map == global_context->smi_js_array_map()) { | 1342 Object* maybe_array_maps = |
1342 if (to_kind == FAST_ELEMENTS) { | 1343 global_context->js_array_maps(); |
Jakob Kummerow
2012/05/13 21:55:27
nit: fits on one line
danno
2012/05/22 11:05:21
Done.
| |
1343 return global_context->object_js_array_map(); | 1344 if (maybe_array_maps->IsFixedArray()) { |
1344 } else { | 1345 FixedArray* array_maps = FixedArray::cast(maybe_array_maps); |
1345 if (to_kind == FAST_DOUBLE_ELEMENTS) { | 1346 if (array_maps->get(from_kind) == current_map) { |
1346 return global_context->double_js_array_map(); | 1347 Object* maybe_transitioned_map = array_maps->get(to_kind); |
1347 } else { | 1348 if (maybe_transitioned_map->IsMap()) { |
1348 ASSERT(to_kind == DICTIONARY_ELEMENTS); | 1349 return Map::cast(maybe_transitioned_map); |
1349 } | 1350 } |
1350 } | 1351 } |
1351 } | 1352 } |
1353 | |
1352 return GetElementsTransitionMapSlow(to_kind); | 1354 return GetElementsTransitionMapSlow(to_kind); |
1353 } | 1355 } |
1354 | 1356 |
1355 | 1357 |
1356 void JSObject::set_map_and_elements(Map* new_map, | 1358 void JSObject::set_map_and_elements(Map* new_map, |
1357 FixedArrayBase* value, | 1359 FixedArrayBase* value, |
1358 WriteBarrierMode mode) { | 1360 WriteBarrierMode mode) { |
1359 ASSERT(value->HasValidElements()); | 1361 ASSERT(value->HasValidElements()); |
1360 #ifdef DEBUG | |
1361 ValidateSmiOnlyElements(); | |
1362 #endif | |
1363 if (new_map != NULL) { | 1362 if (new_map != NULL) { |
1364 if (mode == UPDATE_WRITE_BARRIER) { | 1363 if (mode == UPDATE_WRITE_BARRIER) { |
1365 set_map(new_map); | 1364 set_map(new_map); |
1366 } else { | 1365 } else { |
1367 ASSERT(mode == SKIP_WRITE_BARRIER); | 1366 ASSERT(mode == SKIP_WRITE_BARRIER); |
1368 set_map_no_write_barrier(new_map); | 1367 set_map_no_write_barrier(new_map); |
1369 } | 1368 } |
1370 } | 1369 } |
1371 ASSERT((map()->has_fast_elements() || | 1370 ASSERT((map()->has_fast_smi_or_object_elements() || |
1372 map()->has_fast_smi_only_elements() || | |
1373 (value == GetHeap()->empty_fixed_array())) == | 1371 (value == GetHeap()->empty_fixed_array())) == |
1374 (value->map() == GetHeap()->fixed_array_map() || | 1372 (value->map() == GetHeap()->fixed_array_map() || |
1375 value->map() == GetHeap()->fixed_cow_array_map())); | 1373 value->map() == GetHeap()->fixed_cow_array_map())); |
1376 ASSERT((value == GetHeap()->empty_fixed_array()) || | 1374 ASSERT((value == GetHeap()->empty_fixed_array()) || |
1377 (map()->has_fast_double_elements() == value->IsFixedDoubleArray())); | 1375 (map()->has_fast_double_elements() == value->IsFixedDoubleArray())); |
1378 WRITE_FIELD(this, kElementsOffset, value); | 1376 WRITE_FIELD(this, kElementsOffset, value); |
1379 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode); | 1377 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode); |
1380 } | 1378 } |
1381 | 1379 |
1382 | 1380 |
1383 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { | 1381 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { |
1384 set_map_and_elements(NULL, value, mode); | 1382 set_map_and_elements(NULL, value, mode); |
1385 } | 1383 } |
1386 | 1384 |
1387 | 1385 |
1388 void JSObject::initialize_properties() { | 1386 void JSObject::initialize_properties() { |
1389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); | 1387 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); |
1390 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); | 1388 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); |
1391 } | 1389 } |
1392 | 1390 |
1393 | 1391 |
1394 void JSObject::initialize_elements() { | 1392 void JSObject::initialize_elements() { |
1395 ASSERT(map()->has_fast_elements() || | 1393 ASSERT(map()->has_fast_smi_or_object_elements() || |
1396 map()->has_fast_smi_only_elements() || | |
1397 map()->has_fast_double_elements()); | 1394 map()->has_fast_double_elements()); |
1398 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); | 1395 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); |
1399 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); | 1396 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); |
1400 } | 1397 } |
1401 | 1398 |
1402 | 1399 |
1403 MaybeObject* JSObject::ResetElements() { | 1400 MaybeObject* JSObject::ResetElements() { |
1404 Object* obj; | 1401 Object* obj; |
1405 ElementsKind elements_kind = FLAG_smi_only_arrays | 1402 ElementsKind elements_kind = GetInitialFastElementsKind(); |
1406 ? FAST_SMI_ONLY_ELEMENTS | 1403 if (!FLAG_smi_only_arrays) { |
1407 : FAST_ELEMENTS; | 1404 elements_kind = FastSmiToObjectElementsKind(elements_kind); |
1405 } | |
1408 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), | 1406 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), |
1409 elements_kind); | 1407 elements_kind); |
1410 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1408 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1411 set_map(Map::cast(obj)); | 1409 set_map(Map::cast(obj)); |
1412 initialize_elements(); | 1410 initialize_elements(); |
1413 return this; | 1411 return this; |
1414 } | 1412 } |
1415 | 1413 |
1416 | 1414 |
1417 ACCESSORS(Oddball, to_string, String, kToStringOffset) | 1415 ACCESSORS(Oddball, to_string, String, kToStringOffset) |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1669 return reinterpret_cast<FixedArrayBase*>(object); | 1667 return reinterpret_cast<FixedArrayBase*>(object); |
1670 } | 1668 } |
1671 | 1669 |
1672 | 1670 |
1673 Object* FixedArray::get(int index) { | 1671 Object* FixedArray::get(int index) { |
1674 ASSERT(index >= 0 && index < this->length()); | 1672 ASSERT(index >= 0 && index < this->length()); |
1675 return READ_FIELD(this, kHeaderSize + index * kPointerSize); | 1673 return READ_FIELD(this, kHeaderSize + index * kPointerSize); |
1676 } | 1674 } |
1677 | 1675 |
1678 | 1676 |
1677 bool FixedArray::is_the_hole(int index) { | |
1678 ASSERT(index >= 0 && index < this->length()); | |
Jakob Kummerow
2012/05/13 21:55:27
nit: this ASSERT, while correct, is not necessary,
danno
2012/05/22 11:05:21
Done.
| |
1679 return get(index) == GetHeap()->the_hole_value(); | |
1680 } | |
1681 | |
1682 | |
1679 void FixedArray::set(int index, Smi* value) { | 1683 void FixedArray::set(int index, Smi* value) { |
1680 ASSERT(map() != HEAP->fixed_cow_array_map()); | 1684 ASSERT(map() != HEAP->fixed_cow_array_map()); |
1681 ASSERT(index >= 0 && index < this->length()); | 1685 ASSERT(index >= 0 && index < this->length()); |
1682 ASSERT(reinterpret_cast<Object*>(value)->IsSmi()); | 1686 ASSERT(reinterpret_cast<Object*>(value)->IsSmi()); |
1683 int offset = kHeaderSize + index * kPointerSize; | 1687 int offset = kHeaderSize + index * kPointerSize; |
1684 WRITE_FIELD(this, offset, value); | 1688 WRITE_FIELD(this, offset, value); |
1685 } | 1689 } |
1686 | 1690 |
1687 | 1691 |
1688 void FixedArray::set(int index, Object* value) { | 1692 void FixedArray::set(int index, Object* value) { |
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2850 } | 2854 } |
2851 | 2855 |
2852 | 2856 |
2853 bool Map::has_non_instance_prototype() { | 2857 bool Map::has_non_instance_prototype() { |
2854 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0; | 2858 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0; |
2855 } | 2859 } |
2856 | 2860 |
2857 | 2861 |
2858 void Map::set_function_with_prototype(bool value) { | 2862 void Map::set_function_with_prototype(bool value) { |
2859 if (value) { | 2863 if (value) { |
2860 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype)); | 2864 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype)); |
2861 } else { | 2865 } else { |
2862 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype)); | 2866 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype)); |
2863 } | 2867 } |
2864 } | 2868 } |
2865 | 2869 |
2866 | 2870 |
2867 bool Map::function_with_prototype() { | 2871 bool Map::function_with_prototype() { |
2868 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0; | 2872 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0; |
2869 } | 2873 } |
2870 | 2874 |
2871 | 2875 |
2872 void Map::set_is_access_check_needed(bool access_check_needed) { | 2876 void Map::set_is_access_check_needed(bool access_check_needed) { |
2873 if (access_check_needed) { | 2877 if (access_check_needed) { |
2874 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded)); | 2878 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded)); |
2875 } else { | 2879 } else { |
2876 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded)); | 2880 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded)); |
2877 } | 2881 } |
2878 } | 2882 } |
(...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3936 } | 3940 } |
3937 | 3941 |
3938 | 3942 |
3939 MaybeObject* JSFunction::set_initial_map_and_cache_transitions( | 3943 MaybeObject* JSFunction::set_initial_map_and_cache_transitions( |
3940 Map* initial_map) { | 3944 Map* initial_map) { |
3941 Context* global_context = context()->global_context(); | 3945 Context* global_context = context()->global_context(); |
3942 Object* array_function = | 3946 Object* array_function = |
3943 global_context->get(Context::ARRAY_FUNCTION_INDEX); | 3947 global_context->get(Context::ARRAY_FUNCTION_INDEX); |
3944 if (array_function->IsJSFunction() && | 3948 if (array_function->IsJSFunction() && |
3945 this == JSFunction::cast(array_function)) { | 3949 this == JSFunction::cast(array_function)) { |
3946 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); | 3950 // Replace all of the cached initial array maps in the global context with |
3951 // the appropriate transitioned elements kind maps. | |
3952 Heap* heap = GetHeap(); | |
3953 MaybeObject* maybe_maps = | |
3954 heap->AllocateFixedArrayWithHoles(kElementsKindCount); | |
Jakob Kummerow
2012/05/13 21:55:27
Do you mean kFastElementsKindCount here?
danno
2012/05/22 11:05:21
kElementsKindCount is better here, since it remove
| |
3955 FixedArray* maps; | |
3956 if (!maybe_maps->To(&maps)) return maybe_maps; | |
3947 | 3957 |
3948 MaybeObject* maybe_map = initial_map->CopyDropTransitions(); | 3958 Map* current_map = initial_map; |
3949 Map* new_double_map = NULL; | 3959 ElementsKind kind = current_map->elements_kind(); |
3950 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map; | 3960 ASSERT(kind == GetInitialFastElementsKind()); |
3951 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS); | 3961 maps->set(kind, current_map); |
3952 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, | 3962 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; |
3953 new_double_map); | 3963 i < kFastElementsKindCount; ++i) { |
3954 if (maybe_map->IsFailure()) return maybe_map; | 3964 ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i); |
3955 | 3965 MaybeObject* maybe_new_map = current_map->CopyDropTransitions(); |
3956 maybe_map = new_double_map->CopyDropTransitions(); | 3966 Map* new_map = NULL; |
3957 Map* new_object_map = NULL; | 3967 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map; |
3958 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map; | 3968 new_map->set_elements_kind(transitioned_kind); |
3959 new_object_map->set_elements_kind(FAST_ELEMENTS); | 3969 maybe_new_map = current_map->AddElementsTransition(transitioned_kind, |
3960 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS, | 3970 new_map); |
3961 new_object_map); | 3971 if (maybe_new_map->IsFailure()) return maybe_new_map; |
3962 if (maybe_map->IsFailure()) return maybe_map; | 3972 maps->set(transitioned_kind, new_map); |
3963 | 3973 current_map = new_map; |
3964 global_context->set_smi_js_array_map(initial_map); | 3974 } |
3965 global_context->set_double_js_array_map(new_double_map); | 3975 global_context->set_js_array_maps(maps); |
3966 global_context->set_object_js_array_map(new_object_map); | |
3967 } | 3976 } |
3968 set_initial_map(initial_map); | 3977 set_initial_map(initial_map); |
3969 return this; | 3978 return this; |
3970 } | 3979 } |
3971 | 3980 |
3972 | 3981 |
3973 bool JSFunction::has_initial_map() { | 3982 bool JSFunction::has_initial_map() { |
3974 return prototype_or_initial_map()->IsMap(); | 3983 return prototype_or_initial_map()->IsMap(); |
3975 } | 3984 } |
3976 | 3985 |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4292 } | 4301 } |
4293 } | 4302 } |
4294 | 4303 |
4295 | 4304 |
4296 ElementsKind JSObject::GetElementsKind() { | 4305 ElementsKind JSObject::GetElementsKind() { |
4297 ElementsKind kind = map()->elements_kind(); | 4306 ElementsKind kind = map()->elements_kind(); |
4298 #if DEBUG | 4307 #if DEBUG |
4299 FixedArrayBase* fixed_array = | 4308 FixedArrayBase* fixed_array = |
4300 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); | 4309 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); |
4301 Map* map = fixed_array->map(); | 4310 Map* map = fixed_array->map(); |
4302 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && | 4311 ASSERT((IsFastSmiOrObjectElementsKind(kind) && |
4303 (map == GetHeap()->fixed_array_map() || | 4312 (map == GetHeap()->fixed_array_map() || |
4304 map == GetHeap()->fixed_cow_array_map())) || | 4313 map == GetHeap()->fixed_cow_array_map())) || |
4305 (kind == FAST_DOUBLE_ELEMENTS && | 4314 (IsFastDoubleElementsKind(kind) && |
4306 (fixed_array->IsFixedDoubleArray() || | 4315 (fixed_array->IsFixedDoubleArray() || |
4307 fixed_array == GetHeap()->empty_fixed_array())) || | 4316 fixed_array == GetHeap()->empty_fixed_array())) || |
4308 (kind == DICTIONARY_ELEMENTS && | 4317 (kind == DICTIONARY_ELEMENTS && |
4309 fixed_array->IsFixedArray() && | 4318 fixed_array->IsFixedArray() && |
4310 fixed_array->IsDictionary()) || | 4319 fixed_array->IsDictionary()) || |
4311 (kind > DICTIONARY_ELEMENTS)); | 4320 (kind > DICTIONARY_ELEMENTS)); |
4312 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || | 4321 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || |
4313 (elements()->IsFixedArray() && elements()->length() >= 2)); | 4322 (elements()->IsFixedArray() && elements()->length() >= 2)); |
4314 #endif | 4323 #endif |
4315 return kind; | 4324 return kind; |
4316 } | 4325 } |
4317 | 4326 |
4318 | 4327 |
4319 ElementsAccessor* JSObject::GetElementsAccessor() { | 4328 ElementsAccessor* JSObject::GetElementsAccessor() { |
4320 return ElementsAccessor::ForKind(GetElementsKind()); | 4329 return ElementsAccessor::ForKind(GetElementsKind()); |
4321 } | 4330 } |
4322 | 4331 |
4323 | 4332 |
4324 bool JSObject::HasFastElements() { | 4333 bool JSObject::HasFastObjectElements() { |
4325 return GetElementsKind() == FAST_ELEMENTS; | 4334 return IsFastObjectElementsKind(GetElementsKind()); |
4326 } | 4335 } |
4327 | 4336 |
4328 | 4337 |
4329 bool JSObject::HasFastSmiOnlyElements() { | 4338 bool JSObject::HasFastSmiElements() { |
4330 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS; | 4339 return IsFastSmiElementsKind(GetElementsKind()); |
4331 } | 4340 } |
4332 | 4341 |
4333 | 4342 |
4334 bool JSObject::HasFastTypeElements() { | 4343 bool JSObject::HasFastSmiOrObjectElements() { |
4335 ElementsKind elements_kind = GetElementsKind(); | 4344 return IsFastSmiOrObjectElementsKind(GetElementsKind()); |
4336 return elements_kind == FAST_SMI_ONLY_ELEMENTS || | |
4337 elements_kind == FAST_ELEMENTS; | |
4338 } | 4345 } |
4339 | 4346 |
4340 | 4347 |
4341 bool JSObject::HasFastDoubleElements() { | 4348 bool JSObject::HasFastDoubleElements() { |
4342 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; | 4349 return IsFastDoubleElementsKind(GetElementsKind()); |
4343 } | 4350 } |
4344 | 4351 |
4345 | 4352 |
4353 bool JSObject::HasFastHoleyElements() { | |
4354 return IsFastHoleyElementsKind(GetElementsKind()); | |
4355 } | |
4356 | |
4357 | |
4346 bool JSObject::HasDictionaryElements() { | 4358 bool JSObject::HasDictionaryElements() { |
4347 return GetElementsKind() == DICTIONARY_ELEMENTS; | 4359 return GetElementsKind() == DICTIONARY_ELEMENTS; |
4348 } | 4360 } |
4349 | 4361 |
4350 | 4362 |
4351 bool JSObject::HasNonStrictArgumentsElements() { | 4363 bool JSObject::HasNonStrictArgumentsElements() { |
4352 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS; | 4364 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS; |
4353 } | 4365 } |
4354 | 4366 |
4355 | 4367 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4389 return map()->has_named_interceptor(); | 4401 return map()->has_named_interceptor(); |
4390 } | 4402 } |
4391 | 4403 |
4392 | 4404 |
4393 bool JSObject::HasIndexedInterceptor() { | 4405 bool JSObject::HasIndexedInterceptor() { |
4394 return map()->has_indexed_interceptor(); | 4406 return map()->has_indexed_interceptor(); |
4395 } | 4407 } |
4396 | 4408 |
4397 | 4409 |
4398 MaybeObject* JSObject::EnsureWritableFastElements() { | 4410 MaybeObject* JSObject::EnsureWritableFastElements() { |
4399 ASSERT(HasFastTypeElements()); | 4411 ASSERT(HasFastSmiOrObjectElements()); |
4400 FixedArray* elems = FixedArray::cast(elements()); | 4412 FixedArray* elems = FixedArray::cast(elements()); |
4401 Isolate* isolate = GetIsolate(); | 4413 Isolate* isolate = GetIsolate(); |
4402 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; | 4414 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
4403 Object* writable_elems; | 4415 Object* writable_elems; |
4404 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( | 4416 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( |
4405 elems, isolate->heap()->fixed_array_map()); | 4417 elems, isolate->heap()->fixed_array_map()); |
4406 if (!maybe_writable_elems->ToObject(&writable_elems)) { | 4418 if (!maybe_writable_elems->ToObject(&writable_elems)) { |
4407 return maybe_writable_elems; | 4419 return maybe_writable_elems; |
4408 } | 4420 } |
4409 } | 4421 } |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4747 // No write barrier is needed since empty_fixed_array is not in new space. | 4759 // No write barrier is needed since empty_fixed_array is not in new space. |
4748 // Please note this function is used during marking: | 4760 // Please note this function is used during marking: |
4749 // - MarkCompactCollector::MarkUnmarkedObject | 4761 // - MarkCompactCollector::MarkUnmarkedObject |
4750 // - IncrementalMarking::Step | 4762 // - IncrementalMarking::Step |
4751 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); | 4763 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); |
4752 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); | 4764 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); |
4753 } | 4765 } |
4754 | 4766 |
4755 | 4767 |
4756 void JSArray::EnsureSize(int required_size) { | 4768 void JSArray::EnsureSize(int required_size) { |
4757 ASSERT(HasFastTypeElements()); | 4769 ASSERT(HasFastSmiOrObjectElements()); |
4758 FixedArray* elts = FixedArray::cast(elements()); | 4770 FixedArray* elts = FixedArray::cast(elements()); |
4759 const int kArraySizeThatFitsComfortablyInNewSpace = 128; | 4771 const int kArraySizeThatFitsComfortablyInNewSpace = 128; |
4760 if (elts->length() < required_size) { | 4772 if (elts->length() < required_size) { |
4761 // Doubling in size would be overkill, but leave some slack to avoid | 4773 // Doubling in size would be overkill, but leave some slack to avoid |
4762 // constantly growing. | 4774 // constantly growing. |
4763 Expand(required_size + (required_size >> 3)); | 4775 Expand(required_size + (required_size >> 3)); |
4764 // It's a performance benefit to keep a frequently used array in new-space. | 4776 // It's a performance benefit to keep a frequently used array in new-space. |
4765 } else if (!GetHeap()->new_space()->Contains(elts) && | 4777 } else if (!GetHeap()->new_space()->Contains(elts) && |
4766 required_size < kArraySizeThatFitsComfortablyInNewSpace) { | 4778 required_size < kArraySizeThatFitsComfortablyInNewSpace) { |
4767 // Expand will allocate a new backing store in new space even if the size | 4779 // Expand will allocate a new backing store in new space even if the size |
(...skipping 11 matching lines...) Expand all Loading... | |
4779 | 4791 |
4780 bool JSArray::AllowsSetElementsLength() { | 4792 bool JSArray::AllowsSetElementsLength() { |
4781 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray(); | 4793 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray(); |
4782 ASSERT(result == !HasExternalArrayElements()); | 4794 ASSERT(result == !HasExternalArrayElements()); |
4783 return result; | 4795 return result; |
4784 } | 4796 } |
4785 | 4797 |
4786 | 4798 |
4787 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { | 4799 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { |
4788 MaybeObject* maybe_result = EnsureCanContainElements( | 4800 MaybeObject* maybe_result = EnsureCanContainElements( |
4789 storage, ALLOW_COPIED_DOUBLE_ELEMENTS); | 4801 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS); |
4790 if (maybe_result->IsFailure()) return maybe_result; | 4802 if (maybe_result->IsFailure()) return maybe_result; |
4791 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && | 4803 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && |
4792 GetElementsKind() == FAST_DOUBLE_ELEMENTS) || | 4804 IsFastDoubleElementsKind(GetElementsKind())) || |
4793 ((storage->map() != GetHeap()->fixed_double_array_map()) && | 4805 ((storage->map() != GetHeap()->fixed_double_array_map()) && |
4794 ((GetElementsKind() == FAST_ELEMENTS) || | 4806 (IsFastObjectElementsKind(GetElementsKind()) || |
4795 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS && | 4807 (IsFastElementsKind(GetElementsKind()) && |
Jakob Kummerow
2012/05/13 21:55:27
Did you mean IsFastSmiElementsKind?
danno
2012/05/22 11:05:21
Done.
| |
4796 FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); | 4808 FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); |
4797 set_elements(storage); | 4809 set_elements(storage); |
4798 set_length(Smi::FromInt(storage->length())); | 4810 set_length(Smi::FromInt(storage->length())); |
4799 return this; | 4811 return this; |
4800 } | 4812 } |
4801 | 4813 |
4802 | 4814 |
4803 MaybeObject* FixedArray::Copy() { | 4815 MaybeObject* FixedArray::Copy() { |
4804 if (length() == 0) return this; | 4816 if (length() == 0) return this; |
4805 return GetHeap()->CopyFixedArray(this); | 4817 return GetHeap()->CopyFixedArray(this); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4962 #undef WRITE_UINT32_FIELD | 4974 #undef WRITE_UINT32_FIELD |
4963 #undef READ_SHORT_FIELD | 4975 #undef READ_SHORT_FIELD |
4964 #undef WRITE_SHORT_FIELD | 4976 #undef WRITE_SHORT_FIELD |
4965 #undef READ_BYTE_FIELD | 4977 #undef READ_BYTE_FIELD |
4966 #undef WRITE_BYTE_FIELD | 4978 #undef WRITE_BYTE_FIELD |
4967 | 4979 |
4968 | 4980 |
4969 } } // namespace v8::internal | 4981 } } // namespace v8::internal |
4970 | 4982 |
4971 #endif // V8_OBJECTS_INL_H_ | 4983 #endif // V8_OBJECTS_INL_H_ |
OLD | NEW |