Commit 523851b3 authored by rafaelw@chromium.org's avatar rafaelw@chromium.org

Handlify JSObject::PrepareElementsForSort

BUG=
R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/32523008

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17402 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 77b3da38
......@@ -343,6 +343,14 @@ static MaybeObject* GetDeclaredAccessorProperty(Object* receiver,
}
Handle<FixedArray> JSObject::EnsureWritableFastElements(
Handle<JSObject> object) {
CALL_HEAP_FUNCTION(object->GetIsolate(),
object->EnsureWritableFastElements(),
FixedArray);
}
Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
Handle<Object> receiver,
Handle<Object> structure,
......@@ -14287,6 +14295,14 @@ template
int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
Handle<Object> JSObject::PrepareSlowElementsForSort(
Handle<JSObject> object, uint32_t limit) {
CALL_HEAP_FUNCTION(object->GetIsolate(),
object->PrepareSlowElementsForSort(limit),
Object);
}
// Collates undefined and unexisting elements below limit from position
// zero of the elements. The object stays in Dictionary mode.
MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
......@@ -14389,74 +14405,57 @@ MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
// the start of the elements array.
// If the object is in dictionary mode, it is converted to fast elements
// mode.
MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
Heap* heap = GetHeap();
Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
uint32_t limit) {
Isolate* isolate = object->GetIsolate();
ASSERT(!map()->is_observed());
if (HasDictionaryElements()) {
ASSERT(!object->map()->is_observed());
if (object->HasDictionaryElements()) {
// Convert to fast elements containing only the existing properties.
// Ordering is irrelevant, since we are going to sort anyway.
SeededNumberDictionary* dict = element_dictionary();
if (IsJSArray() || dict->requires_slow_elements() ||
Handle<SeededNumberDictionary> dict(object->element_dictionary());
if (object->IsJSArray() || dict->requires_slow_elements() ||
dict->max_number_key() >= limit) {
return PrepareSlowElementsForSort(limit);
return JSObject::PrepareSlowElementsForSort(object, limit);
}
// Convert to fast elements.
Object* obj;
MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
FAST_HOLEY_ELEMENTS);
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
Map* new_map = Map::cast(obj);
Handle<Map> new_map =
JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS);
PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED;
Object* new_array;
{ MaybeObject* maybe_new_array =
heap->AllocateFixedArray(dict->NumberOfElements(), tenure);
if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array;
}
FixedArray* fast_elements = FixedArray::cast(new_array);
dict->CopyValuesTo(fast_elements);
ValidateElements();
PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ?
NOT_TENURED: TENURED;
Handle<FixedArray> fast_elements =
isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure);
dict->CopyValuesTo(*fast_elements);
object->ValidateElements();
set_map_and_elements(new_map, fast_elements);
} else if (HasExternalArrayElements()) {
object->set_map_and_elements(*new_map, *fast_elements);
} else if (object->HasExternalArrayElements()) {
// External arrays cannot have holes or undefined elements.
return Smi::FromInt(ExternalArray::cast(elements())->length());
} else if (!HasFastDoubleElements()) {
Object* obj;
{ MaybeObject* maybe_obj = EnsureWritableFastElements();
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
}
return handle(Smi::FromInt(
ExternalArray::cast(object->elements())->length()), isolate);
} else if (!object->HasFastDoubleElements()) {
JSObject::EnsureWritableFastElements(object);
}
ASSERT(HasFastSmiOrObjectElements() || HasFastDoubleElements());
ASSERT(object->HasFastSmiOrObjectElements() ||
object->HasFastDoubleElements());
// Collect holes at the end, undefined before that and the rest at the
// start, and return the number of non-hole, non-undefined values.
FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements());
Handle<FixedArrayBase> elements_base(object->elements());
uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
if (limit > elements_length) {
limit = elements_length ;
}
if (limit == 0) {
return Smi::FromInt(0);
}
HeapNumber* result_double = NULL;
if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
// Pessimistically allocate space for return value before
// we start mutating the array.
Object* new_double;
{ MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0);
if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
}
result_double = HeapNumber::cast(new_double);
return handle(Smi::FromInt(0), isolate);
}
uint32_t result = 0;
if (elements_base->map() == heap->fixed_double_array_map()) {
FixedDoubleArray* elements = FixedDoubleArray::cast(elements_base);
if (elements_base->map() == isolate->heap()->fixed_double_array_map()) {
FixedDoubleArray* elements = FixedDoubleArray::cast(*elements_base);
// Split elements into defined and the_hole, in that order.
unsigned int holes = limit;
// Assume most arrays contain no holes and undefined values, so minimize the
......@@ -14483,7 +14482,7 @@ MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
holes++;
}
} else {
FixedArray* elements = FixedArray::cast(elements_base);
FixedArray* elements = FixedArray::cast(*elements_base);
DisallowHeapAllocation no_gc;
// Split elements into defined, undefined and the_hole, in that order. Only
......@@ -14528,12 +14527,7 @@ MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) {
}
}
if (result <= static_cast<uint32_t>(Smi::kMaxValue)) {
return Smi::FromInt(static_cast<int>(result));
}
ASSERT_NE(NULL, result_double);
result_double->set_value(static_cast<double>(result));
return result_double;
return isolate->factory()->NewNumberFromUint(result);
}
......
......@@ -2112,14 +2112,19 @@ class JSObject: public JSReceiver {
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
// Requires: HasFastElements().
static Handle<FixedArray> EnsureWritableFastElements(
Handle<JSObject> object);
MUST_USE_RESULT inline MaybeObject* EnsureWritableFastElements();
// Collects elements starting at index 0.
// Undefined values are placed after non-undefined values.
// Returns the number of non-undefined values.
MUST_USE_RESULT MaybeObject* PrepareElementsForSort(uint32_t limit);
static Handle<Object> PrepareElementsForSort(Handle<JSObject> object,
uint32_t limit);
// As PrepareElementsForSort, but only on objects where elements is
// a dictionary, and it will stay a dictionary.
static Handle<Object> PrepareSlowElementsForSort(Handle<JSObject> object,
uint32_t limit);
MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit);
static Handle<Object> GetPropertyWithCallback(Handle<JSObject> object,
......
......@@ -10548,11 +10548,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GlobalPrint) {
// property.
// Returns the number of non-undefined elements collected.
RUNTIME_FUNCTION(MaybeObject*, Runtime_RemoveArrayHoles) {
SealHandleScope shs(isolate);
HandleScope scope(isolate);
ASSERT(args.length() == 2);
CONVERT_ARG_CHECKED(JSObject, object, 0);
CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
return object->PrepareElementsForSort(limit);
return *JSObject::PrepareElementsForSort(object, limit);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment