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

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: ia32 ready to go 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 =
1342 if (to_kind == FAST_ELEMENTS) { 1343 global_context->js_array_maps();
Jakob Kummerow 2012/05/13 21:55:27 nit: fits on one line
danno 2012/05/22 11:05:21 Done.
1343 return global_context->object_js_array_map(); 1344 if (maybe_array_maps->IsFixedArray()) {
1344 } else { 1345 FixedArray* array_maps = FixedArray::cast(maybe_array_maps);
1345 if (to_kind == FAST_DOUBLE_ELEMENTS) { 1346 if (array_maps->get(from_kind) == current_map) {
1346 return global_context->double_js_array_map(); 1347 Object* maybe_transitioned_map = array_maps->get(to_kind);
1347 } else { 1348 if (maybe_transitioned_map->IsMap()) {
1348 ASSERT(to_kind == DICTIONARY_ELEMENTS); 1349 return Map::cast(maybe_transitioned_map);
1349 } 1350 }
1350 } 1351 }
1351 } 1352 }
1353
1352 return GetElementsTransitionMapSlow(to_kind); 1354 return GetElementsTransitionMapSlow(to_kind);
1353 } 1355 }
1354 1356
1355 1357
1356 void JSObject::set_map_and_elements(Map* new_map, 1358 void JSObject::set_map_and_elements(Map* new_map,
1357 FixedArrayBase* value, 1359 FixedArrayBase* value,
1358 WriteBarrierMode mode) { 1360 WriteBarrierMode mode) {
1359 ASSERT(value->HasValidElements()); 1361 ASSERT(value->HasValidElements());
1360 #ifdef DEBUG
1361 ValidateSmiOnlyElements();
1362 #endif
1363 if (new_map != NULL) { 1362 if (new_map != NULL) {
1364 if (mode == UPDATE_WRITE_BARRIER) { 1363 if (mode == UPDATE_WRITE_BARRIER) {
1365 set_map(new_map); 1364 set_map(new_map);
1366 } else { 1365 } else {
1367 ASSERT(mode == SKIP_WRITE_BARRIER); 1366 ASSERT(mode == SKIP_WRITE_BARRIER);
1368 set_map_no_write_barrier(new_map); 1367 set_map_no_write_barrier(new_map);
1369 } 1368 }
1370 } 1369 }
1371 ASSERT((map()->has_fast_elements() || 1370 ASSERT((map()->has_fast_smi_or_object_elements() ||
1372 map()->has_fast_smi_only_elements() ||
1373 (value == GetHeap()->empty_fixed_array())) == 1371 (value == GetHeap()->empty_fixed_array())) ==
1374 (value->map() == GetHeap()->fixed_array_map() || 1372 (value->map() == GetHeap()->fixed_array_map() ||
1375 value->map() == GetHeap()->fixed_cow_array_map())); 1373 value->map() == GetHeap()->fixed_cow_array_map()));
1376 ASSERT((value == GetHeap()->empty_fixed_array()) || 1374 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1377 (map()->has_fast_double_elements() == value->IsFixedDoubleArray())); 1375 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
1378 WRITE_FIELD(this, kElementsOffset, value); 1376 WRITE_FIELD(this, kElementsOffset, value);
1379 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode); 1377 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
1380 } 1378 }
1381 1379
1382 1380
1383 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { 1381 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1384 set_map_and_elements(NULL, value, mode); 1382 set_map_and_elements(NULL, value, mode);
1385 } 1383 }
1386 1384
1387 1385
1388 void JSObject::initialize_properties() { 1386 void JSObject::initialize_properties() {
1389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 1387 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1390 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); 1388 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
1391 } 1389 }
1392 1390
1393 1391
1394 void JSObject::initialize_elements() { 1392 void JSObject::initialize_elements() {
1395 ASSERT(map()->has_fast_elements() || 1393 ASSERT(map()->has_fast_smi_or_object_elements() ||
1396 map()->has_fast_smi_only_elements() ||
1397 map()->has_fast_double_elements()); 1394 map()->has_fast_double_elements());
1398 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 1395 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1399 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); 1396 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
1400 } 1397 }
1401 1398
1402 1399
1403 MaybeObject* JSObject::ResetElements() { 1400 MaybeObject* JSObject::ResetElements() {
1404 Object* obj; 1401 Object* obj;
1405 ElementsKind elements_kind = FLAG_smi_only_arrays 1402 ElementsKind elements_kind = GetInitialFastElementsKind();
1406 ? FAST_SMI_ONLY_ELEMENTS 1403 if (!FLAG_smi_only_arrays) {
1407 : FAST_ELEMENTS; 1404 elements_kind = FastSmiToObjectElementsKind(elements_kind);
1405 }
1408 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), 1406 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1409 elements_kind); 1407 elements_kind);
1410 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1408 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1411 set_map(Map::cast(obj)); 1409 set_map(Map::cast(obj));
1412 initialize_elements(); 1410 initialize_elements();
1413 return this; 1411 return this;
1414 } 1412 }
1415 1413
1416 1414
1417 ACCESSORS(Oddball, to_string, String, kToStringOffset) 1415 ACCESSORS(Oddball, to_string, String, kToStringOffset)
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1669 return reinterpret_cast<FixedArrayBase*>(object); 1667 return reinterpret_cast<FixedArrayBase*>(object);
1670 } 1668 }
1671 1669
1672 1670
1673 Object* FixedArray::get(int index) { 1671 Object* FixedArray::get(int index) {
1674 ASSERT(index >= 0 && index < this->length()); 1672 ASSERT(index >= 0 && index < this->length());
1675 return READ_FIELD(this, kHeaderSize + index * kPointerSize); 1673 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1676 } 1674 }
1677 1675
1678 1676
1677 bool FixedArray::is_the_hole(int index) {
1678 ASSERT(index >= 0 && index < this->length());
Jakob Kummerow 2012/05/13 21:55:27 nit: this ASSERT, while correct, is not necessary,
danno 2012/05/22 11:05:21 Done.
1679 return get(index) == GetHeap()->the_hole_value();
1680 }
1681
1682
1679 void FixedArray::set(int index, Smi* value) { 1683 void FixedArray::set(int index, Smi* value) {
1680 ASSERT(map() != HEAP->fixed_cow_array_map()); 1684 ASSERT(map() != HEAP->fixed_cow_array_map());
1681 ASSERT(index >= 0 && index < this->length()); 1685 ASSERT(index >= 0 && index < this->length());
1682 ASSERT(reinterpret_cast<Object*>(value)->IsSmi()); 1686 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1683 int offset = kHeaderSize + index * kPointerSize; 1687 int offset = kHeaderSize + index * kPointerSize;
1684 WRITE_FIELD(this, offset, value); 1688 WRITE_FIELD(this, offset, value);
1685 } 1689 }
1686 1690
1687 1691
1688 void FixedArray::set(int index, Object* value) { 1692 void FixedArray::set(int index, Object* value) {
(...skipping 1161 matching lines...) Expand 10 before | Expand all | Expand 10 after
2850 } 2854 }
2851 2855
2852 2856
2853 bool Map::has_non_instance_prototype() { 2857 bool Map::has_non_instance_prototype() {
2854 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0; 2858 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2855 } 2859 }
2856 2860
2857 2861
2858 void Map::set_function_with_prototype(bool value) { 2862 void Map::set_function_with_prototype(bool value) {
2859 if (value) { 2863 if (value) {
2860 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype)); 2864 set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
2861 } else { 2865 } else {
2862 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype)); 2866 set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
2863 } 2867 }
2864 } 2868 }
2865 2869
2866 2870
2867 bool Map::function_with_prototype() { 2871 bool Map::function_with_prototype() {
2868 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0; 2872 return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
2869 } 2873 }
2870 2874
2871 2875
2872 void Map::set_is_access_check_needed(bool access_check_needed) { 2876 void Map::set_is_access_check_needed(bool access_check_needed) {
2873 if (access_check_needed) { 2877 if (access_check_needed) {
2874 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded)); 2878 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2875 } else { 2879 } else {
2876 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded)); 2880 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2877 } 2881 }
2878 } 2882 }
(...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after
3936 } 3940 }
3937 3941
3938 3942
3939 MaybeObject* JSFunction::set_initial_map_and_cache_transitions( 3943 MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3940 Map* initial_map) { 3944 Map* initial_map) {
3941 Context* global_context = context()->global_context(); 3945 Context* global_context = context()->global_context();
3942 Object* array_function = 3946 Object* array_function =
3943 global_context->get(Context::ARRAY_FUNCTION_INDEX); 3947 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3944 if (array_function->IsJSFunction() && 3948 if (array_function->IsJSFunction() &&
3945 this == JSFunction::cast(array_function)) { 3949 this == JSFunction::cast(array_function)) {
3946 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); 3950 // Replace all of the cached initial array maps in the global context with
3951 // the appropriate transitioned elements kind maps.
3952 Heap* heap = GetHeap();
3953 MaybeObject* maybe_maps =
3954 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
Jakob Kummerow 2012/05/13 21:55:27 Do you mean kFastElementsKindCount here?
danno 2012/05/22 11:05:21 kElementsKindCount is better here, since it remove
3955 FixedArray* maps;
3956 if (!maybe_maps->To(&maps)) return maybe_maps;
3947 3957
3948 MaybeObject* maybe_map = initial_map->CopyDropTransitions(); 3958 Map* current_map = initial_map;
3949 Map* new_double_map = NULL; 3959 ElementsKind kind = current_map->elements_kind();
3950 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map; 3960 ASSERT(kind == GetInitialFastElementsKind());
3951 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS); 3961 maps->set(kind, current_map);
3952 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, 3962 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
3953 new_double_map); 3963 i < kFastElementsKindCount; ++i) {
3954 if (maybe_map->IsFailure()) return maybe_map; 3964 ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i);
3955 3965 MaybeObject* maybe_new_map = current_map->CopyDropTransitions();
3956 maybe_map = new_double_map->CopyDropTransitions(); 3966 Map* new_map = NULL;
3957 Map* new_object_map = NULL; 3967 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
3958 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map; 3968 new_map->set_elements_kind(transitioned_kind);
3959 new_object_map->set_elements_kind(FAST_ELEMENTS); 3969 maybe_new_map = current_map->AddElementsTransition(transitioned_kind,
3960 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS, 3970 new_map);
3961 new_object_map); 3971 if (maybe_new_map->IsFailure()) return maybe_new_map;
3962 if (maybe_map->IsFailure()) return maybe_map; 3972 maps->set(transitioned_kind, new_map);
3963 3973 current_map = new_map;
3964 global_context->set_smi_js_array_map(initial_map); 3974 }
3965 global_context->set_double_js_array_map(new_double_map); 3975 global_context->set_js_array_maps(maps);
3966 global_context->set_object_js_array_map(new_object_map);
3967 } 3976 }
3968 set_initial_map(initial_map); 3977 set_initial_map(initial_map);
3969 return this; 3978 return this;
3970 } 3979 }
3971 3980
3972 3981
3973 bool JSFunction::has_initial_map() { 3982 bool JSFunction::has_initial_map() {
3974 return prototype_or_initial_map()->IsMap(); 3983 return prototype_or_initial_map()->IsMap();
3975 } 3984 }
3976 3985
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
4292 } 4301 }
4293 } 4302 }
4294 4303
4295 4304
4296 ElementsKind JSObject::GetElementsKind() { 4305 ElementsKind JSObject::GetElementsKind() {
4297 ElementsKind kind = map()->elements_kind(); 4306 ElementsKind kind = map()->elements_kind();
4298 #if DEBUG 4307 #if DEBUG
4299 FixedArrayBase* fixed_array = 4308 FixedArrayBase* fixed_array =
4300 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); 4309 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4301 Map* map = fixed_array->map(); 4310 Map* map = fixed_array->map();
4302 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && 4311 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4303 (map == GetHeap()->fixed_array_map() || 4312 (map == GetHeap()->fixed_array_map() ||
4304 map == GetHeap()->fixed_cow_array_map())) || 4313 map == GetHeap()->fixed_cow_array_map())) ||
4305 (kind == FAST_DOUBLE_ELEMENTS && 4314 (IsFastDoubleElementsKind(kind) &&
4306 (fixed_array->IsFixedDoubleArray() || 4315 (fixed_array->IsFixedDoubleArray() ||
4307 fixed_array == GetHeap()->empty_fixed_array())) || 4316 fixed_array == GetHeap()->empty_fixed_array())) ||
4308 (kind == DICTIONARY_ELEMENTS && 4317 (kind == DICTIONARY_ELEMENTS &&
4309 fixed_array->IsFixedArray() && 4318 fixed_array->IsFixedArray() &&
4310 fixed_array->IsDictionary()) || 4319 fixed_array->IsDictionary()) ||
4311 (kind > DICTIONARY_ELEMENTS)); 4320 (kind > DICTIONARY_ELEMENTS));
4312 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || 4321 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4313 (elements()->IsFixedArray() && elements()->length() >= 2)); 4322 (elements()->IsFixedArray() && elements()->length() >= 2));
4314 #endif 4323 #endif
4315 return kind; 4324 return kind;
4316 } 4325 }
4317 4326
4318 4327
4319 ElementsAccessor* JSObject::GetElementsAccessor() { 4328 ElementsAccessor* JSObject::GetElementsAccessor() {
4320 return ElementsAccessor::ForKind(GetElementsKind()); 4329 return ElementsAccessor::ForKind(GetElementsKind());
4321 } 4330 }
4322 4331
4323 4332
4324 bool JSObject::HasFastElements() { 4333 bool JSObject::HasFastObjectElements() {
4325 return GetElementsKind() == FAST_ELEMENTS; 4334 return IsFastObjectElementsKind(GetElementsKind());
4326 } 4335 }
4327 4336
4328 4337
4329 bool JSObject::HasFastSmiOnlyElements() { 4338 bool JSObject::HasFastSmiElements() {
4330 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS; 4339 return IsFastSmiElementsKind(GetElementsKind());
4331 } 4340 }
4332 4341
4333 4342
4334 bool JSObject::HasFastTypeElements() { 4343 bool JSObject::HasFastSmiOrObjectElements() {
4335 ElementsKind elements_kind = GetElementsKind(); 4344 return IsFastSmiOrObjectElementsKind(GetElementsKind());
4336 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4337 elements_kind == FAST_ELEMENTS;
4338 } 4345 }
4339 4346
4340 4347
4341 bool JSObject::HasFastDoubleElements() { 4348 bool JSObject::HasFastDoubleElements() {
4342 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; 4349 return IsFastDoubleElementsKind(GetElementsKind());
4343 } 4350 }
4344 4351
4345 4352
4353 bool JSObject::HasFastHoleyElements() {
4354 return IsFastHoleyElementsKind(GetElementsKind());
4355 }
4356
4357
4346 bool JSObject::HasDictionaryElements() { 4358 bool JSObject::HasDictionaryElements() {
4347 return GetElementsKind() == DICTIONARY_ELEMENTS; 4359 return GetElementsKind() == DICTIONARY_ELEMENTS;
4348 } 4360 }
4349 4361
4350 4362
4351 bool JSObject::HasNonStrictArgumentsElements() { 4363 bool JSObject::HasNonStrictArgumentsElements() {
4352 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS; 4364 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4353 } 4365 }
4354 4366
4355 4367
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4389 return map()->has_named_interceptor(); 4401 return map()->has_named_interceptor();
4390 } 4402 }
4391 4403
4392 4404
4393 bool JSObject::HasIndexedInterceptor() { 4405 bool JSObject::HasIndexedInterceptor() {
4394 return map()->has_indexed_interceptor(); 4406 return map()->has_indexed_interceptor();
4395 } 4407 }
4396 4408
4397 4409
4398 MaybeObject* JSObject::EnsureWritableFastElements() { 4410 MaybeObject* JSObject::EnsureWritableFastElements() {
4399 ASSERT(HasFastTypeElements()); 4411 ASSERT(HasFastSmiOrObjectElements());
4400 FixedArray* elems = FixedArray::cast(elements()); 4412 FixedArray* elems = FixedArray::cast(elements());
4401 Isolate* isolate = GetIsolate(); 4413 Isolate* isolate = GetIsolate();
4402 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; 4414 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
4403 Object* writable_elems; 4415 Object* writable_elems;
4404 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( 4416 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4405 elems, isolate->heap()->fixed_array_map()); 4417 elems, isolate->heap()->fixed_array_map());
4406 if (!maybe_writable_elems->ToObject(&writable_elems)) { 4418 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4407 return maybe_writable_elems; 4419 return maybe_writable_elems;
4408 } 4420 }
4409 } 4421 }
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
4747 // No write barrier is needed since empty_fixed_array is not in new space. 4759 // No write barrier is needed since empty_fixed_array is not in new space.
4748 // Please note this function is used during marking: 4760 // Please note this function is used during marking:
4749 // - MarkCompactCollector::MarkUnmarkedObject 4761 // - MarkCompactCollector::MarkUnmarkedObject
4750 // - IncrementalMarking::Step 4762 // - IncrementalMarking::Step
4751 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); 4763 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4752 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); 4764 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
4753 } 4765 }
4754 4766
4755 4767
4756 void JSArray::EnsureSize(int required_size) { 4768 void JSArray::EnsureSize(int required_size) {
4757 ASSERT(HasFastTypeElements()); 4769 ASSERT(HasFastSmiOrObjectElements());
4758 FixedArray* elts = FixedArray::cast(elements()); 4770 FixedArray* elts = FixedArray::cast(elements());
4759 const int kArraySizeThatFitsComfortablyInNewSpace = 128; 4771 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4760 if (elts->length() < required_size) { 4772 if (elts->length() < required_size) {
4761 // Doubling in size would be overkill, but leave some slack to avoid 4773 // Doubling in size would be overkill, but leave some slack to avoid
4762 // constantly growing. 4774 // constantly growing.
4763 Expand(required_size + (required_size >> 3)); 4775 Expand(required_size + (required_size >> 3));
4764 // It's a performance benefit to keep a frequently used array in new-space. 4776 // It's a performance benefit to keep a frequently used array in new-space.
4765 } else if (!GetHeap()->new_space()->Contains(elts) && 4777 } else if (!GetHeap()->new_space()->Contains(elts) &&
4766 required_size < kArraySizeThatFitsComfortablyInNewSpace) { 4778 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4767 // Expand will allocate a new backing store in new space even if the size 4779 // Expand will allocate a new backing store in new space even if the size
(...skipping 11 matching lines...) Expand all
4779 4791
4780 bool JSArray::AllowsSetElementsLength() { 4792 bool JSArray::AllowsSetElementsLength() {
4781 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray(); 4793 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4782 ASSERT(result == !HasExternalArrayElements()); 4794 ASSERT(result == !HasExternalArrayElements());
4783 return result; 4795 return result;
4784 } 4796 }
4785 4797
4786 4798
4787 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { 4799 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4788 MaybeObject* maybe_result = EnsureCanContainElements( 4800 MaybeObject* maybe_result = EnsureCanContainElements(
4789 storage, ALLOW_COPIED_DOUBLE_ELEMENTS); 4801 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
4790 if (maybe_result->IsFailure()) return maybe_result; 4802 if (maybe_result->IsFailure()) return maybe_result;
4791 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && 4803 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4792 GetElementsKind() == FAST_DOUBLE_ELEMENTS) || 4804 IsFastDoubleElementsKind(GetElementsKind())) ||
4793 ((storage->map() != GetHeap()->fixed_double_array_map()) && 4805 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4794 ((GetElementsKind() == FAST_ELEMENTS) || 4806 (IsFastObjectElementsKind(GetElementsKind()) ||
4795 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS && 4807 (IsFastElementsKind(GetElementsKind()) &&
Jakob Kummerow 2012/05/13 21:55:27 Did you mean IsFastSmiElementsKind?
danno 2012/05/22 11:05:21 Done.
4796 FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); 4808 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
4797 set_elements(storage); 4809 set_elements(storage);
4798 set_length(Smi::FromInt(storage->length())); 4810 set_length(Smi::FromInt(storage->length()));
4799 return this; 4811 return this;
4800 } 4812 }
4801 4813
4802 4814
4803 MaybeObject* FixedArray::Copy() { 4815 MaybeObject* FixedArray::Copy() {
4804 if (length() == 0) return this; 4816 if (length() == 0) return this;
4805 return GetHeap()->CopyFixedArray(this); 4817 return GetHeap()->CopyFixedArray(this);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
4962 #undef WRITE_UINT32_FIELD 4974 #undef WRITE_UINT32_FIELD
4963 #undef READ_SHORT_FIELD 4975 #undef READ_SHORT_FIELD
4964 #undef WRITE_SHORT_FIELD 4976 #undef WRITE_SHORT_FIELD
4965 #undef READ_BYTE_FIELD 4977 #undef READ_BYTE_FIELD
4966 #undef WRITE_BYTE_FIELD 4978 #undef WRITE_BYTE_FIELD
4967 4979
4968 4980
4969 } } // namespace v8::internal 4981 } } // namespace v8::internal
4970 4982
4971 #endif // V8_OBJECTS_INL_H_ 4983 #endif // V8_OBJECTS_INL_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698