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

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

Powered by Google App Engine
This is Rietveld 408576698