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

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: Created 7 years, 2 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') | 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<Object> JSObject::EnsureWritableFastElements(Handle<JSObject> object) {
Michael Starzinger 2013/10/25 08:11:44 IIUC the return type of this function can be narro
rafaelw 2013/10/25 20:23:47 Done.
347 CALL_HEAP_FUNCTION(object->GetIsolate(),
348 object->EnsureWritableFastElements(),
349 Object);
350 }
351
352
346 Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object, 353 Handle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object,
347 Handle<Object> receiver, 354 Handle<Object> receiver,
348 Handle<Object> structure, 355 Handle<Object> structure,
349 Handle<Name> name) { 356 Handle<Name> name) {
350 Isolate* isolate = name->GetIsolate(); 357 Isolate* isolate = name->GetIsolate();
351 // To accommodate both the old and the new api we switch on the 358 // To accommodate both the old and the new api we switch on the
352 // data structure used to store the callbacks. Eventually foreign 359 // data structure used to store the callbacks. Eventually foreign
353 // callbacks should be phased out. 360 // callbacks should be phased out.
354 if (structure->IsForeign()) { 361 if (structure->IsForeign()) {
355 AccessorDescriptor* callback = 362 AccessorDescriptor* callback =
(...skipping 13912 matching lines...) Expand 10 before | Expand all | Expand 10 after
14268 template 14275 template
14269 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements(); 14276 int Dictionary<SeededNumberDictionaryShape, uint32_t>::NumberOfEnumElements();
14270 14277
14271 template 14278 template
14272 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements(); 14279 int Dictionary<NameDictionaryShape, Name*>::NumberOfEnumElements();
14273 14280
14274 template 14281 template
14275 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t); 14282 int HashTable<SeededNumberDictionaryShape, uint32_t>::FindEntry(uint32_t);
14276 14283
14277 14284
14285 Handle<Object> JSObject::PrepareSlowElementsForSort(
14286 Handle<JSObject> object, uint32_t limit) {
14287 CALL_HEAP_FUNCTION(object->GetIsolate(),
14288 object->PrepareSlowElementsForSort(limit),
14289 Object);
14290 }
14291
14292
14278 // Collates undefined and unexisting elements below limit from position 14293 // Collates undefined and unexisting elements below limit from position
14279 // zero of the elements. The object stays in Dictionary mode. 14294 // zero of the elements. The object stays in Dictionary mode.
14280 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { 14295 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) {
14281 ASSERT(HasDictionaryElements()); 14296 ASSERT(HasDictionaryElements());
14282 // Must stay in dictionary mode, either because of requires_slow_elements, 14297 // Must stay in dictionary mode, either because of requires_slow_elements,
14283 // or because we are not going to sort (and therefore compact) all of the 14298 // or because we are not going to sort (and therefore compact) all of the
14284 // elements. 14299 // elements.
14285 SeededNumberDictionary* dict = element_dictionary(); 14300 SeededNumberDictionary* dict = element_dictionary();
14286 HeapNumber* result_double = NULL; 14301 HeapNumber* result_double = NULL;
14287 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { 14302 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
14370 ASSERT_NE(NULL, result_double); 14385 ASSERT_NE(NULL, result_double);
14371 result_double->set_value(static_cast<double>(result)); 14386 result_double->set_value(static_cast<double>(result));
14372 return result_double; 14387 return result_double;
14373 } 14388 }
14374 14389
14375 14390
14376 // Collects all defined (non-hole) and non-undefined (array) elements at 14391 // Collects all defined (non-hole) and non-undefined (array) elements at
14377 // the start of the elements array. 14392 // the start of the elements array.
14378 // If the object is in dictionary mode, it is converted to fast elements 14393 // If the object is in dictionary mode, it is converted to fast elements
14379 // mode. 14394 // mode.
14380 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { 14395 Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
14381 Heap* heap = GetHeap(); 14396 uint32_t limit) {
14397 Isolate* isolate = object->GetIsolate();
14382 14398
14383 ASSERT(!map()->is_observed()); 14399 ASSERT(!object->map()->is_observed());
14384 if (HasDictionaryElements()) { 14400 if (object->HasDictionaryElements()) {
14385 // Convert to fast elements containing only the existing properties. 14401 // Convert to fast elements containing only the existing properties.
14386 // Ordering is irrelevant, since we are going to sort anyway. 14402 // Ordering is irrelevant, since we are going to sort anyway.
14387 SeededNumberDictionary* dict = element_dictionary(); 14403 Handle<SeededNumberDictionary> dict = handle(object->element_dictionary());
Michael Starzinger 2013/10/25 08:11:44 nit: Let's use the constructor syntax here instead
rafaelw 2013/10/25 20:23:47 Done.
14388 if (IsJSArray() || dict->requires_slow_elements() || 14404 if (object->IsJSArray() || dict->requires_slow_elements() ||
14389 dict->max_number_key() >= limit) { 14405 dict->max_number_key() >= limit) {
14390 return PrepareSlowElementsForSort(limit); 14406 return JSObject::PrepareSlowElementsForSort(object, limit);
14391 } 14407 }
14392 // Convert to fast elements. 14408 // Convert to fast elements.
14393 14409
14394 Object* obj; 14410 Handle<Map> new_map =
14395 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(), 14411 JSObject::GetElementsTransitionMap(object, FAST_HOLEY_ELEMENTS);
14396 FAST_HOLEY_ELEMENTS);
14397 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
14398 Map* new_map = Map::cast(obj);
14399 14412
14400 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED; 14413 PretenureFlag tenure = object->GetHeap()->InNewSpace(*object) ?
Michael Starzinger 2013/10/25 08:11:44 nit: Using isolate->heap() here is cheaper and cle
rafaelw 2013/10/25 20:23:47 Done.
14401 Object* new_array; 14414 NOT_TENURED: TENURED;
14402 { MaybeObject* maybe_new_array = 14415 Handle<FixedArray> fast_elements =
14403 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); 14416 isolate->factory()->NewFixedArray(dict->NumberOfElements(), tenure);
14404 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; 14417 dict->CopyValuesTo(*fast_elements);
14405 } 14418 object->ValidateElements();
14406 FixedArray* fast_elements = FixedArray::cast(new_array);
14407 dict->CopyValuesTo(fast_elements);
14408 ValidateElements();
14409 14419
14410 set_map_and_elements(new_map, fast_elements); 14420 object->set_map_and_elements(*new_map, *fast_elements);
14411 } else if (HasExternalArrayElements()) { 14421 } else if (object->HasExternalArrayElements()) {
14412 // External arrays cannot have holes or undefined elements. 14422 // External arrays cannot have holes or undefined elements.
14413 return Smi::FromInt(ExternalArray::cast(elements())->length()); 14423 return handle(Smi::FromInt(
14414 } else if (!HasFastDoubleElements()) { 14424 ExternalArray::cast(object->elements())->length()), isolate);
14415 Object* obj; 14425 } else if (!object->HasFastDoubleElements()) {
14416 { MaybeObject* maybe_obj = EnsureWritableFastElements(); 14426 JSObject::EnsureWritableFastElements(object);
14417 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
14418 }
14419 } 14427 }
14420 ASSERT(HasFastSmiOrObjectElements() || HasFastDoubleElements()); 14428 ASSERT(object->HasFastSmiOrObjectElements() ||
14429 object->HasFastDoubleElements());
14421 14430
14422 // Collect holes at the end, undefined before that and the rest at the 14431 // Collect holes at the end, undefined before that and the rest at the
14423 // start, and return the number of non-hole, non-undefined values. 14432 // start, and return the number of non-hole, non-undefined values.
14424 14433
14425 FixedArrayBase* elements_base = FixedArrayBase::cast(this->elements()); 14434 Handle<FixedArrayBase> elements_base(object->elements());
14426 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); 14435 uint32_t elements_length = static_cast<uint32_t>(elements_base->length());
14427 if (limit > elements_length) { 14436 if (limit > elements_length) {
14428 limit = elements_length ; 14437 limit = elements_length ;
14429 } 14438 }
14430 if (limit == 0) { 14439 if (limit == 0) {
14431 return Smi::FromInt(0); 14440 return handle(Smi::FromInt(0), isolate);
14432 }
14433
14434 HeapNumber* result_double = NULL;
14435 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) {
14436 // Pessimistically allocate space for return value before
14437 // we start mutating the array.
14438 Object* new_double;
14439 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0);
14440 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double;
14441 }
14442 result_double = HeapNumber::cast(new_double);
14443 } 14441 }
14444 14442
14445 uint32_t result = 0; 14443 uint32_t result = 0;
14446 if (elements_base->map() == heap->fixed_double_array_map()) { 14444 if (elements_base->map() == object->GetHeap()->fixed_double_array_map()) {
Michael Starzinger 2013/10/25 08:11:44 nit: Using isolate->heap() here is cheaper and cle
rafaelw 2013/10/25 20:23:47 Done.
14447 FixedDoubleArray* elements = FixedDoubleArray::cast(elements_base); 14445 FixedDoubleArray* elements = FixedDoubleArray::cast(*elements_base);
14448 // Split elements into defined and the_hole, in that order. 14446 // Split elements into defined and the_hole, in that order.
14449 unsigned int holes = limit; 14447 unsigned int holes = limit;
14450 // Assume most arrays contain no holes and undefined values, so minimize the 14448 // Assume most arrays contain no holes and undefined values, so minimize the
14451 // number of stores of non-undefined, non-the-hole values. 14449 // number of stores of non-undefined, non-the-hole values.
14452 for (unsigned int i = 0; i < holes; i++) { 14450 for (unsigned int i = 0; i < holes; i++) {
14453 if (elements->is_the_hole(i)) { 14451 if (elements->is_the_hole(i)) {
14454 holes--; 14452 holes--;
14455 } else { 14453 } else {
14456 continue; 14454 continue;
14457 } 14455 }
14458 // Position i needs to be filled. 14456 // Position i needs to be filled.
14459 while (holes > i) { 14457 while (holes > i) {
14460 if (elements->is_the_hole(holes)) { 14458 if (elements->is_the_hole(holes)) {
14461 holes--; 14459 holes--;
14462 } else { 14460 } else {
14463 elements->set(i, elements->get_scalar(holes)); 14461 elements->set(i, elements->get_scalar(holes));
14464 break; 14462 break;
14465 } 14463 }
14466 } 14464 }
14467 } 14465 }
14468 result = holes; 14466 result = holes;
14469 while (holes < limit) { 14467 while (holes < limit) {
14470 elements->set_the_hole(holes); 14468 elements->set_the_hole(holes);
14471 holes++; 14469 holes++;
14472 } 14470 }
14473 } else { 14471 } else {
14474 FixedArray* elements = FixedArray::cast(elements_base); 14472 FixedArray* elements = FixedArray::cast(*elements_base);
14475 DisallowHeapAllocation no_gc; 14473 DisallowHeapAllocation no_gc;
14476 14474
14477 // Split elements into defined, undefined and the_hole, in that order. Only 14475 // Split elements into defined, undefined and the_hole, in that order. Only
14478 // count locations for undefined and the hole, and fill them afterwards. 14476 // count locations for undefined and the hole, and fill them afterwards.
14479 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc); 14477 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_gc);
14480 unsigned int undefs = limit; 14478 unsigned int undefs = limit;
14481 unsigned int holes = limit; 14479 unsigned int holes = limit;
14482 // Assume most arrays contain no holes and undefined values, so minimize the 14480 // Assume most arrays contain no holes and undefined values, so minimize the
14483 // number of stores of non-undefined, non-the-hole values. 14481 // number of stores of non-undefined, non-the-hole values.
14484 for (unsigned int i = 0; i < undefs; i++) { 14482 for (unsigned int i = 0; i < undefs; i++) {
(...skipping 24 matching lines...) Expand all
14509 while (undefs < holes) { 14507 while (undefs < holes) {
14510 elements->set_undefined(undefs); 14508 elements->set_undefined(undefs);
14511 undefs++; 14509 undefs++;
14512 } 14510 }
14513 while (holes < limit) { 14511 while (holes < limit) {
14514 elements->set_the_hole(holes); 14512 elements->set_the_hole(holes);
14515 holes++; 14513 holes++;
14516 } 14514 }
14517 } 14515 }
14518 14516
14519 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { 14517 return isolate->factory()->NewNumberFromUint(result);
14520 return Smi::FromInt(static_cast<int>(result));
14521 }
14522 ASSERT_NE(NULL, result_double);
14523 result_double->set_value(static_cast<double>(result));
14524 return result_double;
14525 } 14518 }
14526 14519
14527 14520
14528 ExternalArrayType JSTypedArray::type() { 14521 ExternalArrayType JSTypedArray::type() {
14529 switch (elements()->map()->instance_type()) { 14522 switch (elements()->map()->instance_type()) {
14530 case EXTERNAL_BYTE_ARRAY_TYPE: 14523 case EXTERNAL_BYTE_ARRAY_TYPE:
14531 return kExternalByteArray; 14524 return kExternalByteArray;
14532 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: 14525 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
14533 return kExternalUnsignedByteArray; 14526 return kExternalUnsignedByteArray;
14534 case EXTERNAL_SHORT_ARRAY_TYPE: 14527 case EXTERNAL_SHORT_ARRAY_TYPE:
(...skipping 1851 matching lines...) Expand 10 before | Expand all | Expand 10 after
16386 #define ERROR_MESSAGES_TEXTS(C, T) T, 16379 #define ERROR_MESSAGES_TEXTS(C, T) T,
16387 static const char* error_messages_[] = { 16380 static const char* error_messages_[] = {
16388 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16381 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16389 }; 16382 };
16390 #undef ERROR_MESSAGES_TEXTS 16383 #undef ERROR_MESSAGES_TEXTS
16391 return error_messages_[reason]; 16384 return error_messages_[reason];
16392 } 16385 }
16393 16386
16394 16387
16395 } } // namespace v8::internal 16388 } } // 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