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

Side by Side Diff: src/objects.cc

Issue 32523008: Handlify JSObject::PrepareElementsForSort (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: cr changes Created 7 years, 1 month 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') | src/runtime.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 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 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 return GetPrimitiveValue(data->primitive_value_descriptor, 336 return GetPrimitiveValue(data->primitive_value_descriptor,
337 current, 337 current,
338 isolate->heap()); 338 isolate->heap());
339 } 339 }
340 } 340 }
341 UNREACHABLE(); 341 UNREACHABLE();
342 return NULL; 342 return NULL;
343 } 343 }
344 344
345 345
346 Handle<FixedArray> JSObject::EnsureWritableFastElements(
347 Handle<JSObject> object) {
348 CALL_HEAP_FUNCTION(object->GetIsolate(),
349 object->EnsureWritableFastElements(),
350 FixedArray);
351 }
352
353
346 Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object, 354 Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
347 Handle<Object> receiver, 355 Handle<Object> receiver,
348 Handle<Object> structure, 356 Handle<Object> structure,
349 Handle<Name> name) { 357 Handle<Name> name) {
350 Isolate* isolate = name->GetIsolate(); 358 Isolate* isolate = name->GetIsolate();
351 // To accommodate both the old and the new api we switch on the 359 // To accommodate both the old and the new api we switch on the
352 // data structure used to store the callbacks. Eventually foreign 360 // data structure used to store the callbacks. Eventually foreign
353 // callbacks should be phased out. 361 // callbacks should be phased out.
354 if (structure->IsForeign()) { 362 if (structure->IsForeign()) {
355 AccessorDescriptor* callback = 363 AccessorDescriptor* callback =
(...skipping 13924 matching lines...) Expand 10 before | Expand all | Expand 10 after
14280 template 14288 template
14281 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); 14289 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements();
14282 14290
14283 template 14291 template
14284 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements(); 14292 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements();
14285 14293
14286 template 14294 template
14287 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); 14295 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
14288 14296
14289 14297
14298 Handle<Object> JSObject::PrepareSlowElementsForSort(
14299 Handle<JSObject> object, uint32_t limit) {
14300 CALL_HEAP_FUNCTION(object->GetIsolate(),
14301 object->PrepareSlowElementsForSort(limit),
14302 Object);
14303 }
14304
14305
14290 // Collates undefined and unexisting elements below limit from position 14306 // Collates undefined and unexisting elements below limit from position
14291 // zero of the elements. The object stays in Dictionary mode. 14307 // zero of the elements. The object stays in Dictionary mode.
14292 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { 14308 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
14293 ASSERT(HasDictionaryElements()); 14309 ASSERT(HasDictionaryElements());
14294 // Must stay in dictionary mode, either because of requires_slow_elements, 14310 // Must stay in dictionary mode, either because of requires_slow_elements,
14295 // or because we are not going to sort (and therefore compact) all of the 14311 // or because we are not going to sort (and therefore compact) all of the
14296 // elements. 14312 // elements.
14297 SeededNumberDictionary* dict = element_dictionary(); 14313 SeededNumberDictionary* dict = element_dictionary();
14298 HeapNumber* result_double = NULL; 14314 HeapNumber* result_double = NULL;
14299 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 14315 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
14382 ASSERT_NE(NULL, result_double); 14398 ASSERT_NE(NULL, result_double);
14383 result_double->set_value(static_cast<double>(result)); 14399 result_double->set_value(static_cast<double>(result));
14384 return result_double; 14400 return result_double;
14385 } 14401 }
14386 14402
14387 14403
14388 // Collects all defined (non-hole) and non-undefined (array) elements at 14404 // Collects all defined (non-hole) and non-undefined (array) elements at
14389 // the start of the elements array. 14405 // the start of the elements array.
14390 // If the object is in dictionary mode, it is converted to fast elements 14406 // If the object is in dictionary mode, it is converted to fast elements
14391 // mode. 14407 // mode.
14392 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { 14408 Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
14393 Heap* heap = GetHeap(); 14409 uint32_t limit) {
14410 Isolate* isolate = object->GetIsolate();
14394 14411
14395 ASSERT(!map()->is_observed()); 14412 ASSERT(!object->map()->is_observed());
14396 if (HasDictionaryElements()) { 14413 if (object->HasDictionaryElements()) {
14397 // Convert to fast elements containing only the existing properties. 14414 // Convert to fast elements containing only the existing properties.
14398 // Ordering is irrelevant, since we are going to sort anyway. 14415 // Ordering is irrelevant, since we are going to sort anyway.
14399 SeededNumberDictionary* dict = element_dictionary(); 14416 Handle<SeededNumberDictionary> dict(object->element_dictionary());
14400 if (IsJSArray() || dict->requires_slow_elements() || 14417 if (object->IsJSArray() || dict->requires_slow_elements() ||
14401 dict->max_number_key() >= limit) { 14418 dict->max_number_key() >= limit) {
14402 return PrepareSlowElementsForSort(limit); 14419 return JSObject::PrepareSlowElementsForSort(object, limit);
14403 } 14420 }
14404 // Convert to fast elements. 14421 // Convert to fast elements.
14405 14422
14406 Object* obj; 14423 Handle<Map> new_map =
14407 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), 14424 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS);
14408 FAST_HOLEY_ELEMENTS);
14409 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
14410 Map* new_map = Map::cast(obj);
14411 14425
14412 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED; 14426 PretenureFlag tenure = isolate->heap()->InNewSpace(*object) ?
14413 Object* new_array; 14427 NOT_TENURED: TENURED;
14414 { MaybeObject* maybe_new_array = 14428 Handle<FixedArray> fast_elements =
14415 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); 14429 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure);
14416 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; 14430 dict->CopyValuesTo(*fast_elements);
14417 } 14431 object->ValidateElements();
14418 FixedArray* fast_elements = FixedArray::cast(new_array);
14419 dict->CopyValuesTo(fast_elements);
14420 ValidateElements();
14421 14432
14422 set_map_and_elements(new_map, fast_elements); 14433 object->set_map_and_elements(*new_map, *fast_elements);
14423 } else if (HasExternalArrayElements()) { 14434 } else if (object->HasExternalArrayElements()) {
14424 // External arrays cannot have holes or undefined elements. 14435 // External arrays cannot have holes or undefined elements.
14425 return Smi::FromInt(ExternalArray::cast(elements())->length()); 14436 return handle(Smi::FromInt(
14426 } else if (!HasFastDoubleElements()) { 14437 ExternalArray::cast(object->elements())->length()), isolate);
14427 Object* obj; 14438 } else if (!object->HasFastDoubleElements()) {
14428 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 14439 JSObject::EnsureWritableFastElements(object);
14429 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
14430 }
14431 } 14440 }
14432 ASSERT(HasFastSmiOrObjectElements() || HasFastDoubleElements()); 14441 ASSERT(object->HasFastSmiOrObjectElements() ||
14442 object->HasFastDoubleElements());
14433 14443
14434 // Collect holes at the end, undefined before that and the rest at the 14444 // Collect holes at the end, undefined before that and the rest at the
14435 // start, and return the number of non-hole, non-undefined values. 14445 // start, and return the number of non-hole, non-undefined values.
14436 14446
14437 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements()); 14447 Handle<FixedArrayBase> elements_base(object->elements());
14438 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); 14448 uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
14439 if (limit > elements_length) { 14449 if (limit > elements_length) {
14440 limit = elements_length ; 14450 limit = elements_length ;
14441 } 14451 }
14442 if (limit == 0) { 14452 if (limit == 0) {
14443 return Smi::FromInt(0); 14453 return handle(Smi::FromInt(0), isolate);
14444 }
14445
14446 HeapNumber* result_double = NULL;
14447 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
14448 // Pessimistically allocate space for return value before
14449 // we start mutating the array.
14450 Object* new_double;
14451 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0);
14452 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
14453 }
14454 result_double = HeapNumber::cast(new_double);
14455 } 14454 }
14456 14455
14457 uint32_t result = 0; 14456 uint32_t result = 0;
14458 if (elements_base->map() == heap->fixed_double_array_map()) { 14457 if (elements_base->map() == isolate->heap()->fixed_double_array_map()) {
14459 FixedDoubleArray* elements = FixedDoubleArray::cast(elements_base); 14458 FixedDoubleArray* elements = FixedDoubleArray::cast(*elements_base);
14460 // Split elements into defined and the_hole, in that order. 14459 // Split elements into defined and the_hole, in that order.
14461 unsigned int holes = limit; 14460 unsigned int holes = limit;
14462 // Assume most arrays contain no holes and undefined values, so minimize the 14461 // Assume most arrays contain no holes and undefined values, so minimize the
14463 // number of stores of non-undefined, non-the-hole values. 14462 // number of stores of non-undefined, non-the-hole values.
14464 for (unsigned int i = 0; i < holes; i++) { 14463 for (unsigned int i = 0; i < holes; i++) {
14465 if (elements->is_the_hole(i)) { 14464 if (elements->is_the_hole(i)) {
14466 holes--; 14465 holes--;
14467 } else { 14466 } else {
14468 continue; 14467 continue;
14469 } 14468 }
14470 // Position i needs to be filled. 14469 // Position i needs to be filled.
14471 while (holes > i) { 14470 while (holes > i) {
14472 if (elements->is_the_hole(holes)) { 14471 if (elements->is_the_hole(holes)) {
14473 holes--; 14472 holes--;
14474 } else { 14473 } else {
14475 elements->set(i, elements->get_scalar(holes)); 14474 elements->set(i, elements->get_scalar(holes));
14476 break; 14475 break;
14477 } 14476 }
14478 } 14477 }
14479 } 14478 }
14480 result = holes; 14479 result = holes;
14481 while (holes < limit) { 14480 while (holes < limit) {
14482 elements->set_the_hole(holes); 14481 elements->set_the_hole(holes);
14483 holes++; 14482 holes++;
14484 } 14483 }
14485 } else { 14484 } else {
14486 FixedArray* elements = FixedArray::cast(elements_base); 14485 FixedArray* elements = FixedArray::cast(*elements_base);
14487 DisallowHeapAllocation no_gc; 14486 DisallowHeapAllocation no_gc;
14488 14487
14489 // Split elements into defined, undefined and the_hole, in that order. Only 14488 // Split elements into defined, undefined and the_hole, in that order. Only
14490 // count locations for undefined and the hole, and fill them afterwards. 14489 // count locations for undefined and the hole, and fill them afterwards.
14491 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc); 14490 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc);
14492 unsigned int undefs = limit; 14491 unsigned int undefs = limit;
14493 unsigned int holes = limit; 14492 unsigned int holes = limit;
14494 // Assume most arrays contain no holes and undefined values, so minimize the 14493 // Assume most arrays contain no holes and undefined values, so minimize the
14495 // number of stores of non-undefined, non-the-hole values. 14494 // number of stores of non-undefined, non-the-hole values.
14496 for (unsigned int i = 0; i < undefs; i++) { 14495 for (unsigned int i = 0; i < undefs; i++) {
(...skipping 24 matching lines...) Expand all
14521 while (undefs < holes) { 14520 while (undefs < holes) {
14522 elements->set_undefined(undefs); 14521 elements->set_undefined(undefs);
14523 undefs++; 14522 undefs++;
14524 } 14523 }
14525 while (holes < limit) { 14524 while (holes < limit) {
14526 elements->set_the_hole(holes); 14525 elements->set_the_hole(holes);
14527 holes++; 14526 holes++;
14528 } 14527 }
14529 } 14528 }
14530 14529
14531 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { 14530 return isolate->factory()->NewNumberFromUint(result);
14532 return Smi::FromInt(static_cast<int>(result));
14533 }
14534 ASSERT_NE(NULL, result_double);
14535 result_double->set_value(static_cast<double>(result));
14536 return result_double;
14537 } 14531 }
14538 14532
14539 14533
14540 ExternalArrayType JSTypedArray::type() { 14534 ExternalArrayType JSTypedArray::type() {
14541 switch (elements()->map()->instance_type()) { 14535 switch (elements()->map()->instance_type()) {
14542 case EXTERNAL_BYTE_ARRAY_TYPE: 14536 case EXTERNAL_BYTE_ARRAY_TYPE:
14543 return kExternalByteArray; 14537 return kExternalByteArray;
14544 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 14538 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
14545 return kExternalUnsignedByteArray; 14539 return kExternalUnsignedByteArray;
14546 case EXTERNAL_SHORT_ARRAY_TYPE: 14540 case EXTERNAL_SHORT_ARRAY_TYPE:
(...skipping 1851 matching lines...) Expand 10 before | Expand all | Expand 10 after
16398 #define ERROR_MESSAGES_TEXTS(C, T) T, 16392 #define ERROR_MESSAGES_TEXTS(C, T) T,
16399 static const char* error_messages_[] = { 16393 static const char* error_messages_[] = {
16400 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16394 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16401 }; 16395 };
16402 #undef ERROR_MESSAGES_TEXTS 16396 #undef ERROR_MESSAGES_TEXTS
16403 return error_messages_[reason]; 16397 return error_messages_[reason];
16404 } 16398 }
16405 16399
16406 16400
16407 } } // namespace v8::internal 16401 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698