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

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

Issue 10170030: Implement tracking and optimizations of packed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Platforms ports and review feedback 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() { 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 = global_context->js_array_maps();
1342 if (to_kind == FAST_ELEMENTS) { 1343 if (maybe_array_maps->IsFixedArray()) {
1343 return global_context->object_js_array_map(); 1344 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1344 } else { 1345 if (array_maps->get(from_kind) == current_map) {
1345 if (to_kind == FAST_DOUBLE_ELEMENTS) { 1346 Object* maybe_transitioned_map = array_maps->get(to_kind);
1346 return global_context->double_js_array_map(); 1347 if (maybe_transitioned_map->IsMap()) {
1347 } else { 1348 return Map::cast(maybe_transitioned_map);
1348 ASSERT(to_kind == DICTIONARY_ELEMENTS);
1349 } 1349 }
1350 } 1350 }
1351 } 1351 }
1352
1352 return GetElementsTransitionMapSlow(to_kind); 1353 return GetElementsTransitionMapSlow(to_kind);
1353 } 1354 }
1354 1355
1355 1356
1356 void JSObject::set_map_and_elements(Map* new_map, 1357 void JSObject::set_map_and_elements(Map* new_map,
1357 FixedArrayBase* value, 1358 FixedArrayBase* value,
1358 WriteBarrierMode mode) { 1359 WriteBarrierMode mode) {
1359 ASSERT(value->HasValidElements()); 1360 ASSERT(value->HasValidElements());
1360 #ifdef DEBUG
1361 ValidateSmiOnlyElements();
1362 #endif
1363 if (new_map != NULL) { 1361 if (new_map != NULL) {
1364 if (mode == UPDATE_WRITE_BARRIER) { 1362 if (mode == UPDATE_WRITE_BARRIER) {
1365 set_map(new_map); 1363 set_map(new_map);
1366 } else { 1364 } else {
1367 ASSERT(mode == SKIP_WRITE_BARRIER); 1365 ASSERT(mode == SKIP_WRITE_BARRIER);
1368 set_map_no_write_barrier(new_map); 1366 set_map_no_write_barrier(new_map);
1369 } 1367 }
1370 } 1368 }
1371 ASSERT((map()->has_fast_elements() || 1369 ASSERT((map()->has_fast_smi_or_object_elements() ||
1372 map()->has_fast_smi_only_elements() ||
1373 (value == GetHeap()->empty_fixed_array())) == 1370 (value == GetHeap()->empty_fixed_array())) ==
1374 (value->map() == GetHeap()->fixed_array_map() || 1371 (value->map() == GetHeap()->fixed_array_map() ||
1375 value->map() == GetHeap()->fixed_cow_array_map())); 1372 value->map() == GetHeap()->fixed_cow_array_map()));
1376 ASSERT((value == GetHeap()->empty_fixed_array()) || 1373 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1377 (map()->has_fast_double_elements() == value->IsFixedDoubleArray())); 1374 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
1378 WRITE_FIELD(this, kElementsOffset, value); 1375 WRITE_FIELD(this, kElementsOffset, value);
1379 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode); 1376 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
1380 } 1377 }
1381 1378
1382 1379
1383 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { 1380 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1384 set_map_and_elements(NULL, value, mode); 1381 set_map_and_elements(NULL, value, mode);
1385 } 1382 }
1386 1383
1387 1384
1388 void JSObject::initialize_properties() { 1385 void JSObject::initialize_properties() {
1389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 1386 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1390 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); 1387 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
1391 } 1388 }
1392 1389
1393 1390
1394 void JSObject::initialize_elements() { 1391 void JSObject::initialize_elements() {
1395 ASSERT(map()->has_fast_elements() || 1392 ASSERT(map()->has_fast_smi_or_object_elements() ||
1396 map()->has_fast_smi_only_elements() ||
1397 map()->has_fast_double_elements()); 1393 map()->has_fast_double_elements());
1398 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 1394 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1399 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); 1395 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
1400 } 1396 }
1401 1397
1402 1398
1403 MaybeObject* JSObject::ResetElements() { 1399 MaybeObject* JSObject::ResetElements() {
1404 Object* obj; 1400 Object* obj;
1405 ElementsKind elements_kind = FLAG_smi_only_arrays 1401 ElementsKind elements_kind = GetInitialFastElementsKind();
1406 ? FAST_SMI_ONLY_ELEMENTS 1402 if (!FLAG_smi_only_arrays) {
1407 : FAST_ELEMENTS; 1403 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1404 }
1408 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), 1405 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1409 elements_kind); 1406 elements_kind);
1410 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1407 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1411 set_map(Map::cast(obj)); 1408 set_map(Map::cast(obj));
1412 initialize_elements(); 1409 initialize_elements();
1413 return this; 1410 return this;
1414 } 1411 }
1415 1412
1416 1413
1417 ACCESSORS(Oddball, to_string, String, kToStringOffset) 1414 ACCESSORS(Oddball, to_string, String, kToStringOffset)
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1669 return reinterpret_cast<FixedArrayBase*>(object); 1666 return reinterpret_cast<FixedArrayBase*>(object);
1670 } 1667 }
1671 1668
1672 1669
1673 Object* FixedArray::get(int index) { 1670 Object* FixedArray::get(int index) {
1674 ASSERT(index >= 0 && index < this->length()); 1671 ASSERT(index >= 0 && index < this->length());
1675 return READ_FIELD(this, kHeaderSize + index * kPointerSize); 1672 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1676 } 1673 }
1677 1674
1678 1675
1676 bool FixedArray::is_the_hole(int index) {
1677 return get(index) == GetHeap()->the_hole_value();
1678 }
1679
1680
1679 void FixedArray::set(int index, Smi* value) { 1681 void FixedArray::set(int index, Smi* value) {
1680 ASSERT(map() != HEAP->fixed_cow_array_map()); 1682 ASSERT(map() != HEAP->fixed_cow_array_map());
1681 ASSERT(index >= 0 && index < this->length()); 1683 ASSERT(index >= 0 && index < this->length());
1682 ASSERT(reinterpret_cast<Object*>(value)->IsSmi()); 1684 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1683 int offset = kHeaderSize + index * kPointerSize; 1685 int offset = kHeaderSize + index * kPointerSize;
1684 WRITE_FIELD(this, offset, value); 1686 WRITE_FIELD(this, offset, value);
1685 } 1687 }
1686 1688
1687 1689
1688 void FixedArray::set(int index, Object* value) { 1690 void FixedArray::set(int index, Object* value) {
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2850 } 2852 }
2851 2853
2852 2854
2853 bool Map::has_non_instance_prototype() { 2855 bool Map::has_non_instance_prototype() {
2854 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0; 2856 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2855 } 2857 }
2856 2858
2857 2859
2858 void Map::set_function_with_prototype(bool value) { 2860 void Map::set_function_with_prototype(bool value) {
2859 if (value) { 2861 if (value) {
2860 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype)); 2862 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
2861 } else { 2863 } else {
2862 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype)); 2864 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
2863 } 2865 }
2864 } 2866 }
2865 2867
2866 2868
2867 bool Map::function_with_prototype() { 2869 bool Map::function_with_prototype() {
2868 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0; 2870 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
2869 } 2871 }
2870 2872
2871 2873
2872 void Map::set_is_access_check_needed(bool access_check_needed) { 2874 void Map::set_is_access_check_needed(bool access_check_needed) {
2873 if (access_check_needed) { 2875 if (access_check_needed) {
2874 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded)); 2876 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2875 } else { 2877 } else {
2876 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded)); 2878 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2877 } 2879 }
2878 } 2880 }
(...skipping 1109 matching lines...) Expand 10 before | Expand all | Expand 10 after
3988 } 3990 }
3989 3991
3990 3992
3991 MaybeObject* JSFunction::set_initial_map_and_cache_transitions( 3993 MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3992 Map* initial_map) { 3994 Map* initial_map) {
3993 Context* global_context = context()->global_context(); 3995 Context* global_context = context()->global_context();
3994 Object* array_function = 3996 Object* array_function =
3995 global_context->get(Context::ARRAY_FUNCTION_INDEX); 3997 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3996 if (array_function->IsJSFunction() && 3998 if (array_function->IsJSFunction() &&
3997 this == JSFunction::cast(array_function)) { 3999 this == JSFunction::cast(array_function)) {
3998 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); 4000 // Replace all of the cached initial array maps in the global context with
4001 // the appropriate transitioned elements kind maps.
4002 Heap* heap = GetHeap();
4003 MaybeObject* maybe_maps =
4004 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4005 FixedArray* maps;
4006 if (!maybe_maps->To(&maps)) return maybe_maps;
3999 4007
4000 MaybeObject* maybe_map = initial_map->CopyDropTransitions(); 4008 Map* current_map = initial_map;
4001 Map* new_double_map = NULL; 4009 ElementsKind kind = current_map->elements_kind();
4002 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map; 4010 ASSERT(kind == GetInitialFastElementsKind());
4003 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS); 4011 maps->set(kind, current_map);
4004 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, 4012 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4005 new_double_map); 4013 i < kFastElementsKindCount; ++i) {
4006 if (maybe_map->IsFailure()) return maybe_map; 4014 ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i);
4007 4015 MaybeObject* maybe_new_map = current_map->CopyDropTransitions();
4008 maybe_map = new_double_map->CopyDropTransitions(); 4016 Map* new_map = NULL;
4009 Map* new_object_map = NULL; 4017 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
4010 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map; 4018 new_map->set_elements_kind(transitioned_kind);
4011 new_object_map->set_elements_kind(FAST_ELEMENTS); 4019 maybe_new_map = current_map->AddElementsTransition(transitioned_kind,
4012 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS, 4020 new_map);
4013 new_object_map); 4021 if (maybe_new_map->IsFailure()) return maybe_new_map;
4014 if (maybe_map->IsFailure()) return maybe_map; 4022 maps->set(transitioned_kind, new_map);
4015 4023 current_map = new_map;
4016 global_context->set_smi_js_array_map(initial_map); 4024 }
4017 global_context->set_double_js_array_map(new_double_map); 4025 global_context->set_js_array_maps(maps);
4018 global_context->set_object_js_array_map(new_object_map);
4019 } 4026 }
4020 set_initial_map(initial_map); 4027 set_initial_map(initial_map);
4021 return this; 4028 return this;
4022 } 4029 }
4023 4030
4024 4031
4025 bool JSFunction::has_initial_map() { 4032 bool JSFunction::has_initial_map() {
4026 return prototype_or_initial_map()->IsMap(); 4033 return prototype_or_initial_map()->IsMap();
4027 } 4034 }
4028 4035
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
4344 } 4351 }
4345 } 4352 }
4346 4353
4347 4354
4348 ElementsKind JSObject::GetElementsKind() { 4355 ElementsKind JSObject::GetElementsKind() {
4349 ElementsKind kind = map()->elements_kind(); 4356 ElementsKind kind = map()->elements_kind();
4350 #if DEBUG 4357 #if DEBUG
4351 FixedArrayBase* fixed_array = 4358 FixedArrayBase* fixed_array =
4352 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); 4359 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4353 Map* map = fixed_array->map(); 4360 Map* map = fixed_array->map();
4354 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && 4361 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4355 (map == GetHeap()->fixed_array_map() || 4362 (map == GetHeap()->fixed_array_map() ||
4356 map == GetHeap()->fixed_cow_array_map())) || 4363 map == GetHeap()->fixed_cow_array_map())) ||
4357 (kind == FAST_DOUBLE_ELEMENTS && 4364 (IsFastDoubleElementsKind(kind) &&
4358 (fixed_array->IsFixedDoubleArray() || 4365 (fixed_array->IsFixedDoubleArray() ||
4359 fixed_array == GetHeap()->empty_fixed_array())) || 4366 fixed_array == GetHeap()->empty_fixed_array())) ||
4360 (kind == DICTIONARY_ELEMENTS && 4367 (kind == DICTIONARY_ELEMENTS &&
4361 fixed_array->IsFixedArray() && 4368 fixed_array->IsFixedArray() &&
4362 fixed_array->IsDictionary()) || 4369 fixed_array->IsDictionary()) ||
4363 (kind > DICTIONARY_ELEMENTS)); 4370 (kind > DICTIONARY_ELEMENTS));
4364 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || 4371 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4365 (elements()->IsFixedArray() && elements()->length() >= 2)); 4372 (elements()->IsFixedArray() && elements()->length() >= 2));
4366 #endif 4373 #endif
4367 return kind; 4374 return kind;
4368 } 4375 }
4369 4376
4370 4377
4371 ElementsAccessor* JSObject::GetElementsAccessor() { 4378 ElementsAccessor* JSObject::GetElementsAccessor() {
4372 return ElementsAccessor::ForKind(GetElementsKind()); 4379 return ElementsAccessor::ForKind(GetElementsKind());
4373 } 4380 }
4374 4381
4375 4382
4376 bool JSObject::HasFastElements() { 4383 bool JSObject::HasFastObjectElements() {
4377 return GetElementsKind() == FAST_ELEMENTS; 4384 return IsFastObjectElementsKind(GetElementsKind());
4378 } 4385 }
4379 4386
4380 4387
4381 bool JSObject::HasFastSmiOnlyElements() { 4388 bool JSObject::HasFastSmiElements() {
4382 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS; 4389 return IsFastSmiElementsKind(GetElementsKind());
4383 } 4390 }
4384 4391
4385 4392
4386 bool JSObject::HasFastTypeElements() { 4393 bool JSObject::HasFastSmiOrObjectElements() {
4387 ElementsKind elements_kind = GetElementsKind(); 4394 return IsFastSmiOrObjectElementsKind(GetElementsKind());
4388 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4389 elements_kind == FAST_ELEMENTS;
4390 } 4395 }
4391 4396
4392 4397
4393 bool JSObject::HasFastDoubleElements() { 4398 bool JSObject::HasFastDoubleElements() {
4394 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; 4399 return IsFastDoubleElementsKind(GetElementsKind());
4395 } 4400 }
4396 4401
4397 4402
4403 bool JSObject::HasFastHoleyElements() {
4404 return IsFastHoleyElementsKind(GetElementsKind());
4405 }
4406
4407
4398 bool JSObject::HasDictionaryElements() { 4408 bool JSObject::HasDictionaryElements() {
4399 return GetElementsKind() == DICTIONARY_ELEMENTS; 4409 return GetElementsKind() == DICTIONARY_ELEMENTS;
4400 } 4410 }
4401 4411
4402 4412
4403 bool JSObject::HasNonStrictArgumentsElements() { 4413 bool JSObject::HasNonStrictArgumentsElements() {
4404 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS; 4414 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4405 } 4415 }
4406 4416
4407 4417
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4441 return map()->has_named_interceptor(); 4451 return map()->has_named_interceptor();
4442 } 4452 }
4443 4453
4444 4454
4445 bool JSObject::HasIndexedInterceptor() { 4455 bool JSObject::HasIndexedInterceptor() {
4446 return map()->has_indexed_interceptor(); 4456 return map()->has_indexed_interceptor();
4447 } 4457 }
4448 4458
4449 4459
4450 MaybeObject* JSObject::EnsureWritableFastElements() { 4460 MaybeObject* JSObject::EnsureWritableFastElements() {
4451 ASSERT(HasFastTypeElements()); 4461 ASSERT(HasFastSmiOrObjectElements());
4452 FixedArray* elems = FixedArray::cast(elements()); 4462 FixedArray* elems = FixedArray::cast(elements());
4453 Isolate* isolate = GetIsolate(); 4463 Isolate* isolate = GetIsolate();
4454 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; 4464 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
4455 Object* writable_elems; 4465 Object* writable_elems;
4456 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( 4466 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4457 elems, isolate->heap()->fixed_array_map()); 4467 elems, isolate->heap()->fixed_array_map());
4458 if (!maybe_writable_elems->ToObject(&writable_elems)) { 4468 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4459 return maybe_writable_elems; 4469 return maybe_writable_elems;
4460 } 4470 }
4461 } 4471 }
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
4799 // No write barrier is needed since empty_fixed_array is not in new space. 4809 // No write barrier is needed since empty_fixed_array is not in new space.
4800 // Please note this function is used during marking: 4810 // Please note this function is used during marking:
4801 // - MarkCompactCollector::MarkUnmarkedObject 4811 // - MarkCompactCollector::MarkUnmarkedObject
4802 // - IncrementalMarking::Step 4812 // - IncrementalMarking::Step
4803 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); 4813 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4804 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); 4814 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
4805 } 4815 }
4806 4816
4807 4817
4808 void JSArray::EnsureSize(int required_size) { 4818 void JSArray::EnsureSize(int required_size) {
4809 ASSERT(HasFastTypeElements()); 4819 ASSERT(HasFastSmiOrObjectElements());
4810 FixedArray* elts = FixedArray::cast(elements()); 4820 FixedArray* elts = FixedArray::cast(elements());
4811 const int kArraySizeThatFitsComfortablyInNewSpace = 128; 4821 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4812 if (elts->length() < required_size) { 4822 if (elts->length() < required_size) {
4813 // Doubling in size would be overkill, but leave some slack to avoid 4823 // Doubling in size would be overkill, but leave some slack to avoid
4814 // constantly growing. 4824 // constantly growing.
4815 Expand(required_size + (required_size >> 3)); 4825 Expand(required_size + (required_size >> 3));
4816 // It's a performance benefit to keep a frequently used array in new-space. 4826 // It's a performance benefit to keep a frequently used array in new-space.
4817 } else if (!GetHeap()->new_space()->Contains(elts) && 4827 } else if (!GetHeap()->new_space()->Contains(elts) &&
4818 required_size < kArraySizeThatFitsComfortablyInNewSpace) { 4828 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4819 // Expand will allocate a new backing store in new space even if the size 4829 // Expand will allocate a new backing store in new space even if the size
(...skipping 11 matching lines...) Expand all
4831 4841
4832 bool JSArray::AllowsSetElementsLength() { 4842 bool JSArray::AllowsSetElementsLength() {
4833 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray(); 4843 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4834 ASSERT(result == !HasExternalArrayElements()); 4844 ASSERT(result == !HasExternalArrayElements());
4835 return result; 4845 return result;
4836 } 4846 }
4837 4847
4838 4848
4839 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { 4849 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4840 MaybeObject* maybe_result = EnsureCanContainElements( 4850 MaybeObject* maybe_result = EnsureCanContainElements(
4841 storage, ALLOW_COPIED_DOUBLE_ELEMENTS); 4851 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
4842 if (maybe_result->IsFailure()) return maybe_result; 4852 if (maybe_result->IsFailure()) return maybe_result;
4843 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && 4853 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4844 GetElementsKind() == FAST_DOUBLE_ELEMENTS) || 4854 IsFastDoubleElementsKind(GetElementsKind())) ||
4845 ((storage->map() != GetHeap()->fixed_double_array_map()) && 4855 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4846 ((GetElementsKind() == FAST_ELEMENTS) || 4856 (IsFastObjectElementsKind(GetElementsKind()) ||
4847 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS && 4857 (IsFastSmiElementsKind(GetElementsKind()) &&
Jakob Kummerow 2012/05/22 17:36:49 nit: could just use IsFastSmiOrObjectElementsKind
danno 2012/05/23 14:25:36 That's a little bit different. The () make sure th
4848 FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); 4858 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
4849 set_elements(storage); 4859 set_elements(storage);
4850 set_length(Smi::FromInt(storage->length())); 4860 set_length(Smi::FromInt(storage->length()));
4851 return this; 4861 return this;
4852 } 4862 }
4853 4863
4854 4864
4855 MaybeObject* FixedArray::Copy() { 4865 MaybeObject* FixedArray::Copy() {
4856 if (length() == 0) return this; 4866 if (length() == 0) return this;
4857 return GetHeap()->CopyFixedArray(this); 4867 return GetHeap()->CopyFixedArray(this);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
5014 #undef WRITE_UINT32_FIELD 5024 #undef WRITE_UINT32_FIELD
5015 #undef READ_SHORT_FIELD 5025 #undef READ_SHORT_FIELD
5016 #undef WRITE_SHORT_FIELD 5026 #undef WRITE_SHORT_FIELD
5017 #undef READ_BYTE_FIELD 5027 #undef READ_BYTE_FIELD
5018 #undef WRITE_BYTE_FIELD 5028 #undef WRITE_BYTE_FIELD
5019 5029
5020 5030
5021 } } // namespace v8::internal 5031 } } // namespace v8::internal
5022 5032
5023 #endif // V8_OBJECTS_INL_H_ 5033 #endif // V8_OBJECTS_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698