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

Side by Side Diff: src/objects.cc

Issue 238713003: Handlify PrepareSlowElementsForSort and JSArrayUpdateLengthFromIndex. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 8 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.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 13065 matching lines...) Expand 10 before | Expand all | Expand 10 after
13076 13076
13077 // Transitions from HOLEY -> PACKED are not allowed. 13077 // Transitions from HOLEY -> PACKED are not allowed.
13078 return !IsFastHoleyElementsKind(from_kind) || 13078 return !IsFastHoleyElementsKind(from_kind) ||
13079 IsFastHoleyElementsKind(to_kind); 13079 IsFastHoleyElementsKind(to_kind);
13080 } 13080 }
13081 13081
13082 13082
13083 void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array, 13083 void JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray> array,
13084 uint32_t index, 13084 uint32_t index,
13085 Handle<Object> value) { 13085 Handle<Object> value) {
13086 CALL_HEAP_FUNCTION_VOID(array->GetIsolate(), 13086 uint32_t old_len = 0;
13087 array->JSArrayUpdateLengthFromIndex(index, *value)); 13087 CHECK(array->length()->ToArrayIndex(&old_len));
13088 // Check to see if we need to update the length. For now, we make
13089 // sure that the length stays within 32-bits (unsigned).
13090 if (index >= old_len && index != 0xffffffff) {
13091 Handle<Object> len = array->GetIsolate()->factory()->NewNumber(
13092 static_cast<double>(index) + 1);
13093 array->set_length(*len);
13094 }
13088 } 13095 }
13089 13096
13090 13097
13091 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index,
13092 Object* value) {
13093 uint32_t old_len = 0;
13094 CHECK(length()->ToArrayIndex(&old_len));
13095 // Check to see if we need to update the length. For now, we make
13096 // sure that the length stays within 32-bits (unsigned).
13097 if (index >= old_len && index != 0xffffffff) {
13098 Object* len;
13099 { MaybeObject* maybe_len =
13100 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1);
13101 if (!maybe_len->ToObject(&len)) return maybe_len;
13102 }
13103 set_length(len);
13104 }
13105 return value;
13106 }
13107
13108
13109 MaybeHandle<Object> JSObject::GetElementWithInterceptor( 13098 MaybeHandle<Object> JSObject::GetElementWithInterceptor(
13110 Handle<JSObject> object, 13099 Handle<JSObject> object,
13111 Handle<Object> receiver, 13100 Handle<Object> receiver,
13112 uint32_t index) { 13101 uint32_t index) {
13113 Isolate* isolate = object->GetIsolate(); 13102 Isolate* isolate = object->GetIsolate();
13114 13103
13115 // Make sure that the top context does not change when doing 13104 // Make sure that the top context does not change when doing
13116 // callbacks or interceptor calls. 13105 // callbacks or interceptor calls.
13117 AssertNoContextChange ncc(isolate); 13106 AssertNoContextChange ncc(isolate);
13118 13107
(...skipping 1394 matching lines...) Expand 10 before | Expand all | Expand 10 after
14513 Handle<Object> value, 14502 Handle<Object> value,
14514 PropertyDetails details) { 14503 PropertyDetails details) {
14515 CALL_HEAP_FUNCTION(dict->GetIsolate(), 14504 CALL_HEAP_FUNCTION(dict->GetIsolate(),
14516 dict->Add(*name, *value, details), 14505 dict->Add(*name, *value, details),
14517 NameDictionary); 14506 NameDictionary);
14518 } 14507 }
14519 14508
14520 14509
14521 Handle<Object> JSObject::PrepareSlowElementsForSort( 14510 Handle<Object> JSObject::PrepareSlowElementsForSort(
14522 Handle<JSObject> object, uint32_t limit) { 14511 Handle<JSObject> object, uint32_t limit) {
14523 CALL_HEAP_FUNCTION(object->GetIsolate(), 14512 ASSERT(object->HasDictionaryElements());
14524 object->PrepareSlowElementsForSort(limit), 14513 Isolate* isolate = object->GetIsolate();
14525 Object);
14526 }
14527
14528
14529 // Collates undefined and unexisting elements below limit from position
14530 // zero of the elements. The object stays in Dictionary mode.
14531 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
14532 ASSERT(HasDictionaryElements());
14533 // Must stay in dictionary mode, either because of requires_slow_elements, 14514 // Must stay in dictionary mode, either because of requires_slow_elements,
14534 // or because we are not going to sort (and therefore compact) all of the 14515 // or because we are not going to sort (and therefore compact) all of the
14535 // elements. 14516 // elements.
14536 SeededNumberDictionary* dict = element_dictionary(); 14517 Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate);
14537 HeapNumber* result_double = NULL; 14518 Handle<SeededNumberDictionary> new_dict =
14538 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 14519 isolate->factory()->NewSeededNumberDictionary(dict->NumberOfElements());
14539 // Allocate space for result before we start mutating the object.
14540 Object* new_double;
14541 { MaybeObject* maybe_new_double = GetHeap()->AllocateHeapNumber(0.0);
14542 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
14543 }
14544 result_double = HeapNumber::cast(new_double);
14545 }
14546
14547 Object* obj;
14548 { MaybeObject* maybe_obj =
14549 SeededNumberDictionary::Allocate(GetHeap(), dict->NumberOfElements());
14550 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
14551 }
14552 SeededNumberDictionary* new_dict = SeededNumberDictionary::cast(obj);
14553
14554 DisallowHeapAllocation no_alloc;
14555 14520
14556 uint32_t pos = 0; 14521 uint32_t pos = 0;
14557 uint32_t undefs = 0; 14522 uint32_t undefs = 0;
14558 int capacity = dict->Capacity(); 14523 int capacity = dict->Capacity();
14524 Handle<Smi> bailout(Smi::FromInt(-1), isolate);
14525 // Entry to the new dictionary does not cause it to grow, as we have
14526 // allocated one that is large enough for all entries.
14527 DisallowHeapAllocation no_gc;
14559 for (int i = 0; i < capacity; i++) { 14528 for (int i = 0; i < capacity; i++) {
14560 Object* k = dict->KeyAt(i); 14529 Object* k = dict->KeyAt(i);
14561 if (dict->IsKey(k)) { 14530 if (!dict->IsKey(k)) continue;
14562 ASSERT(k->IsNumber()); 14531
14563 ASSERT(!k->IsSmi() || Smi::cast(k)->value() >= 0); 14532 ASSERT(k->IsNumber());
14564 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); 14533 ASSERT(!k->IsSmi() || Smi::cast(k)->value() >= 0);
14565 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); 14534 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0);
14566 Object* value = dict->ValueAt(i); 14535 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32);
14567 PropertyDetails details = dict->DetailsAt(i); 14536
14568 if (details.type() == CALLBACKS || details.IsReadOnly()) { 14537 HandleScope scope(isolate);
14569 // Bail out and do the sorting of undefineds and array holes in JS. 14538 Handle<Object> value(dict->ValueAt(i), isolate);
14570 // Also bail out if the element is not supposed to be moved. 14539 PropertyDetails details = dict->DetailsAt(i);
14571 return Smi::FromInt(-1); 14540 if (details.type() == CALLBACKS || details.IsReadOnly()) {
14541 // Bail out and do the sorting of undefineds and array holes in JS.
14542 // Also bail out if the element is not supposed to be moved.
14543 return bailout;
14544 }
14545
14546 uint32_t key = NumberToUint32(k);
14547 if (key < limit) {
14548 if (value->IsUndefined()) {
14549 undefs++;
14550 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
14551 // Adding an entry with the key beyond smi-range requires
14552 // allocation. Bailout.
14553 return bailout;
14554 } else {
14555 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14556 new_dict, pos, value, details);
14557 ASSERT(result.is_identical_to(new_dict));
14558 USE(result);
14559 pos++;
14572 } 14560 }
14573 uint32_t key = NumberToUint32(k); 14561 } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
14574 // In the following we assert that adding the entry to the new dictionary 14562 // Adding an entry with the key beyond smi-range requires
14575 // does not cause GC. This is the case because we made sure to allocate 14563 // allocation. Bailout.
14576 // the dictionary big enough above, so it need not grow. 14564 return bailout;
14577 if (key < limit) { 14565 } else {
14578 if (value->IsUndefined()) { 14566 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14579 undefs++; 14567 new_dict, key, value, details);
14580 } else { 14568 ASSERT(result.is_identical_to(new_dict));
14581 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { 14569 USE(result);
14582 // Adding an entry with the key beyond smi-range requires
14583 // allocation. Bailout.
14584 return Smi::FromInt(-1);
14585 }
14586 new_dict->AddNumberEntry(pos, value, details)->ToObjectUnchecked();
14587 pos++;
14588 }
14589 } else {
14590 if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
14591 // Adding an entry with the key beyond smi-range requires
14592 // allocation. Bailout.
14593 return Smi::FromInt(-1);
14594 }
14595 new_dict->AddNumberEntry(key, value, details)->ToObjectUnchecked();
14596 }
14597 } 14570 }
14598 } 14571 }
14599 14572
14600 uint32_t result = pos; 14573 uint32_t result = pos;
14601 PropertyDetails no_details = PropertyDetails(NONE, NORMAL, 0); 14574 PropertyDetails no_details = PropertyDetails(NONE, NORMAL, 0);
14602 Heap* heap = GetHeap();
14603 while (undefs > 0) { 14575 while (undefs > 0) {
14604 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { 14576 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
14605 // Adding an entry with the key beyond smi-range requires 14577 // Adding an entry with the key beyond smi-range requires
14606 // allocation. Bailout. 14578 // allocation. Bailout.
14607 return Smi::FromInt(-1); 14579 return bailout;
14608 } 14580 }
14609 new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details)-> 14581 HandleScope scope(isolate);
14610 ToObjectUnchecked(); 14582 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
14583 new_dict, pos, isolate->factory()->undefined_value(), no_details);
14584 ASSERT(result.is_identical_to(new_dict));
14585 USE(result);
14611 pos++; 14586 pos++;
14612 undefs--; 14587 undefs--;
14613 } 14588 }
14614 14589
14615 set_elements(new_dict); 14590 object->set_elements(*new_dict);
14616 14591
14617 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { 14592 AllowHeapAllocation allocate_return_value;
14618 return Smi::FromInt(static_cast<int>(result)); 14593 return isolate->factory()->NewNumberFromUint(result);
mvstanton 2014/04/15 09:56:19 Nice consolidation to use NewNumberFromUint().
14619 }
14620
14621 ASSERT_NE(NULL, result_double);
14622 result_double->set_value(static_cast<double>(result));
14623 return result_double;
14624 } 14594 }
14625 14595
14626 14596
14627 // Collects all defined (non-hole) and non-undefined (array) elements at 14597 // Collects all defined (non-hole) and non-undefined (array) elements at
14628 // the start of the elements array. 14598 // the start of the elements array.
14629 // If the object is in dictionary mode, it is converted to fast elements 14599 // If the object is in dictionary mode, it is converted to fast elements
14630 // mode. 14600 // mode.
14631 Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object, 14601 Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
14632 uint32_t limit) { 14602 uint32_t limit) {
14633 Isolate* isolate = object->GetIsolate(); 14603 Isolate* isolate = object->GetIsolate();
(...skipping 1986 matching lines...) Expand 10 before | Expand all | Expand 10 after
16620 #define ERROR_MESSAGES_TEXTS(C, T) T, 16590 #define ERROR_MESSAGES_TEXTS(C, T) T,
16621 static const char* error_messages_[] = { 16591 static const char* error_messages_[] = {
16622 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16592 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16623 }; 16593 };
16624 #undef ERROR_MESSAGES_TEXTS 16594 #undef ERROR_MESSAGES_TEXTS
16625 return error_messages_[reason]; 16595 return error_messages_[reason];
16626 } 16596 }
16627 16597
16628 16598
16629 } } // namespace v8::internal 16599 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698