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

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: 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
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after
4001 } 4003 }
4002 4004
4003 4005
4004 MaybeObject* JSFunction::set_initial_map_and_cache_transitions( 4006 MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
4005 Map* initial_map) { 4007 Map* initial_map) {
4006 Context* global_context = context()->global_context(); 4008 Context* global_context = context()->global_context();
4007 Object* array_function = 4009 Object* array_function =
4008 global_context->get(Context::ARRAY_FUNCTION_INDEX); 4010 global_context->get(Context::ARRAY_FUNCTION_INDEX);
4009 if (array_function->IsJSFunction() && 4011 if (array_function->IsJSFunction() &&
4010 this == JSFunction::cast(array_function)) { 4012 this == JSFunction::cast(array_function)) {
4011 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS); 4013 // Replace all of the cached initial array maps in the global context with
4014 // the appropriate transitioned elements kind maps.
4015 Heap* heap = GetHeap();
4016 MaybeObject* maybe_maps =
4017 heap->AllocateFixedArrayWithHoles(kElementsKindCount);
4018 FixedArray* maps;
4019 if (!maybe_maps->To(&maps)) return maybe_maps;
4012 4020
4013 MaybeObject* maybe_map = initial_map->CopyDropTransitions(); 4021 Map* current_map = initial_map;
4014 Map* new_double_map = NULL; 4022 ElementsKind kind = current_map->elements_kind();
4015 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map; 4023 ASSERT(kind == GetInitialFastElementsKind());
4016 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS); 4024 maps->set(kind, current_map);
4017 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS, 4025 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1;
4018 new_double_map); 4026 i < kFastElementsKindCount; ++i) {
4019 if (maybe_map->IsFailure()) return maybe_map; 4027 ElementsKind transitioned_kind = GetFastElementsKindFromSequenceIndex(i);
4020 4028 MaybeObject* maybe_new_map = current_map->CopyDropTransitions();
4021 maybe_map = new_double_map->CopyDropTransitions(); 4029 Map* new_map = NULL;
4022 Map* new_object_map = NULL; 4030 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map;
4023 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map; 4031 new_map->set_elements_kind(transitioned_kind);
4024 new_object_map->set_elements_kind(FAST_ELEMENTS); 4032 maybe_new_map = current_map->AddElementsTransition(transitioned_kind,
4025 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS, 4033 new_map);
4026 new_object_map); 4034 if (maybe_new_map->IsFailure()) return maybe_new_map;
4027 if (maybe_map->IsFailure()) return maybe_map; 4035 maps->set(transitioned_kind, new_map);
4028 4036 current_map = new_map;
4029 global_context->set_smi_js_array_map(initial_map); 4037 }
4030 global_context->set_double_js_array_map(new_double_map); 4038 global_context->set_js_array_maps(maps);
4031 global_context->set_object_js_array_map(new_object_map);
4032 } 4039 }
4033 set_initial_map(initial_map); 4040 set_initial_map(initial_map);
4034 return this; 4041 return this;
4035 } 4042 }
4036 4043
4037 4044
4038 bool JSFunction::has_initial_map() { 4045 bool JSFunction::has_initial_map() {
4039 return prototype_or_initial_map()->IsMap(); 4046 return prototype_or_initial_map()->IsMap();
4040 } 4047 }
4041 4048
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
4357 } 4364 }
4358 } 4365 }
4359 4366
4360 4367
4361 ElementsKind JSObject::GetElementsKind() { 4368 ElementsKind JSObject::GetElementsKind() {
4362 ElementsKind kind = map()->elements_kind(); 4369 ElementsKind kind = map()->elements_kind();
4363 #if DEBUG 4370 #if DEBUG
4364 FixedArrayBase* fixed_array = 4371 FixedArrayBase* fixed_array =
4365 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset)); 4372 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4366 Map* map = fixed_array->map(); 4373 Map* map = fixed_array->map();
4367 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) && 4374 ASSERT((IsFastSmiOrObjectElementsKind(kind) &&
4368 (map == GetHeap()->fixed_array_map() || 4375 (map == GetHeap()->fixed_array_map() ||
4369 map == GetHeap()->fixed_cow_array_map())) || 4376 map == GetHeap()->fixed_cow_array_map())) ||
4370 (kind == FAST_DOUBLE_ELEMENTS && 4377 (IsFastDoubleElementsKind(kind) &&
4371 (fixed_array->IsFixedDoubleArray() || 4378 (fixed_array->IsFixedDoubleArray() ||
4372 fixed_array == GetHeap()->empty_fixed_array())) || 4379 fixed_array == GetHeap()->empty_fixed_array())) ||
4373 (kind == DICTIONARY_ELEMENTS && 4380 (kind == DICTIONARY_ELEMENTS &&
4374 fixed_array->IsFixedArray() && 4381 fixed_array->IsFixedArray() &&
4375 fixed_array->IsDictionary()) || 4382 fixed_array->IsDictionary()) ||
4376 (kind > DICTIONARY_ELEMENTS)); 4383 (kind > DICTIONARY_ELEMENTS));
4377 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) || 4384 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4378 (elements()->IsFixedArray() && elements()->length() >= 2)); 4385 (elements()->IsFixedArray() && elements()->length() >= 2));
4379 #endif 4386 #endif
4380 return kind; 4387 return kind;
4381 } 4388 }
4382 4389
4383 4390
4384 ElementsAccessor* JSObject::GetElementsAccessor() { 4391 ElementsAccessor* JSObject::GetElementsAccessor() {
4385 return ElementsAccessor::ForKind(GetElementsKind()); 4392 return ElementsAccessor::ForKind(GetElementsKind());
4386 } 4393 }
4387 4394
4388 4395
4389 bool JSObject::HasFastElements() { 4396 bool JSObject::HasFastObjectElements() {
4390 return GetElementsKind() == FAST_ELEMENTS; 4397 return IsFastObjectElementsKind(GetElementsKind());
4391 } 4398 }
4392 4399
4393 4400
4394 bool JSObject::HasFastSmiOnlyElements() { 4401 bool JSObject::HasFastSmiElements() {
4395 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS; 4402 return IsFastSmiElementsKind(GetElementsKind());
4396 } 4403 }
4397 4404
4398 4405
4399 bool JSObject::HasFastTypeElements() { 4406 bool JSObject::HasFastSmiOrObjectElements() {
4400 ElementsKind elements_kind = GetElementsKind(); 4407 return IsFastSmiOrObjectElementsKind(GetElementsKind());
4401 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4402 elements_kind == FAST_ELEMENTS;
4403 } 4408 }
4404 4409
4405 4410
4406 bool JSObject::HasFastDoubleElements() { 4411 bool JSObject::HasFastDoubleElements() {
4407 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; 4412 return IsFastDoubleElementsKind(GetElementsKind());
4408 } 4413 }
4409 4414
4410 4415
4416 bool JSObject::HasFastHoleyElements() {
4417 return IsFastHoleyElementsKind(GetElementsKind());
4418 }
4419
4420
4411 bool JSObject::HasDictionaryElements() { 4421 bool JSObject::HasDictionaryElements() {
4412 return GetElementsKind() == DICTIONARY_ELEMENTS; 4422 return GetElementsKind() == DICTIONARY_ELEMENTS;
4413 } 4423 }
4414 4424
4415 4425
4416 bool JSObject::HasNonStrictArgumentsElements() { 4426 bool JSObject::HasNonStrictArgumentsElements() {
4417 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS; 4427 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4418 } 4428 }
4419 4429
4420 4430
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
4454 return map()->has_named_interceptor(); 4464 return map()->has_named_interceptor();
4455 } 4465 }
4456 4466
4457 4467
4458 bool JSObject::HasIndexedInterceptor() { 4468 bool JSObject::HasIndexedInterceptor() {
4459 return map()->has_indexed_interceptor(); 4469 return map()->has_indexed_interceptor();
4460 } 4470 }
4461 4471
4462 4472
4463 MaybeObject* JSObject::EnsureWritableFastElements() { 4473 MaybeObject* JSObject::EnsureWritableFastElements() {
4464 ASSERT(HasFastTypeElements()); 4474 ASSERT(HasFastSmiOrObjectElements());
4465 FixedArray* elems = FixedArray::cast(elements()); 4475 FixedArray* elems = FixedArray::cast(elements());
4466 Isolate* isolate = GetIsolate(); 4476 Isolate* isolate = GetIsolate();
4467 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; 4477 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
4468 Object* writable_elems; 4478 Object* writable_elems;
4469 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( 4479 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4470 elems, isolate->heap()->fixed_array_map()); 4480 elems, isolate->heap()->fixed_array_map());
4471 if (!maybe_writable_elems->ToObject(&writable_elems)) { 4481 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4472 return maybe_writable_elems; 4482 return maybe_writable_elems;
4473 } 4483 }
4474 } 4484 }
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
4812 // No write barrier is needed since empty_fixed_array is not in new space. 4822 // No write barrier is needed since empty_fixed_array is not in new space.
4813 // Please note this function is used during marking: 4823 // Please note this function is used during marking:
4814 // - MarkCompactCollector::MarkUnmarkedObject 4824 // - MarkCompactCollector::MarkUnmarkedObject
4815 // - IncrementalMarking::Step 4825 // - IncrementalMarking::Step
4816 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); 4826 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4817 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); 4827 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
4818 } 4828 }
4819 4829
4820 4830
4821 void JSArray::EnsureSize(int required_size) { 4831 void JSArray::EnsureSize(int required_size) {
4822 ASSERT(HasFastTypeElements()); 4832 ASSERT(HasFastSmiOrObjectElements());
4823 FixedArray* elts = FixedArray::cast(elements()); 4833 FixedArray* elts = FixedArray::cast(elements());
4824 const int kArraySizeThatFitsComfortablyInNewSpace = 128; 4834 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4825 if (elts->length() < required_size) { 4835 if (elts->length() < required_size) {
4826 // Doubling in size would be overkill, but leave some slack to avoid 4836 // Doubling in size would be overkill, but leave some slack to avoid
4827 // constantly growing. 4837 // constantly growing.
4828 Expand(required_size + (required_size >> 3)); 4838 Expand(required_size + (required_size >> 3));
4829 // It's a performance benefit to keep a frequently used array in new-space. 4839 // It's a performance benefit to keep a frequently used array in new-space.
4830 } else if (!GetHeap()->new_space()->Contains(elts) && 4840 } else if (!GetHeap()->new_space()->Contains(elts) &&
4831 required_size < kArraySizeThatFitsComfortablyInNewSpace) { 4841 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4832 // Expand will allocate a new backing store in new space even if the size 4842 // Expand will allocate a new backing store in new space even if the size
(...skipping 11 matching lines...) Expand all
4844 4854
4845 bool JSArray::AllowsSetElementsLength() { 4855 bool JSArray::AllowsSetElementsLength() {
4846 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray(); 4856 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4847 ASSERT(result == !HasExternalArrayElements()); 4857 ASSERT(result == !HasExternalArrayElements());
4848 return result; 4858 return result;
4849 } 4859 }
4850 4860
4851 4861
4852 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) { 4862 MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4853 MaybeObject* maybe_result = EnsureCanContainElements( 4863 MaybeObject* maybe_result = EnsureCanContainElements(
4854 storage, ALLOW_COPIED_DOUBLE_ELEMENTS); 4864 storage, storage->length(), ALLOW_COPIED_DOUBLE_ELEMENTS);
4855 if (maybe_result->IsFailure()) return maybe_result; 4865 if (maybe_result->IsFailure()) return maybe_result;
4856 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() && 4866 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4857 GetElementsKind() == FAST_DOUBLE_ELEMENTS) || 4867 IsFastDoubleElementsKind(GetElementsKind())) ||
4858 ((storage->map() != GetHeap()->fixed_double_array_map()) && 4868 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4859 ((GetElementsKind() == FAST_ELEMENTS) || 4869 (IsFastObjectElementsKind(GetElementsKind()) ||
4860 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS && 4870 (IsFastSmiElementsKind(GetElementsKind()) &&
4861 FixedArray::cast(storage)->ContainsOnlySmisOrHoles())))); 4871 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
4862 set_elements(storage); 4872 set_elements(storage);
4863 set_length(Smi::FromInt(storage->length())); 4873 set_length(Smi::FromInt(storage->length()));
4864 return this; 4874 return this;
4865 } 4875 }
4866 4876
4867 4877
4868 MaybeObject* FixedArray::Copy() { 4878 MaybeObject* FixedArray::Copy() {
4869 if (length() == 0) return this; 4879 if (length() == 0) return this;
4870 return GetHeap()->CopyFixedArray(this); 4880 return GetHeap()->CopyFixedArray(this);
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
5027 #undef WRITE_UINT32_FIELD 5037 #undef WRITE_UINT32_FIELD
5028 #undef READ_SHORT_FIELD 5038 #undef READ_SHORT_FIELD
5029 #undef WRITE_SHORT_FIELD 5039 #undef WRITE_SHORT_FIELD
5030 #undef READ_BYTE_FIELD 5040 #undef READ_BYTE_FIELD
5031 #undef WRITE_BYTE_FIELD 5041 #undef WRITE_BYTE_FIELD
5032 5042
5033 5043
5034 } } // namespace v8::internal 5044 } } // namespace v8::internal
5035 5045
5036 #endif // V8_OBJECTS_INL_H_ 5046 #endif // V8_OBJECTS_INL_H_
OLDNEW
« no previous file with comments | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698