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