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

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

Issue 7901016: Basic support for tracking smi-only arrays on ia32. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: ready to land Created 9 years, 3 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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1282 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 1293
1294 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset) 1294 ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
1295 1295
1296 1296
1297 FixedArrayBase* JSObject::elements() { 1297 FixedArrayBase* JSObject::elements() {
1298 Object* array = READ_FIELD(this, kElementsOffset); 1298 Object* array = READ_FIELD(this, kElementsOffset);
1299 ASSERT(array->HasValidElements()); 1299 ASSERT(array->HasValidElements());
1300 return static_cast<FixedArrayBase*>(array); 1300 return static_cast<FixedArrayBase*>(array);
1301 } 1301 }
1302 1302
1303 void JSObject::ValidateSmiOnlyElements() {
1304 #if DEBUG
1305 if (FLAG_smi_only_arrays &&
1306 map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
1307 Heap* heap = GetHeap();
1308 // Don't use elements, since integrity checks will fail if there
1309 // are filler pointers in the array.
1310 FixedArray* fixed_array =
1311 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1312 Map* map = fixed_array->map();
1313 // Arrays that have been shifted in place can't be verified.
1314 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1315 map != heap->raw_unchecked_two_pointer_filler_map() &&
1316 map != heap->free_space_map()) {
1317 for (int i = 0; i < fixed_array->length(); i++) {
1318 Object* current = fixed_array->get(i);
1319 ASSERT(current->IsSmi() || current == heap->the_hole_value());
1320 }
1321 }
1322 }
1323 #endif
1324 }
1325
1326
1327 MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
1328 #if DEBUG
1329 ValidateSmiOnlyElements();
1330 #endif
1331 if (FLAG_smi_only_arrays &&
1332 (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
1333 Object* obj;
1334 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
1335 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1336 set_map(Map::cast(obj));
1337 }
1338 return this;
1339 }
1340
1341
1342 MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
1343 uint32_t count) {
1344 if (FLAG_smi_only_arrays &&
1345 map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
1346 for (uint32_t i = 0; i < count; ++i) {
1347 Object* current = *objects++;
1348 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) {
1349 return EnsureCanContainNonSmiElements();
1350 }
1351 }
1352 }
1353 return this;
1354 }
1355
1356
1357 MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) {
1358 if (FLAG_smi_only_arrays) {
1359 Object** objects = reinterpret_cast<Object**>(
1360 FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
1361 return EnsureCanContainElements(objects, elements->length());
1362 } else {
1363 return this;
1364 }
1365 }
1366
1303 1367
1304 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) { 1368 void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1305 ASSERT(map()->has_fast_elements() == 1369 ASSERT((map()->has_fast_elements() ||
1370 map()->has_fast_smi_only_elements()) ==
1306 (value->map() == GetHeap()->fixed_array_map() || 1371 (value->map() == GetHeap()->fixed_array_map() ||
1307 value->map() == GetHeap()->fixed_cow_array_map())); 1372 value->map() == GetHeap()->fixed_cow_array_map()));
1308 ASSERT(map()->has_fast_double_elements() == 1373 ASSERT(map()->has_fast_double_elements() ==
1309 value->IsFixedDoubleArray()); 1374 value->IsFixedDoubleArray());
1310 ASSERT(value->HasValidElements()); 1375 ASSERT(value->HasValidElements());
1376 #ifdef DEBUG
1377 ValidateSmiOnlyElements();
1378 #endif
1311 WRITE_FIELD(this, kElementsOffset, value); 1379 WRITE_FIELD(this, kElementsOffset, value);
1312 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode); 1380 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
1313 } 1381 }
1314 1382
1315 1383
1316 void JSObject::initialize_properties() { 1384 void JSObject::initialize_properties() {
1317 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 1385 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1318 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array()); 1386 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
1319 } 1387 }
1320 1388
1321 1389
1322 void JSObject::initialize_elements() { 1390 void JSObject::initialize_elements() {
1323 ASSERT(map()->has_fast_elements()); 1391 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
1324 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array())); 1392 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1325 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array()); 1393 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
1326 } 1394 }
1327 1395
1328 1396
1329 MaybeObject* JSObject::ResetElements() { 1397 MaybeObject* JSObject::ResetElements() {
1330 Object* obj; 1398 Object* obj;
1331 { MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS); 1399 ElementsKind elements_kind = FLAG_smi_only_arrays
1332 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1400 ? FAST_SMI_ONLY_ELEMENTS
1333 } 1401 : FAST_ELEMENTS;
1402 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1403 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1334 set_map(Map::cast(obj)); 1404 set_map(Map::cast(obj));
1335 initialize_elements(); 1405 initialize_elements();
1336 return this; 1406 return this;
1337 } 1407 }
1338 1408
1339 1409
1340 ACCESSORS(Oddball, to_string, String, kToStringOffset) 1410 ACCESSORS(Oddball, to_string, String, kToStringOffset)
1341 ACCESSORS(Oddball, to_number, Object, kToNumberOffset) 1411 ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1342 1412
1343 1413
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 int offset = kHeaderSize + old_length * kDoubleSize; 1749 int offset = kHeaderSize + old_length * kDoubleSize;
1680 for (int current = from->length(); current < length(); ++current) { 1750 for (int current = from->length(); current < length(); ++current) {
1681 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double()); 1751 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1682 offset += kDoubleSize; 1752 offset += kDoubleSize;
1683 } 1753 }
1684 } 1754 }
1685 1755
1686 1756
1687 void FixedDoubleArray::Initialize(FixedArray* from) { 1757 void FixedDoubleArray::Initialize(FixedArray* from) {
1688 int old_length = from->length(); 1758 int old_length = from->length();
1689 ASSERT(old_length < length()); 1759 ASSERT(old_length <= length());
1690 for (int i = 0; i < old_length; i++) { 1760 for (int i = 0; i < old_length; i++) {
1691 Object* hole_or_object = from->get(i); 1761 Object* hole_or_object = from->get(i);
1692 if (hole_or_object->IsTheHole()) { 1762 if (hole_or_object->IsTheHole()) {
1693 set_the_hole(i); 1763 set_the_hole(i);
1694 } else { 1764 } else {
1695 set(i, hole_or_object->Number()); 1765 set(i, hole_or_object->Number());
1696 } 1766 }
1697 } 1767 }
1698 int offset = kHeaderSize + old_length * kDoubleSize; 1768 int offset = kHeaderSize + old_length * kDoubleSize;
1699 for (int current = from->length(); current < length(); ++current) { 1769 for (int current = from->length(); current < length(); ++current) {
(...skipping 2250 matching lines...) Expand 10 before | Expand all | Expand 10 after
3950 fa->set_unchecked(index, Smi::cast(value)); 4020 fa->set_unchecked(index, Smi::cast(value));
3951 } else { 4021 } else {
3952 // We only do this during GC, so we don't need to notify the write barrier. 4022 // We only do this during GC, so we don't need to notify the write barrier.
3953 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER); 4023 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
3954 } 4024 }
3955 } 4025 }
3956 4026
3957 4027
3958 ElementsKind JSObject::GetElementsKind() { 4028 ElementsKind JSObject::GetElementsKind() {
3959 ElementsKind kind = map()->elements_kind(); 4029 ElementsKind kind = map()->elements_kind();
3960 ASSERT((kind == FAST_ELEMENTS && 4030 #if DEBUG
3961 (elements()->map() == GetHeap()->fixed_array_map() || 4031 FixedArrayBase* fixed_array =
3962 elements()->map() == GetHeap()->fixed_cow_array_map())) || 4032 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4033 Map* map = fixed_array->map();
4034 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
4035 (map == GetHeap()->fixed_array_map() ||
4036 map == GetHeap()->fixed_cow_array_map())) ||
3963 (kind == FAST_DOUBLE_ELEMENTS && 4037 (kind == FAST_DOUBLE_ELEMENTS &&
3964 elements()->IsFixedDoubleArray()) || 4038 fixed_array->IsFixedDoubleArray()) ||
3965 (kind == DICTIONARY_ELEMENTS && 4039 (kind == DICTIONARY_ELEMENTS &&
3966 elements()->IsFixedArray() && 4040 fixed_array->IsFixedArray() &&
3967 elements()->IsDictionary()) || 4041 fixed_array->IsDictionary()) ||
3968 (kind > DICTIONARY_ELEMENTS)); 4042 (kind > DICTIONARY_ELEMENTS));
4043 #endif
3969 return kind; 4044 return kind;
3970 } 4045 }
3971 4046
3972 4047
3973 ElementsAccessor* JSObject::GetElementsAccessor() { 4048 ElementsAccessor* JSObject::GetElementsAccessor() {
3974 return ElementsAccessor::ForKind(GetElementsKind()); 4049 return ElementsAccessor::ForKind(GetElementsKind());
3975 } 4050 }
3976 4051
3977 4052
3978 bool JSObject::HasFastElements() { 4053 bool JSObject::HasFastElements() {
3979 return GetElementsKind() == FAST_ELEMENTS; 4054 return GetElementsKind() == FAST_ELEMENTS;
3980 } 4055 }
3981 4056
3982 4057
4058 bool JSObject::HasFastSmiOnlyElements() {
4059 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4060 }
4061
4062
4063 bool JSObject::HasFastTypeElements() {
4064 ElementsKind elements_kind = GetElementsKind();
4065 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4066 elements_kind == FAST_ELEMENTS;
4067 }
4068
4069
3983 bool JSObject::HasFastDoubleElements() { 4070 bool JSObject::HasFastDoubleElements() {
3984 return GetElementsKind() == FAST_DOUBLE_ELEMENTS; 4071 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
3985 } 4072 }
3986 4073
3987 4074
3988 bool JSObject::HasDictionaryElements() { 4075 bool JSObject::HasDictionaryElements() {
3989 return GetElementsKind() == DICTIONARY_ELEMENTS; 4076 return GetElementsKind() == DICTIONARY_ELEMENTS;
3990 } 4077 }
3991 4078
3992 4079
4080 bool JSObject::HasNonStrictArgumentsElements() {
4081 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4082 }
4083
4084
3993 bool JSObject::HasExternalArrayElements() { 4085 bool JSObject::HasExternalArrayElements() {
3994 HeapObject* array = elements(); 4086 HeapObject* array = elements();
3995 ASSERT(array != NULL); 4087 ASSERT(array != NULL);
3996 return array->IsExternalArray(); 4088 return array->IsExternalArray();
3997 } 4089 }
3998 4090
3999 4091
4000 #define EXTERNAL_ELEMENTS_CHECK(name, type) \ 4092 #define EXTERNAL_ELEMENTS_CHECK(name, type) \
4001 bool JSObject::HasExternal##name##Elements() { \ 4093 bool JSObject::HasExternal##name##Elements() { \
4002 HeapObject* array = elements(); \ 4094 HeapObject* array = elements(); \
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
4034 4126
4035 bool JSObject::AllowsSetElementsLength() { 4127 bool JSObject::AllowsSetElementsLength() {
4036 bool result = elements()->IsFixedArray() || 4128 bool result = elements()->IsFixedArray() ||
4037 elements()->IsFixedDoubleArray(); 4129 elements()->IsFixedDoubleArray();
4038 ASSERT(result == !HasExternalArrayElements()); 4130 ASSERT(result == !HasExternalArrayElements());
4039 return result; 4131 return result;
4040 } 4132 }
4041 4133
4042 4134
4043 MaybeObject* JSObject::EnsureWritableFastElements() { 4135 MaybeObject* JSObject::EnsureWritableFastElements() {
4044 ASSERT(HasFastElements()); 4136 ASSERT(HasFastTypeElements());
4045 FixedArray* elems = FixedArray::cast(elements()); 4137 FixedArray* elems = FixedArray::cast(elements());
4046 Isolate* isolate = GetIsolate(); 4138 Isolate* isolate = GetIsolate();
4047 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; 4139 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
4048 Object* writable_elems; 4140 Object* writable_elems;
4049 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap( 4141 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4050 elems, isolate->heap()->fixed_array_map()); 4142 elems, isolate->heap()->fixed_array_map());
4051 if (!maybe_writable_elems->ToObject(&writable_elems)) { 4143 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4052 return maybe_writable_elems; 4144 return maybe_writable_elems;
4053 } 4145 }
4054 } 4146 }
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
4402 void Map::ClearCodeCache(Heap* heap) { 4494 void Map::ClearCodeCache(Heap* heap) {
4403 // No write barrier is needed since empty_fixed_array is not in new space. 4495 // No write barrier is needed since empty_fixed_array is not in new space.
4404 // Please note this function is used during marking: 4496 // Please note this function is used during marking:
4405 // - MarkCompactCollector::MarkUnmarkedObject 4497 // - MarkCompactCollector::MarkUnmarkedObject
4406 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array())); 4498 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4407 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array()); 4499 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
4408 } 4500 }
4409 4501
4410 4502
4411 void JSArray::EnsureSize(int required_size) { 4503 void JSArray::EnsureSize(int required_size) {
4412 ASSERT(HasFastElements()); 4504 ASSERT(HasFastTypeElements());
4413 FixedArray* elts = FixedArray::cast(elements()); 4505 FixedArray* elts = FixedArray::cast(elements());
4414 const int kArraySizeThatFitsComfortablyInNewSpace = 128; 4506 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4415 if (elts->length() < required_size) { 4507 if (elts->length() < required_size) {
4416 // Doubling in size would be overkill, but leave some slack to avoid 4508 // Doubling in size would be overkill, but leave some slack to avoid
4417 // constantly growing. 4509 // constantly growing.
4418 Expand(required_size + (required_size >> 3)); 4510 Expand(required_size + (required_size >> 3));
4419 // It's a performance benefit to keep a frequently used array in new-space. 4511 // It's a performance benefit to keep a frequently used array in new-space.
4420 } else if (!GetHeap()->new_space()->Contains(elts) && 4512 } else if (!GetHeap()->new_space()->Contains(elts) &&
4421 required_size < kArraySizeThatFitsComfortablyInNewSpace) { 4513 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4422 // Expand will allocate a new backing store in new space even if the size 4514 // Expand will allocate a new backing store in new space even if the size
4423 // we asked for isn't larger than what we had before. 4515 // we asked for isn't larger than what we had before.
4424 Expand(required_size); 4516 Expand(required_size);
4425 } 4517 }
4426 } 4518 }
4427 4519
4428 4520
4429 void JSArray::set_length(Smi* length) { 4521 void JSArray::set_length(Smi* length) {
4430 // Don't need a write barrier for a Smi. 4522 // Don't need a write barrier for a Smi.
4431 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER); 4523 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4432 } 4524 }
4433 4525
4434 4526
4435 void JSArray::SetContent(FixedArray* storage) { 4527 MaybeObject* JSArray::SetContent(FixedArray* storage) {
4528 MaybeObject* maybe_object = EnsureCanContainElements(storage);
4529 if (maybe_object->IsFailure()) return maybe_object;
4436 set_length(Smi::FromInt(storage->length())); 4530 set_length(Smi::FromInt(storage->length()));
4437 set_elements(storage); 4531 set_elements(storage);
4532 return this;
4438 } 4533 }
4439 4534
4440 4535
4441 MaybeObject* FixedArray::Copy() { 4536 MaybeObject* FixedArray::Copy() {
4442 if (length() == 0) return this; 4537 if (length() == 0) return this;
4443 return GetHeap()->CopyFixedArray(this); 4538 return GetHeap()->CopyFixedArray(this);
4444 } 4539 }
4445 4540
4446 4541
4447 Relocatable::Relocatable(Isolate* isolate) { 4542 Relocatable::Relocatable(Isolate* isolate) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
4544 #undef WRITE_INT_FIELD 4639 #undef WRITE_INT_FIELD
4545 #undef READ_SHORT_FIELD 4640 #undef READ_SHORT_FIELD
4546 #undef WRITE_SHORT_FIELD 4641 #undef WRITE_SHORT_FIELD
4547 #undef READ_BYTE_FIELD 4642 #undef READ_BYTE_FIELD
4548 #undef WRITE_BYTE_FIELD 4643 #undef WRITE_BYTE_FIELD
4549 4644
4550 4645
4551 } } // namespace v8::internal 4646 } } // namespace v8::internal
4552 4647
4553 #endif // V8_OBJECTS_INL_H_ 4648 #endif // V8_OBJECTS_INL_H_
OLDNEW
« src/bootstrapper.cc ('K') | « src/objects-debug.cc ('k') | src/objects-printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698