OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |