| 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() { | |
| 1248 #if DEBUG | |
| 1249 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) { | |
| 1250 Heap* heap = GetHeap(); | |
| 1251 // Don't use elements, since integrity checks will fail if there | |
| 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 } | |
| 1266 #endif | |
| 1267 } | |
| 1268 | |
| 1269 | 1235 |
| 1270 MaybeObject* JSObject::EnsureCanContainHeapObjectElements() { | 1236 MaybeObject* JSObject::EnsureCanContainHeapObjectElements() { |
| 1271 #if DEBUG | 1237 #if DEBUG |
| 1272 ValidateSmiOnlyElements(); | 1238 ValidateElements(); |
| 1273 #endif | 1239 #endif |
| 1274 if ((map()->elements_kind() != FAST_ELEMENTS)) { | 1240 ElementsKind elements_kind = map()->elements_kind(); |
| 1275 return TransitionElementsKind(FAST_ELEMENTS); | 1241 if (!IsFastObjectElementsKind(elements_kind)) { |
| 1242 if (IsFastHoleyElementsKind(elements_kind)) { |
| 1243 return TransitionElementsKind(FAST_HOLEY_ELEMENTS); |
| 1244 } else { |
| 1245 return TransitionElementsKind(FAST_ELEMENTS); |
| 1246 } |
| 1276 } | 1247 } |
| 1277 return this; | 1248 return this; |
| 1278 } | 1249 } |
| 1279 | 1250 |
| 1280 | 1251 |
| 1281 MaybeObject* JSObject::EnsureCanContainElements(Object** objects, | 1252 MaybeObject* JSObject::EnsureCanContainElements(Object** objects, |
| 1282 uint32_t count, | 1253 uint32_t count, |
| 1283 EnsureElementsMode mode) { | 1254 EnsureElementsMode mode) { |
| 1284 ElementsKind current_kind = map()->elements_kind(); | 1255 ElementsKind current_kind = map()->elements_kind(); |
| 1285 ElementsKind target_kind = current_kind; | 1256 ElementsKind target_kind = current_kind; |
| 1286 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS); | 1257 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS); |
| 1287 if (current_kind == FAST_ELEMENTS) return this; | 1258 bool is_holey = IsFastHoleyElementsKind(current_kind); |
| 1288 | 1259 if (current_kind == FAST_HOLEY_ELEMENTS) return this; |
| 1289 Heap* heap = GetHeap(); | 1260 Heap* heap = GetHeap(); |
| 1290 Object* the_hole = heap->the_hole_value(); | 1261 Object* the_hole = heap->the_hole_value(); |
| 1291 Object* heap_number_map = heap->heap_number_map(); | 1262 Object* heap_number_map = heap->heap_number_map(); |
| 1292 for (uint32_t i = 0; i < count; ++i) { | 1263 for (uint32_t i = 0; i < count; ++i) { |
| 1293 Object* current = *objects++; | 1264 Object* current = *objects++; |
| 1294 if (!current->IsSmi() && current != the_hole) { | 1265 if (current == the_hole) { |
| 1266 is_holey = true; |
| 1267 target_kind = GetHoleyElementsKind(target_kind); |
| 1268 } else if (!current->IsSmi()) { |
| 1295 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && | 1269 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS && |
| 1296 HeapObject::cast(current)->map() == heap_number_map) { | 1270 HeapObject::cast(current)->map() == heap_number_map && |
| 1297 target_kind = FAST_DOUBLE_ELEMENTS; | 1271 IsFastSmiElementsKind(target_kind)) { |
| 1272 if (is_holey) { |
| 1273 target_kind = FAST_HOLEY_DOUBLE_ELEMENTS; |
| 1274 } else { |
| 1275 target_kind = FAST_DOUBLE_ELEMENTS; |
| 1276 } |
| 1298 } else { | 1277 } else { |
| 1299 target_kind = FAST_ELEMENTS; | 1278 if (!current->IsNumber()) { |
| 1300 break; | 1279 if (is_holey) { |
| 1280 target_kind = FAST_HOLEY_ELEMENTS; |
| 1281 break; |
| 1282 } else { |
| 1283 target_kind = FAST_ELEMENTS; |
| 1284 } |
| 1285 } |
| 1301 } | 1286 } |
| 1302 } | 1287 } |
| 1303 } | 1288 } |
| 1304 | 1289 |
| 1305 if (target_kind != current_kind) { | 1290 if (target_kind != current_kind) { |
| 1306 return TransitionElementsKind(target_kind); | 1291 return TransitionElementsKind(target_kind); |
| 1307 } | 1292 } |
| 1308 return this; | 1293 return this; |
| 1309 } | 1294 } |
| 1310 | 1295 |
| 1311 | 1296 |
| 1312 MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements, | 1297 MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements, |
| 1298 uint32_t length, |
| 1313 EnsureElementsMode mode) { | 1299 EnsureElementsMode mode) { |
| 1314 if (elements->map() != GetHeap()->fixed_double_array_map()) { | 1300 if (elements->map() != GetHeap()->fixed_double_array_map()) { |
| 1315 ASSERT(elements->map() == GetHeap()->fixed_array_map() || | 1301 ASSERT(elements->map() == GetHeap()->fixed_array_map() || |
| 1316 elements->map() == GetHeap()->fixed_cow_array_map()); | 1302 elements->map() == GetHeap()->fixed_cow_array_map()); |
| 1317 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) { | 1303 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) { |
| 1318 mode = DONT_ALLOW_DOUBLE_ELEMENTS; | 1304 mode = DONT_ALLOW_DOUBLE_ELEMENTS; |
| 1319 } | 1305 } |
| 1320 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress(); | 1306 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress(); |
| 1321 return EnsureCanContainElements(objects, elements->length(), mode); | 1307 return EnsureCanContainElements(objects, length, mode); |
| 1322 } | 1308 } |
| 1323 | 1309 |
| 1324 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS); | 1310 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS); |
| 1325 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) { | 1311 if (GetElementsKind() == FAST_HOLEY_SMI_ELEMENTS) { |
| 1312 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS); |
| 1313 } else if (GetElementsKind() == FAST_SMI_ELEMENTS) { |
| 1314 FixedDoubleArray* double_array = FixedDoubleArray::cast(elements); |
| 1315 for (uint32_t i = 0; i < length; ++i) { |
| 1316 if (double_array->is_the_hole(i)) { |
| 1317 return TransitionElementsKind(FAST_HOLEY_DOUBLE_ELEMENTS); |
| 1318 } |
| 1319 } |
| 1326 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS); | 1320 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS); |
| 1327 } | 1321 } |
| 1328 | 1322 |
| 1329 return this; | 1323 return this; |
| 1330 } | 1324 } |
| 1331 | 1325 |
| 1332 | 1326 |
| 1333 MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate, | 1327 MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate, |
| 1334 ElementsKind to_kind) { | 1328 ElementsKind to_kind) { |
| 1335 Map* current_map = map(); | 1329 Map* current_map = map(); |
| 1336 ElementsKind from_kind = current_map->elements_kind(); | 1330 ElementsKind from_kind = current_map->elements_kind(); |
| 1337 | |
| 1338 if (from_kind == to_kind) return current_map; | 1331 if (from_kind == to_kind) return current_map; |
| 1339 | 1332 |
| 1340 Context* global_context = isolate->context()->global_context(); | 1333 Context* global_context = isolate->context()->global_context(); |
| 1341 if (current_map == global_context->smi_js_array_map()) { | 1334 Object* maybe_array_maps = |
| 1342 if (to_kind == FAST_ELEMENTS) { | 1335 global_context->js_array_maps(); |
| 1343 return global_context->object_js_array_map(); | 1336 if (maybe_array_maps->IsFixedArray()) { |
| 1344 } else { | 1337 FixedArray* array_maps = FixedArray::cast(maybe_array_maps); |
| 1345 if (to_kind == FAST_DOUBLE_ELEMENTS) { | 1338 if (array_maps->get(from_kind) == current_map) { |
| 1346 return global_context->double_js_array_map(); | 1339 Object* maybe_transitioned_map = array_maps->get(to_kind); |
| 1347 } else { | 1340 if (maybe_transitioned_map->IsMap()) { |
| 1348 ASSERT(to_kind == DICTIONARY_ELEMENTS); | 1341 return Map::cast(maybe_transitioned_map); |
| 1349 } | 1342 } |
| 1350 } | 1343 } |
| 1351 } | 1344 } |
| 1345 |
| 1352 return GetElementsTransitionMapSlow(to_kind); | 1346 return GetElementsTransitionMapSlow(to_kind); |
| 1353 } | 1347 } |
| 1354 | 1348 |
| 1355 | 1349 |
| 1356 void JSObject::set_map_and_elements(Map* new_map, | 1350 void JSObject::set_map_and_elements(Map* new_map, |
| 1357 FixedArrayBase* value, | 1351 FixedArrayBase* value, |
| 1358 WriteBarrierMode mode) { | 1352 WriteBarrierMode mode) { |
| 1359 ASSERT(value->HasValidElements()); | 1353 ASSERT(value->HasValidElements()); |
| 1360 #ifdef DEBUG | |
| 1361 ValidateSmiOnlyElements(); | |
| 1362 #endif | |
| 1363 if (new_map != NULL) { | 1354 if (new_map != NULL) { |
| 1364 if (mode == UPDATE_WRITE_BARRIER) { | 1355 if (mode == UPDATE_WRITE_BARRIER) { |
| 1365 set_map(new_map); | 1356 set_map(new_map); |
| 1366 } else { | 1357 } else { |
| 1367 ASSERT(mode == SKIP_WRITE_BARRIER); | 1358 ASSERT(mode == SKIP_WRITE_BARRIER); |
| 1368 set_map_no_write_barrier(new_map); | 1359 set_map_no_write_barrier(new_map); |
| 1369 } | 1360 } |
| 1370 } | 1361 } |
| 1371 ASSERT((map()->has_fast_elements() || | 1362 ASSERT((map()->has_fast_smi_or_object_elements() || |
| 1372 map()->has_fast_smi_only_elements() || | |
| 1373 (value == GetHeap()->empty_fixed_array())) == | 1363 (value == GetHeap()->empty_fixed_array())) == |
| 1374 (value->map() == GetHeap()->fixed_array_map() || | 1364 (value->map() == GetHeap()->fixed_array_map() || |
| 1375 value->map() == GetHeap()->fixed_cow_array_map())); | 1365 value->map() == GetHeap()->fixed_cow_array_map())); |
| 1376 ASSERT((value == GetHeap()->empty_fixed_array()) || | 1366 ASSERT((value == GetHeap()->empty_fixed_array()) || |
| 1377 (map()->has_fast_double_elements() == value->IsFixedDoubleArray())); | 1367 (map()->has_fast_double_elements() == value->IsFixedDoubleArray())); |
| 1378 WRITE_FIELD(this, kElementsOffset, value); | 1368 WRITE_FIELD(this, kElementsOffset, value); |
| 1379 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode); | 1369 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode); |
| 1380 } | 1370 } |
| 1381 | 1371 |
| 1382 | 1372 |
| 1383 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { | 1373 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { |
| 1384 set_map_and_elements(NULL, value, mode); | 1374 set_map_and_elements(NULL, value, mode); |
| 1385 } | 1375 } |
| 1386 | 1376 |
| 1387 | 1377 |
| 1388 void JSObject::initialize_properties() { | 1378 void JSObject::initialize_properties() { |
| 1389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); | 1379 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); |
| 1390 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); | 1380 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); |
| 1391 } | 1381 } |
| 1392 | 1382 |
| 1393 | 1383 |
| 1394 void JSObject::initialize_elements() { | 1384 void JSObject::initialize_elements() { |
| 1395 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements()); | 1385 ASSERT(map()->has_fast_smi_or_object_elements()); |
| 1396 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); | 1386 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); |
| 1397 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); | 1387 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); |
| 1398 } | 1388 } |
| 1399 | 1389 |
| 1400 | 1390 |
| 1401 MaybeObject* JSObject::ResetElements() { | 1391 MaybeObject* JSObject::ResetElements() { |
| 1402 Object* obj; | 1392 Object* obj; |
| 1403 ElementsKind elements_kind = FLAG_smi_only_arrays | 1393 ElementsKind elements_kind = GetInitialFastElementsKind(); |
| 1404 ? FAST_SMI_ONLY_ELEMENTS | 1394 if (!FLAG_smi_only_arrays) { |
| 1405 : FAST_ELEMENTS; | 1395 elements_kind = FastSmiToObjectElementsKind(elements_kind); |
| 1396 } |
| 1406 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), | 1397 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), |
| 1407 elements_kind); | 1398 elements_kind); |
| 1408 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1399 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1409 set_map(Map::cast(obj)); | 1400 set_map(Map::cast(obj)); |
| 1410 initialize_elements(); | 1401 initialize_elements(); |
| 1411 return this; | 1402 return this; |
| 1412 } | 1403 } |
| 1413 | 1404 |
| 1414 | 1405 |
| 1415 ACCESSORS(Oddball, to_string, String, kToStringOffset) | 1406 ACCESSORS(Oddball, to_string, String, kToStringOffset) |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1667 return reinterpret_cast<FixedArrayBase*>(object); | 1658 return reinterpret_cast<FixedArrayBase*>(object); |
| 1668 } | 1659 } |
| 1669 | 1660 |
| 1670 | 1661 |
| 1671 Object* FixedArray::get(int index) { | 1662 Object* FixedArray::get(int index) { |
| 1672 ASSERT(index >= 0 && index < this->length()); | 1663 ASSERT(index >= 0 && index < this->length()); |
| 1673 return READ_FIELD(this, kHeaderSize + index * kPointerSize); | 1664 return READ_FIELD(this, kHeaderSize + index * kPointerSize); |
| 1674 } | 1665 } |
| 1675 | 1666 |
| 1676 | 1667 |
| 1668 bool FixedArray::is_the_hole(int index) { |
| 1669 ASSERT(index >= 0 && index < this->length()); |
| 1670 return get(index) == GetHeap()->the_hole_value(); |
| 1671 } |
| 1672 |
| 1673 |
| 1677 void FixedArray::set(int index, Smi* value) { | 1674 void FixedArray::set(int index, Smi* value) { |
| 1678 ASSERT(map() != HEAP->fixed_cow_array_map()); | 1675 ASSERT(map() != HEAP->fixed_cow_array_map()); |
| 1679 ASSERT(index >= 0 && index < this->length()); | 1676 ASSERT(index >= 0 && index < this->length()); |
| 1680 ASSERT(reinterpret_cast<Object*>(value)->IsSmi()); | 1677 ASSERT(reinterpret_cast<Object*>(value)->IsSmi()); |
| 1681 int offset = kHeaderSize + index * kPointerSize; | 1678 int offset = kHeaderSize + index * kPointerSize; |
| 1682 WRITE_FIELD(this, offset, value); | 1679 WRITE_FIELD(this, offset, value); |
| 1683 } | 1680 } |
| 1684 | 1681 |
| 1685 | 1682 |
| 1686 void FixedArray::set(int index, Object* value) { | 1683 void FixedArray::set(int index, Object* value) { |
| (...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2848 } | 2845 } |
| 2849 | 2846 |
| 2850 | 2847 |
| 2851 bool Map::has_non_instance_prototype() { | 2848 bool Map::has_non_instance_prototype() { |
| 2852 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0; | 2849 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0; |
| 2853 } | 2850 } |
| 2854 | 2851 |
| 2855 | 2852 |
| 2856 void Map::set_function_with_prototype(bool value) { | 2853 void Map::set_function_with_prototype(bool value) { |
| 2857 if (value) { | 2854 if (value) { |
| 2858 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype)); | 2855 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype)); |
| 2859 } else { | 2856 } else { |
| 2860 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype)); | 2857 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype)); |
| 2861 } | 2858 } |
| 2862 } | 2859 } |
| 2863 | 2860 |
| 2864 | 2861 |
| 2865 bool Map::function_with_prototype() { | 2862 bool Map::function_with_prototype() { |
| 2866 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0; | 2863 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0; |
| 2867 } | 2864 } |
| 2868 | 2865 |
| 2869 | 2866 |
| 2870 void Map::set_is_access_check_needed(bool access_check_needed) { | 2867 void Map::set_is_access_check_needed(bool access_check_needed) { |
| 2871 if (access_check_needed) { | 2868 if (access_check_needed) { |
| 2872 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded)); | 2869 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded)); |
| 2873 } else { | 2870 } else { |
| 2874 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded)); | 2871 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded)); |
| 2875 } | 2872 } |
| 2876 } | 2873 } |
| (...skipping 1063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3940 } | 3937 } |
| 3941 | 3938 |
| 3942 | 3939 |
| 3943 MaybeObject* JSFunction::set_initial_map_and_cache_transitions( | 3940 MaybeObject* JSFunction::set_initial_map_and_cache_transitions( |
| 3944 Map* initial_map) { | 3941 Map* initial_map) { |
| 3945 Context* global_context = context()->global_context(); | 3942 Context* global_context = context()->global_context(); |
| 3946 Object* array_function = | 3943 Object* array_function = |
| 3947 global_context->get(Context::ARRAY_FUNCTION_INDEX); | 3944 global_context->get(Context::ARRAY_FUNCTION_INDEX); |
| 3948 if (array_function->IsJSFunction() && | 3945 if (array_function->IsJSFunction() && |
| 3949 this == JSFunction::cast(array_function)) { | 3946 this == JSFunction::cast(array_function)) { |
| 3950 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); | 3947 // Replace all of the cached initial array maps in the global context with |
| 3948 // the appropriate transitioned elements kind maps. |
| 3949 Heap* heap = GetHeap(); |
| 3950 MaybeObject* maybe_maps = |
| 3951 heap->AllocateFixedArrayWithHoles(kElementsKindCount); |
| 3952 FixedArray* maps; |
| 3953 if (!maybe_maps->To(&maps)) return maybe_maps; |
| 3951 | 3954 |
| 3952 MaybeObject* maybe_map = initial_map->CopyDropTransitions(); | 3955 Map* current_map = initial_map; |
| 3953 Map* new_double_map = NULL; | 3956 ASSERT(current_map->elements_kind() == FIRST_FAST_ELEMENTS_KIND); |
| 3954 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map; | 3957 maps->set(FIRST_FAST_ELEMENTS_KIND, current_map); |
| 3955 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS); | 3958 for (int i = 1; i < kFastElementsKindCount; ++i) { |
| 3956 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, | 3959 ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i); |
| 3957 new_double_map); | 3960 MaybeObject* maybe_new_map = current_map->CopyDropTransitions(); |
| 3958 if (maybe_map->IsFailure()) return maybe_map; | 3961 Map* new_map = NULL; |
| 3959 | 3962 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map; |
| 3960 maybe_map = new_double_map->CopyDropTransitions(); | 3963 new_map->set_elements_kind(transitioned_kind); |
| 3961 Map* new_object_map = NULL; | 3964 maybe_new_map = current_map->AddElementsTransition(transitioned_kind, |
| 3962 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map; | 3965 new_map); |
| 3963 new_object_map->set_elements_kind(FAST_ELEMENTS); | 3966 if (maybe_new_map->IsFailure()) return maybe_new_map; |
| 3964 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS, | 3967 maps->set(transitioned_kind, new_map); |
| 3965 new_object_map); | 3968 current_map = new_map; |
| 3966 if (maybe_map->IsFailure()) return maybe_map; | 3969 } |
| 3967 | 3970 global_context->set_js_array_maps(maps); |
| 3968 global_context->set_smi_js_array_map(initial_map); | |
| 3969 global_context->set_double_js_array_map(new_double_map); | |
| 3970 global_context->set_object_js_array_map(new_object_map); | |
| 3971 } | 3971 } |
| 3972 set_initial_map(initial_map); | 3972 set_initial_map(initial_map); |
| 3973 return this; | 3973 return this; |
| 3974 } | 3974 } |
| 3975 | 3975 |
| 3976 | 3976 |
| 3977 bool JSFunction::has_initial_map() { | 3977 bool JSFunction::has_initial_map() { |
| 3978 return prototype_or_initial_map()->IsMap(); | 3978 return prototype_or_initial_map()->IsMap(); |
| 3979 } | 3979 } |
| 3980 | 3980 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4296 } | 4296 } |
| 4297 } | 4297 } |
| 4298 | 4298 |
| 4299 | 4299 |
| 4300 ElementsKind JSObject::GetElementsKind() { | 4300 ElementsKind JSObject::GetElementsKind() { |
| 4301 ElementsKind kind = map()->elements_kind(); | 4301 ElementsKind kind = map()->elements_kind(); |
| 4302 #if DEBUG | 4302 #if DEBUG |
| 4303 FixedArrayBase* fixed_array = | 4303 FixedArrayBase* fixed_array = |
| 4304 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); | 4304 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); |
| 4305 Map* map = fixed_array->map(); | 4305 Map* map = fixed_array->map(); |
| 4306 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && | 4306 ASSERT((IsFastSmiOrObjectElementsKind(kind) && |
| 4307 (map == GetHeap()->fixed_array_map() || | 4307 (map == GetHeap()->fixed_array_map() || |
| 4308 map == GetHeap()->fixed_cow_array_map())) || | 4308 map == GetHeap()->fixed_cow_array_map())) || |
| 4309 (kind == FAST_DOUBLE_ELEMENTS && | 4309 (IsFastDoubleElementsKind(kind) && |
| 4310 (fixed_array->IsFixedDoubleArray() || | 4310 (fixed_array->IsFixedDoubleArray() || |
| 4311 fixed_array == GetHeap()->empty_fixed_array())) || | 4311 fixed_array == GetHeap()->empty_fixed_array())) || |
| 4312 (kind == DICTIONARY_ELEMENTS && | 4312 (kind == DICTIONARY_ELEMENTS && |
| 4313 fixed_array->IsFixedArray() && | 4313 fixed_array->IsFixedArray() && |
| 4314 fixed_array->IsDictionary()) || | 4314 fixed_array->IsDictionary()) || |
| 4315 (kind > DICTIONARY_ELEMENTS)); | 4315 (kind > DICTIONARY_ELEMENTS)); |
| 4316 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || | 4316 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || |
| 4317 (elements()->IsFixedArray() && elements()->length() >= 2)); | 4317 (elements()->IsFixedArray() && elements()->length() >= 2)); |
| 4318 #endif | 4318 #endif |
| 4319 return kind; | 4319 return kind; |
| 4320 } | 4320 } |
| 4321 | 4321 |
| 4322 | 4322 |
| 4323 ElementsAccessor* JSObject::GetElementsAccessor() { | 4323 ElementsAccessor* JSObject::GetElementsAccessor() { |
| 4324 return ElementsAccessor::ForKind(GetElementsKind()); | 4324 return ElementsAccessor::ForKind(GetElementsKind()); |
| 4325 } | 4325 } |
| 4326 | 4326 |
| 4327 | 4327 |
| 4328 bool JSObject::HasFastElements() { | 4328 bool JSObject::HasFastObjectElements() { |
| 4329 return GetElementsKind() == FAST_ELEMENTS; | 4329 return IsFastObjectElementsKind(GetElementsKind()); |
| 4330 } | 4330 } |
| 4331 | 4331 |
| 4332 | 4332 |
| 4333 bool JSObject::HasFastSmiOnlyElements() { | 4333 bool JSObject::HasFastSmiElements() { |
| 4334 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS; | 4334 return IsFastSmiElementsKind(GetElementsKind()); |
| 4335 } | 4335 } |
| 4336 | 4336 |
| 4337 | 4337 |
| 4338 bool JSObject::HasFastTypeElements() { | 4338 bool JSObject::HasFastSmiOrObjectElements() { |
| 4339 ElementsKind elements_kind = GetElementsKind(); | 4339 return IsFastSmiOrObjectElementsKind(GetElementsKind()); |
| 4340 return elements_kind == FAST_SMI_ONLY_ELEMENTS || | |
| 4341 elements_kind == FAST_ELEMENTS; | |
| 4342 } | 4340 } |
| 4343 | 4341 |
| 4344 | 4342 |
| 4345 bool JSObject::HasFastDoubleElements() { | 4343 bool JSObject::HasFastDoubleElements() { |
| 4346 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; | 4344 return IsFastDoubleElementsKind(GetElementsKind()); |
| 4347 } | 4345 } |
| 4348 | 4346 |
| 4349 | 4347 |
| 4348 bool JSObject::HasFastHoleyElements() { |
| 4349 return IsFastHoleyElementsKind(GetElementsKind()); |
| 4350 } |
| 4351 |
| 4352 |
| 4350 bool JSObject::HasDictionaryElements() { | 4353 bool JSObject::HasDictionaryElements() { |
| 4351 return GetElementsKind() == DICTIONARY_ELEMENTS; | 4354 return GetElementsKind() == DICTIONARY_ELEMENTS; |
| 4352 } | 4355 } |
| 4353 | 4356 |
| 4354 | 4357 |
| 4355 bool JSObject::HasNonStrictArgumentsElements() { | 4358 bool JSObject::HasNonStrictArgumentsElements() { |
| 4356 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS; | 4359 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS; |
| 4357 } | 4360 } |
| 4358 | 4361 |
| 4359 | 4362 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4393 return map()->has_named_interceptor(); | 4396 return map()->has_named_interceptor(); |
| 4394 } | 4397 } |
| 4395 | 4398 |
| 4396 | 4399 |
| 4397 bool JSObject::HasIndexedInterceptor() { | 4400 bool JSObject::HasIndexedInterceptor() { |
| 4398 return map()->has_indexed_interceptor(); | 4401 return map()->has_indexed_interceptor(); |
| 4399 } | 4402 } |
| 4400 | 4403 |
| 4401 | 4404 |
| 4402 MaybeObject* JSObject::EnsureWritableFastElements() { | 4405 MaybeObject* JSObject::EnsureWritableFastElements() { |
| 4403 ASSERT(HasFastTypeElements()); | 4406 ASSERT(HasFastSmiOrObjectElements()); |
| 4404 FixedArray* elems = FixedArray::cast(elements()); | 4407 FixedArray* elems = FixedArray::cast(elements()); |
| 4405 Isolate* isolate = GetIsolate(); | 4408 Isolate* isolate = GetIsolate(); |
| 4406 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; | 4409 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
| 4407 Object* writable_elems; | 4410 Object* writable_elems; |
| 4408 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( | 4411 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( |
| 4409 elems, isolate->heap()->fixed_array_map()); | 4412 elems, isolate->heap()->fixed_array_map()); |
| 4410 if (!maybe_writable_elems->ToObject(&writable_elems)) { | 4413 if (!maybe_writable_elems->ToObject(&writable_elems)) { |
| 4411 return maybe_writable_elems; | 4414 return maybe_writable_elems; |
| 4412 } | 4415 } |
| 4413 } | 4416 } |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4751 // No write barrier is needed since empty_fixed_array is not in new space. | 4754 // No write barrier is needed since empty_fixed_array is not in new space. |
| 4752 // Please note this function is used during marking: | 4755 // Please note this function is used during marking: |
| 4753 // - MarkCompactCollector::MarkUnmarkedObject | 4756 // - MarkCompactCollector::MarkUnmarkedObject |
| 4754 // - IncrementalMarking::Step | 4757 // - IncrementalMarking::Step |
| 4755 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); | 4758 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); |
| 4756 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); | 4759 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); |
| 4757 } | 4760 } |
| 4758 | 4761 |
| 4759 | 4762 |
| 4760 void JSArray::EnsureSize(int required_size) { | 4763 void JSArray::EnsureSize(int required_size) { |
| 4761 ASSERT(HasFastTypeElements()); | 4764 ASSERT(HasFastSmiOrObjectElements()); |
| 4762 FixedArray* elts = FixedArray::cast(elements()); | 4765 FixedArray* elts = FixedArray::cast(elements()); |
| 4763 const int kArraySizeThatFitsComfortablyInNewSpace = 128; | 4766 const int kArraySizeThatFitsComfortablyInNewSpace = 128; |
| 4764 if (elts->length() < required_size) { | 4767 if (elts->length() < required_size) { |
| 4765 // Doubling in size would be overkill, but leave some slack to avoid | 4768 // Doubling in size would be overkill, but leave some slack to avoid |
| 4766 // constantly growing. | 4769 // constantly growing. |
| 4767 Expand(required_size + (required_size >> 3)); | 4770 Expand(required_size + (required_size >> 3)); |
| 4768 // It's a performance benefit to keep a frequently used array in new-space. | 4771 // It's a performance benefit to keep a frequently used array in new-space. |
| 4769 } else if (!GetHeap()->new_space()->Contains(elts) && | 4772 } else if (!GetHeap()->new_space()->Contains(elts) && |
| 4770 required_size < kArraySizeThatFitsComfortablyInNewSpace) { | 4773 required_size < kArraySizeThatFitsComfortablyInNewSpace) { |
| 4771 // Expand will allocate a new backing store in new space even if the size | 4774 // Expand will allocate a new backing store in new space even if the size |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4783 | 4786 |
| 4784 bool JSArray::AllowsSetElementsLength() { | 4787 bool JSArray::AllowsSetElementsLength() { |
| 4785 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray(); | 4788 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray(); |
| 4786 ASSERT(result == !HasExternalArrayElements()); | 4789 ASSERT(result == !HasExternalArrayElements()); |
| 4787 return result; | 4790 return result; |
| 4788 } | 4791 } |
| 4789 | 4792 |
| 4790 | 4793 |
| 4791 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { | 4794 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { |
| 4792 MaybeObject* maybe_result = EnsureCanContainElements( | 4795 MaybeObject* maybe_result = EnsureCanContainElements( |
| 4793 storage, ALLOW_COPIED_DOUBLE_ELEMENTS); | 4796 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS); |
| 4794 if (maybe_result->IsFailure()) return maybe_result; | 4797 if (maybe_result->IsFailure()) return maybe_result; |
| 4795 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && | 4798 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && |
| 4796 GetElementsKind() == FAST_DOUBLE_ELEMENTS) || | 4799 IsFastDoubleElementsKind(GetElementsKind())) || |
| 4797 ((storage->map() != GetHeap()->fixed_double_array_map()) && | 4800 ((storage->map() != GetHeap()->fixed_double_array_map()) && |
| 4798 ((GetElementsKind() == FAST_ELEMENTS) || | 4801 (IsFastObjectElementsKind(GetElementsKind()) || |
| 4799 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS && | 4802 (IsFastElementsKind(GetElementsKind()) && |
| 4800 FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); | 4803 FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); |
| 4801 set_elements(storage); | 4804 set_elements(storage); |
| 4802 set_length(Smi::FromInt(storage->length())); | 4805 set_length(Smi::FromInt(storage->length())); |
| 4803 return this; | 4806 return this; |
| 4804 } | 4807 } |
| 4805 | 4808 |
| 4806 | 4809 |
| 4807 MaybeObject* FixedArray::Copy() { | 4810 MaybeObject* FixedArray::Copy() { |
| 4808 if (length() == 0) return this; | 4811 if (length() == 0) return this; |
| 4809 return GetHeap()->CopyFixedArray(this); | 4812 return GetHeap()->CopyFixedArray(this); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4966 #undef WRITE_UINT32_FIELD | 4969 #undef WRITE_UINT32_FIELD |
| 4967 #undef READ_SHORT_FIELD | 4970 #undef READ_SHORT_FIELD |
| 4968 #undef WRITE_SHORT_FIELD | 4971 #undef WRITE_SHORT_FIELD |
| 4969 #undef READ_BYTE_FIELD | 4972 #undef READ_BYTE_FIELD |
| 4970 #undef WRITE_BYTE_FIELD | 4973 #undef WRITE_BYTE_FIELD |
| 4971 | 4974 |
| 4972 | 4975 |
| 4973 } } // namespace v8::internal | 4976 } } // namespace v8::internal |
| 4974 | 4977 |
| 4975 #endif // V8_OBJECTS_INL_H_ | 4978 #endif // V8_OBJECTS_INL_H_ |
| OLD | NEW |