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

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

Issue 10209027: Implement tracking and optimizations of packed arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: New upload Created 8 years, 7 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 | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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_
OLDNEW
« src/objects.cc ('K') | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698