OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
117 holder = native_context->string_function()->instance_prototype(); | 117 holder = native_context->string_function()->instance_prototype(); |
118 } else if (IsSymbol()) { | 118 } else if (IsSymbol()) { |
119 holder = native_context->symbol_function()->instance_prototype(); | 119 holder = native_context->symbol_function()->instance_prototype(); |
120 } else if (IsBoolean()) { | 120 } else if (IsBoolean()) { |
121 holder = native_context->boolean_function()->instance_prototype(); | 121 holder = native_context->boolean_function()->instance_prototype(); |
122 } else { | 122 } else { |
123 result->isolate()->PushStackTraceAndDie( | 123 result->isolate()->PushStackTraceAndDie( |
124 0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001); | 124 0xDEAD0000, this, JSReceiver::cast(this)->map(), 0xDEAD0001); |
125 } | 125 } |
126 } | 126 } |
127 ASSERT(holder != NULL); // Cannot handle null or undefined. | 127 DCHECK(holder != NULL); // Cannot handle null or undefined. |
128 JSReceiver::cast(holder)->Lookup(name, result); | 128 JSReceiver::cast(holder)->Lookup(name, result); |
129 } | 129 } |
130 | 130 |
131 | 131 |
132 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { | 132 MaybeHandle<Object> Object::GetProperty(LookupIterator* it) { |
133 for (; it->IsFound(); it->Next()) { | 133 for (; it->IsFound(); it->Next()) { |
134 switch (it->state()) { | 134 switch (it->state()) { |
135 case LookupIterator::NOT_FOUND: | 135 case LookupIterator::NOT_FOUND: |
136 UNREACHABLE(); | 136 UNREACHABLE(); |
137 case LookupIterator::JSPROXY: | 137 case LookupIterator::JSPROXY: |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 if (type == this) return true; | 221 if (type == this) return true; |
222 } | 222 } |
223 // Didn't find the required type in the inheritance chain. | 223 // Didn't find the required type in the inheritance chain. |
224 return false; | 224 return false; |
225 } | 225 } |
226 | 226 |
227 | 227 |
228 template<typename To> | 228 template<typename To> |
229 static inline To* CheckedCast(void *from) { | 229 static inline To* CheckedCast(void *from) { |
230 uintptr_t temp = reinterpret_cast<uintptr_t>(from); | 230 uintptr_t temp = reinterpret_cast<uintptr_t>(from); |
231 ASSERT(temp % sizeof(To) == 0); | 231 DCHECK(temp % sizeof(To) == 0); |
232 return reinterpret_cast<To*>(temp); | 232 return reinterpret_cast<To*>(temp); |
233 } | 233 } |
234 | 234 |
235 | 235 |
236 static Handle<Object> PerformCompare(const BitmaskCompareDescriptor& descriptor, | 236 static Handle<Object> PerformCompare(const BitmaskCompareDescriptor& descriptor, |
237 char* ptr, | 237 char* ptr, |
238 Isolate* isolate) { | 238 Isolate* isolate) { |
239 uint32_t bitmask = descriptor.bitmask; | 239 uint32_t bitmask = descriptor.bitmask; |
240 uint32_t compare_value = descriptor.compare_value; | 240 uint32_t compare_value = descriptor.compare_value; |
241 uint32_t value; | 241 uint32_t value; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 Handle<Object> receiver, | 323 Handle<Object> receiver, |
324 Handle<DeclaredAccessorInfo> info, | 324 Handle<DeclaredAccessorInfo> info, |
325 Isolate* isolate) { | 325 Isolate* isolate) { |
326 DisallowHeapAllocation no_gc; | 326 DisallowHeapAllocation no_gc; |
327 char* current = reinterpret_cast<char*>(*receiver); | 327 char* current = reinterpret_cast<char*>(*receiver); |
328 DeclaredAccessorDescriptorIterator iterator(info->descriptor()); | 328 DeclaredAccessorDescriptorIterator iterator(info->descriptor()); |
329 while (true) { | 329 while (true) { |
330 const DeclaredAccessorDescriptorData* data = iterator.Next(); | 330 const DeclaredAccessorDescriptorData* data = iterator.Next(); |
331 switch (data->type) { | 331 switch (data->type) { |
332 case kDescriptorReturnObject: { | 332 case kDescriptorReturnObject: { |
333 ASSERT(iterator.Complete()); | 333 DCHECK(iterator.Complete()); |
334 current = *CheckedCast<char*>(current); | 334 current = *CheckedCast<char*>(current); |
335 return handle(*CheckedCast<Object*>(current), isolate); | 335 return handle(*CheckedCast<Object*>(current), isolate); |
336 } | 336 } |
337 case kDescriptorPointerDereference: | 337 case kDescriptorPointerDereference: |
338 ASSERT(!iterator.Complete()); | 338 DCHECK(!iterator.Complete()); |
339 current = *reinterpret_cast<char**>(current); | 339 current = *reinterpret_cast<char**>(current); |
340 break; | 340 break; |
341 case kDescriptorPointerShift: | 341 case kDescriptorPointerShift: |
342 ASSERT(!iterator.Complete()); | 342 DCHECK(!iterator.Complete()); |
343 current += data->pointer_shift_descriptor.byte_offset; | 343 current += data->pointer_shift_descriptor.byte_offset; |
344 break; | 344 break; |
345 case kDescriptorObjectDereference: { | 345 case kDescriptorObjectDereference: { |
346 ASSERT(!iterator.Complete()); | 346 DCHECK(!iterator.Complete()); |
347 Object* object = CheckedCast<Object>(current); | 347 Object* object = CheckedCast<Object>(current); |
348 int field = data->object_dereference_descriptor.internal_field; | 348 int field = data->object_dereference_descriptor.internal_field; |
349 Object* smi = JSObject::cast(object)->GetInternalField(field); | 349 Object* smi = JSObject::cast(object)->GetInternalField(field); |
350 ASSERT(smi->IsSmi()); | 350 DCHECK(smi->IsSmi()); |
351 current = reinterpret_cast<char*>(smi); | 351 current = reinterpret_cast<char*>(smi); |
352 break; | 352 break; |
353 } | 353 } |
354 case kDescriptorBitmaskCompare: | 354 case kDescriptorBitmaskCompare: |
355 ASSERT(iterator.Complete()); | 355 DCHECK(iterator.Complete()); |
356 return PerformCompare(data->bitmask_compare_descriptor, | 356 return PerformCompare(data->bitmask_compare_descriptor, |
357 current, | 357 current, |
358 isolate); | 358 isolate); |
359 case kDescriptorPointerCompare: | 359 case kDescriptorPointerCompare: |
360 ASSERT(iterator.Complete()); | 360 DCHECK(iterator.Complete()); |
361 return PerformCompare(data->pointer_compare_descriptor, | 361 return PerformCompare(data->pointer_compare_descriptor, |
362 current, | 362 current, |
363 isolate); | 363 isolate); |
364 case kDescriptorPrimitiveValue: | 364 case kDescriptorPrimitiveValue: |
365 ASSERT(iterator.Complete()); | 365 DCHECK(iterator.Complete()); |
366 return GetPrimitiveValue(data->primitive_value_descriptor, | 366 return GetPrimitiveValue(data->primitive_value_descriptor, |
367 current, | 367 current, |
368 isolate); | 368 isolate); |
369 } | 369 } |
370 } | 370 } |
371 UNREACHABLE(); | 371 UNREACHABLE(); |
372 return isolate->factory()->undefined_value(); | 372 return isolate->factory()->undefined_value(); |
373 } | 373 } |
374 | 374 |
375 | 375 |
376 Handle<FixedArray> JSObject::EnsureWritableFastElements( | 376 Handle<FixedArray> JSObject::EnsureWritableFastElements( |
377 Handle<JSObject> object) { | 377 Handle<JSObject> object) { |
378 ASSERT(object->HasFastSmiOrObjectElements()); | 378 DCHECK(object->HasFastSmiOrObjectElements()); |
379 Isolate* isolate = object->GetIsolate(); | 379 Isolate* isolate = object->GetIsolate(); |
380 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); | 380 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); |
381 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; | 381 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
382 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( | 382 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( |
383 elems, isolate->factory()->fixed_array_map()); | 383 elems, isolate->factory()->fixed_array_map()); |
384 object->set_elements(*writable_elems); | 384 object->set_elements(*writable_elems); |
385 isolate->counters()->cow_arrays_converted()->Increment(); | 385 isolate->counters()->cow_arrays_converted()->Increment(); |
386 return writable_elems; | 386 return writable_elems; |
387 } | 387 } |
388 | 388 |
(...skipping 10 matching lines...) Expand all Loading... |
399 return CallTrap( | 399 return CallTrap( |
400 proxy, "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); | 400 proxy, "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); |
401 } | 401 } |
402 | 402 |
403 | 403 |
404 MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver, | 404 MaybeHandle<Object> Object::GetPropertyWithAccessor(Handle<Object> receiver, |
405 Handle<Name> name, | 405 Handle<Name> name, |
406 Handle<JSObject> holder, | 406 Handle<JSObject> holder, |
407 Handle<Object> structure) { | 407 Handle<Object> structure) { |
408 Isolate* isolate = name->GetIsolate(); | 408 Isolate* isolate = name->GetIsolate(); |
409 ASSERT(!structure->IsForeign()); | 409 DCHECK(!structure->IsForeign()); |
410 // api style callbacks. | 410 // api style callbacks. |
411 if (structure->IsAccessorInfo()) { | 411 if (structure->IsAccessorInfo()) { |
412 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure); | 412 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(structure); |
413 if (!info->IsCompatibleReceiver(*receiver)) { | 413 if (!info->IsCompatibleReceiver(*receiver)) { |
414 Handle<Object> args[2] = { name, receiver }; | 414 Handle<Object> args[2] = { name, receiver }; |
415 Handle<Object> error = | 415 Handle<Object> error = |
416 isolate->factory()->NewTypeError("incompatible_method_receiver", | 416 isolate->factory()->NewTypeError("incompatible_method_receiver", |
417 HandleVector(args, | 417 HandleVector(args, |
418 ARRAY_SIZE(args))); | 418 ARRAY_SIZE(args))); |
419 return isolate->Throw<Object>(error); | 419 return isolate->Throw<Object>(error); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 } | 473 } |
474 | 474 |
475 | 475 |
476 MaybeHandle<Object> Object::SetPropertyWithAccessor( | 476 MaybeHandle<Object> Object::SetPropertyWithAccessor( |
477 Handle<Object> receiver, Handle<Name> name, Handle<Object> value, | 477 Handle<Object> receiver, Handle<Name> name, Handle<Object> value, |
478 Handle<JSObject> holder, Handle<Object> structure, StrictMode strict_mode) { | 478 Handle<JSObject> holder, Handle<Object> structure, StrictMode strict_mode) { |
479 Isolate* isolate = name->GetIsolate(); | 479 Isolate* isolate = name->GetIsolate(); |
480 | 480 |
481 // We should never get here to initialize a const with the hole | 481 // We should never get here to initialize a const with the hole |
482 // value since a const declaration would conflict with the setter. | 482 // value since a const declaration would conflict with the setter. |
483 ASSERT(!structure->IsForeign()); | 483 DCHECK(!structure->IsForeign()); |
484 if (structure->IsExecutableAccessorInfo()) { | 484 if (structure->IsExecutableAccessorInfo()) { |
485 // Don't call executable accessor setters with non-JSObject receivers. | 485 // Don't call executable accessor setters with non-JSObject receivers. |
486 if (!receiver->IsJSObject()) return value; | 486 if (!receiver->IsJSObject()) return value; |
487 // api style callbacks | 487 // api style callbacks |
488 ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure); | 488 ExecutableAccessorInfo* info = ExecutableAccessorInfo::cast(*structure); |
489 if (!info->IsCompatibleReceiver(*receiver)) { | 489 if (!info->IsCompatibleReceiver(*receiver)) { |
490 Handle<Object> args[2] = { name, receiver }; | 490 Handle<Object> args[2] = { name, receiver }; |
491 Handle<Object> error = | 491 Handle<Object> error = |
492 isolate->factory()->NewTypeError("incompatible_method_receiver", | 492 isolate->factory()->NewTypeError("incompatible_method_receiver", |
493 HandleVector(args, | 493 HandleVector(args, |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 it->GetAccessors(), strict_mode); | 642 it->GetAccessors(), strict_mode); |
643 } | 643 } |
644 | 644 |
645 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_SET); | 645 it->isolate()->ReportFailedAccessCheck(checked, v8::ACCESS_SET); |
646 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); | 646 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(it->isolate(), Object); |
647 return value; | 647 return value; |
648 } | 648 } |
649 | 649 |
650 | 650 |
651 Object* JSObject::GetNormalizedProperty(const LookupResult* result) { | 651 Object* JSObject::GetNormalizedProperty(const LookupResult* result) { |
652 ASSERT(!HasFastProperties()); | 652 DCHECK(!HasFastProperties()); |
653 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 653 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
654 if (IsGlobalObject()) { | 654 if (IsGlobalObject()) { |
655 value = PropertyCell::cast(value)->value(); | 655 value = PropertyCell::cast(value)->value(); |
656 } | 656 } |
657 ASSERT(!value->IsPropertyCell() && !value->IsCell()); | 657 DCHECK(!value->IsPropertyCell() && !value->IsCell()); |
658 return value; | 658 return value; |
659 } | 659 } |
660 | 660 |
661 | 661 |
662 Handle<Object> JSObject::GetNormalizedProperty(Handle<JSObject> object, | 662 Handle<Object> JSObject::GetNormalizedProperty(Handle<JSObject> object, |
663 const LookupResult* result) { | 663 const LookupResult* result) { |
664 ASSERT(!object->HasFastProperties()); | 664 DCHECK(!object->HasFastProperties()); |
665 Isolate* isolate = object->GetIsolate(); | 665 Isolate* isolate = object->GetIsolate(); |
666 Handle<Object> value(object->property_dictionary()->ValueAt( | 666 Handle<Object> value(object->property_dictionary()->ValueAt( |
667 result->GetDictionaryEntry()), isolate); | 667 result->GetDictionaryEntry()), isolate); |
668 if (object->IsGlobalObject()) { | 668 if (object->IsGlobalObject()) { |
669 value = handle(Handle<PropertyCell>::cast(value)->value(), isolate); | 669 value = handle(Handle<PropertyCell>::cast(value)->value(), isolate); |
670 ASSERT(!value->IsTheHole()); | 670 DCHECK(!value->IsTheHole()); |
671 } | 671 } |
672 ASSERT(!value->IsPropertyCell() && !value->IsCell()); | 672 DCHECK(!value->IsPropertyCell() && !value->IsCell()); |
673 return value; | 673 return value; |
674 } | 674 } |
675 | 675 |
676 | 676 |
677 void JSObject::SetNormalizedProperty(Handle<JSObject> object, | 677 void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
678 const LookupResult* result, | 678 const LookupResult* result, |
679 Handle<Object> value) { | 679 Handle<Object> value) { |
680 ASSERT(!object->HasFastProperties()); | 680 DCHECK(!object->HasFastProperties()); |
681 NameDictionary* property_dictionary = object->property_dictionary(); | 681 NameDictionary* property_dictionary = object->property_dictionary(); |
682 if (object->IsGlobalObject()) { | 682 if (object->IsGlobalObject()) { |
683 Handle<PropertyCell> cell(PropertyCell::cast( | 683 Handle<PropertyCell> cell(PropertyCell::cast( |
684 property_dictionary->ValueAt(result->GetDictionaryEntry()))); | 684 property_dictionary->ValueAt(result->GetDictionaryEntry()))); |
685 PropertyCell::SetValueInferType(cell, value); | 685 PropertyCell::SetValueInferType(cell, value); |
686 } else { | 686 } else { |
687 property_dictionary->ValueAtPut(result->GetDictionaryEntry(), *value); | 687 property_dictionary->ValueAtPut(result->GetDictionaryEntry(), *value); |
688 } | 688 } |
689 } | 689 } |
690 | 690 |
691 | 691 |
692 void JSObject::SetNormalizedProperty(Handle<JSObject> object, | 692 void JSObject::SetNormalizedProperty(Handle<JSObject> object, |
693 Handle<Name> name, | 693 Handle<Name> name, |
694 Handle<Object> value, | 694 Handle<Object> value, |
695 PropertyDetails details) { | 695 PropertyDetails details) { |
696 ASSERT(!object->HasFastProperties()); | 696 DCHECK(!object->HasFastProperties()); |
697 Handle<NameDictionary> property_dictionary(object->property_dictionary()); | 697 Handle<NameDictionary> property_dictionary(object->property_dictionary()); |
698 | 698 |
699 if (!name->IsUniqueName()) { | 699 if (!name->IsUniqueName()) { |
700 name = object->GetIsolate()->factory()->InternalizeString( | 700 name = object->GetIsolate()->factory()->InternalizeString( |
701 Handle<String>::cast(name)); | 701 Handle<String>::cast(name)); |
702 } | 702 } |
703 | 703 |
704 int entry = property_dictionary->FindEntry(name); | 704 int entry = property_dictionary->FindEntry(name); |
705 if (entry == NameDictionary::kNotFound) { | 705 if (entry == NameDictionary::kNotFound) { |
706 Handle<Object> store_value = value; | 706 Handle<Object> store_value = value; |
707 if (object->IsGlobalObject()) { | 707 if (object->IsGlobalObject()) { |
708 store_value = object->GetIsolate()->factory()->NewPropertyCell(value); | 708 store_value = object->GetIsolate()->factory()->NewPropertyCell(value); |
709 } | 709 } |
710 | 710 |
711 property_dictionary = NameDictionary::Add( | 711 property_dictionary = NameDictionary::Add( |
712 property_dictionary, name, store_value, details); | 712 property_dictionary, name, store_value, details); |
713 object->set_properties(*property_dictionary); | 713 object->set_properties(*property_dictionary); |
714 return; | 714 return; |
715 } | 715 } |
716 | 716 |
717 PropertyDetails original_details = property_dictionary->DetailsAt(entry); | 717 PropertyDetails original_details = property_dictionary->DetailsAt(entry); |
718 int enumeration_index; | 718 int enumeration_index; |
719 // Preserve the enumeration index unless the property was deleted. | 719 // Preserve the enumeration index unless the property was deleted. |
720 if (original_details.IsDeleted()) { | 720 if (original_details.IsDeleted()) { |
721 enumeration_index = property_dictionary->NextEnumerationIndex(); | 721 enumeration_index = property_dictionary->NextEnumerationIndex(); |
722 property_dictionary->SetNextEnumerationIndex(enumeration_index + 1); | 722 property_dictionary->SetNextEnumerationIndex(enumeration_index + 1); |
723 } else { | 723 } else { |
724 enumeration_index = original_details.dictionary_index(); | 724 enumeration_index = original_details.dictionary_index(); |
725 ASSERT(enumeration_index > 0); | 725 DCHECK(enumeration_index > 0); |
726 } | 726 } |
727 | 727 |
728 details = PropertyDetails( | 728 details = PropertyDetails( |
729 details.attributes(), details.type(), enumeration_index); | 729 details.attributes(), details.type(), enumeration_index); |
730 | 730 |
731 if (object->IsGlobalObject()) { | 731 if (object->IsGlobalObject()) { |
732 Handle<PropertyCell> cell( | 732 Handle<PropertyCell> cell( |
733 PropertyCell::cast(property_dictionary->ValueAt(entry))); | 733 PropertyCell::cast(property_dictionary->ValueAt(entry))); |
734 PropertyCell::SetValueInferType(cell, value); | 734 PropertyCell::SetValueInferType(cell, value); |
735 // Please note we have to update the property details. | 735 // Please note we have to update the property details. |
736 property_dictionary->DetailsAtPut(entry, details); | 736 property_dictionary->DetailsAtPut(entry, details); |
737 } else { | 737 } else { |
738 property_dictionary->SetEntry(entry, name, value, details); | 738 property_dictionary->SetEntry(entry, name, value, details); |
739 } | 739 } |
740 } | 740 } |
741 | 741 |
742 | 742 |
743 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, | 743 Handle<Object> JSObject::DeleteNormalizedProperty(Handle<JSObject> object, |
744 Handle<Name> name, | 744 Handle<Name> name, |
745 DeleteMode mode) { | 745 DeleteMode mode) { |
746 ASSERT(!object->HasFastProperties()); | 746 DCHECK(!object->HasFastProperties()); |
747 Isolate* isolate = object->GetIsolate(); | 747 Isolate* isolate = object->GetIsolate(); |
748 Handle<NameDictionary> dictionary(object->property_dictionary()); | 748 Handle<NameDictionary> dictionary(object->property_dictionary()); |
749 int entry = dictionary->FindEntry(name); | 749 int entry = dictionary->FindEntry(name); |
750 if (entry != NameDictionary::kNotFound) { | 750 if (entry != NameDictionary::kNotFound) { |
751 // If we have a global object set the cell to the hole. | 751 // If we have a global object set the cell to the hole. |
752 if (object->IsGlobalObject()) { | 752 if (object->IsGlobalObject()) { |
753 PropertyDetails details = dictionary->DetailsAt(entry); | 753 PropertyDetails details = dictionary->DetailsAt(entry); |
754 if (details.IsDontDelete()) { | 754 if (details.IsDontDelete()) { |
755 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); | 755 if (mode != FORCE_DELETION) return isolate->factory()->false_value(); |
756 // When forced to delete global properties, we have to make a | 756 // When forced to delete global properties, we have to make a |
757 // map change to invalidate any ICs that think they can load | 757 // map change to invalidate any ICs that think they can load |
758 // from the DontDelete cell without checking if it contains | 758 // from the DontDelete cell without checking if it contains |
759 // the hole value. | 759 // the hole value. |
760 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 760 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
761 ASSERT(new_map->is_dictionary_map()); | 761 DCHECK(new_map->is_dictionary_map()); |
762 JSObject::MigrateToMap(object, new_map); | 762 JSObject::MigrateToMap(object, new_map); |
763 } | 763 } |
764 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); | 764 Handle<PropertyCell> cell(PropertyCell::cast(dictionary->ValueAt(entry))); |
765 Handle<Object> value = isolate->factory()->the_hole_value(); | 765 Handle<Object> value = isolate->factory()->the_hole_value(); |
766 PropertyCell::SetValueInferType(cell, value); | 766 PropertyCell::SetValueInferType(cell, value); |
767 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 767 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
768 } else { | 768 } else { |
769 Handle<Object> deleted( | 769 Handle<Object> deleted( |
770 NameDictionary::DeleteProperty(dictionary, entry, mode)); | 770 NameDictionary::DeleteProperty(dictionary, entry, mode)); |
771 if (*deleted == isolate->heap()->true_value()) { | 771 if (*deleted == isolate->heap()->true_value()) { |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
892 } | 892 } |
893 if (IsName()) { | 893 if (IsName()) { |
894 uint32_t hash = Name::cast(this)->Hash(); | 894 uint32_t hash = Name::cast(this)->Hash(); |
895 return Smi::FromInt(hash); | 895 return Smi::FromInt(hash); |
896 } | 896 } |
897 if (IsOddball()) { | 897 if (IsOddball()) { |
898 uint32_t hash = Oddball::cast(this)->to_string()->Hash(); | 898 uint32_t hash = Oddball::cast(this)->to_string()->Hash(); |
899 return Smi::FromInt(hash); | 899 return Smi::FromInt(hash); |
900 } | 900 } |
901 | 901 |
902 ASSERT(IsJSReceiver()); | 902 DCHECK(IsJSReceiver()); |
903 return JSReceiver::cast(this)->GetIdentityHash(); | 903 return JSReceiver::cast(this)->GetIdentityHash(); |
904 } | 904 } |
905 | 905 |
906 | 906 |
907 Handle<Smi> Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) { | 907 Handle<Smi> Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) { |
908 Handle<Object> hash(object->GetHash(), isolate); | 908 Handle<Object> hash(object->GetHash(), isolate); |
909 if (hash->IsSmi()) return Handle<Smi>::cast(hash); | 909 if (hash->IsSmi()) return Handle<Smi>::cast(hash); |
910 | 910 |
911 ASSERT(object->IsJSReceiver()); | 911 DCHECK(object->IsJSReceiver()); |
912 return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object)); | 912 return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object)); |
913 } | 913 } |
914 | 914 |
915 | 915 |
916 bool Object::SameValue(Object* other) { | 916 bool Object::SameValue(Object* other) { |
917 if (other == this) return true; | 917 if (other == this) return true; |
918 | 918 |
919 // The object is either a number, a name, an odd-ball, | 919 // The object is either a number, a name, an odd-ball, |
920 // a real JS object, or a Harmony proxy. | 920 // a real JS object, or a Harmony proxy. |
921 if (IsNumber() && other->IsNumber()) { | 921 if (IsNumber() && other->IsNumber()) { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 (c0 == 'F' || c0 == 'H' || c0 == 'M' || c0 == 'N' || c0 == 'R' || | 1002 (c0 == 'F' || c0 == 'H' || c0 == 'M' || c0 == 'N' || c0 == 'R' || |
1003 c0 == 'S' || c0 == 'X')) { | 1003 c0 == 'S' || c0 == 'X')) { |
1004 return true; // An MP3File, an M. | 1004 return true; // An MP3File, an M. |
1005 } | 1005 } |
1006 return false; | 1006 return false; |
1007 } | 1007 } |
1008 | 1008 |
1009 | 1009 |
1010 Handle<String> String::SlowFlatten(Handle<ConsString> cons, | 1010 Handle<String> String::SlowFlatten(Handle<ConsString> cons, |
1011 PretenureFlag pretenure) { | 1011 PretenureFlag pretenure) { |
1012 ASSERT(AllowHeapAllocation::IsAllowed()); | 1012 DCHECK(AllowHeapAllocation::IsAllowed()); |
1013 ASSERT(cons->second()->length() != 0); | 1013 DCHECK(cons->second()->length() != 0); |
1014 Isolate* isolate = cons->GetIsolate(); | 1014 Isolate* isolate = cons->GetIsolate(); |
1015 int length = cons->length(); | 1015 int length = cons->length(); |
1016 PretenureFlag tenure = isolate->heap()->InNewSpace(*cons) ? pretenure | 1016 PretenureFlag tenure = isolate->heap()->InNewSpace(*cons) ? pretenure |
1017 : TENURED; | 1017 : TENURED; |
1018 Handle<SeqString> result; | 1018 Handle<SeqString> result; |
1019 if (cons->IsOneByteRepresentation()) { | 1019 if (cons->IsOneByteRepresentation()) { |
1020 Handle<SeqOneByteString> flat = isolate->factory()->NewRawOneByteString( | 1020 Handle<SeqOneByteString> flat = isolate->factory()->NewRawOneByteString( |
1021 length, tenure).ToHandleChecked(); | 1021 length, tenure).ToHandleChecked(); |
1022 DisallowHeapAllocation no_gc; | 1022 DisallowHeapAllocation no_gc; |
1023 WriteToFlat(*cons, flat->GetChars(), 0, length); | 1023 WriteToFlat(*cons, flat->GetChars(), 0, length); |
1024 result = flat; | 1024 result = flat; |
1025 } else { | 1025 } else { |
1026 Handle<SeqTwoByteString> flat = isolate->factory()->NewRawTwoByteString( | 1026 Handle<SeqTwoByteString> flat = isolate->factory()->NewRawTwoByteString( |
1027 length, tenure).ToHandleChecked(); | 1027 length, tenure).ToHandleChecked(); |
1028 DisallowHeapAllocation no_gc; | 1028 DisallowHeapAllocation no_gc; |
1029 WriteToFlat(*cons, flat->GetChars(), 0, length); | 1029 WriteToFlat(*cons, flat->GetChars(), 0, length); |
1030 result = flat; | 1030 result = flat; |
1031 } | 1031 } |
1032 cons->set_first(*result); | 1032 cons->set_first(*result); |
1033 cons->set_second(isolate->heap()->empty_string()); | 1033 cons->set_second(isolate->heap()->empty_string()); |
1034 ASSERT(result->IsFlat()); | 1034 DCHECK(result->IsFlat()); |
1035 return result; | 1035 return result; |
1036 } | 1036 } |
1037 | 1037 |
1038 | 1038 |
1039 | 1039 |
1040 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { | 1040 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { |
1041 // Externalizing twice leaks the external resource, so it's | 1041 // Externalizing twice leaks the external resource, so it's |
1042 // prohibited by the API. | 1042 // prohibited by the API. |
1043 ASSERT(!this->IsExternalString()); | 1043 DCHECK(!this->IsExternalString()); |
1044 #ifdef ENABLE_SLOW_ASSERTS | 1044 #ifdef ENABLE_SLOW_DCHECKS |
1045 if (FLAG_enable_slow_asserts) { | 1045 if (FLAG_enable_slow_asserts) { |
1046 // Assert that the resource and the string are equivalent. | 1046 // Assert that the resource and the string are equivalent. |
1047 ASSERT(static_cast<size_t>(this->length()) == resource->length()); | 1047 DCHECK(static_cast<size_t>(this->length()) == resource->length()); |
1048 ScopedVector<uc16> smart_chars(this->length()); | 1048 ScopedVector<uc16> smart_chars(this->length()); |
1049 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 1049 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
1050 ASSERT(memcmp(smart_chars.start(), | 1050 DCHECK(memcmp(smart_chars.start(), |
1051 resource->data(), | 1051 resource->data(), |
1052 resource->length() * sizeof(smart_chars[0])) == 0); | 1052 resource->length() * sizeof(smart_chars[0])) == 0); |
1053 } | 1053 } |
1054 #endif // DEBUG | 1054 #endif // DEBUG |
1055 Heap* heap = GetHeap(); | 1055 Heap* heap = GetHeap(); |
1056 int size = this->Size(); // Byte size of the original string. | 1056 int size = this->Size(); // Byte size of the original string. |
1057 if (size < ExternalString::kShortSize) { | 1057 if (size < ExternalString::kShortSize) { |
1058 return false; | 1058 return false; |
1059 } | 1059 } |
1060 bool is_ascii = this->IsOneByteRepresentation(); | 1060 bool is_ascii = this->IsOneByteRepresentation(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); | 1102 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); |
1103 self->set_resource(resource); | 1103 self->set_resource(resource); |
1104 if (is_internalized) self->Hash(); // Force regeneration of the hash value. | 1104 if (is_internalized) self->Hash(); // Force regeneration of the hash value. |
1105 | 1105 |
1106 heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR); | 1106 heap->AdjustLiveBytes(this->address(), new_size - size, Heap::FROM_MUTATOR); |
1107 return true; | 1107 return true; |
1108 } | 1108 } |
1109 | 1109 |
1110 | 1110 |
1111 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { | 1111 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { |
1112 #ifdef ENABLE_SLOW_ASSERTS | 1112 #ifdef ENABLE_SLOW_DCHECKS |
1113 if (FLAG_enable_slow_asserts) { | 1113 if (FLAG_enable_slow_asserts) { |
1114 // Assert that the resource and the string are equivalent. | 1114 // Assert that the resource and the string are equivalent. |
1115 ASSERT(static_cast<size_t>(this->length()) == resource->length()); | 1115 DCHECK(static_cast<size_t>(this->length()) == resource->length()); |
1116 if (this->IsTwoByteRepresentation()) { | 1116 if (this->IsTwoByteRepresentation()) { |
1117 ScopedVector<uint16_t> smart_chars(this->length()); | 1117 ScopedVector<uint16_t> smart_chars(this->length()); |
1118 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 1118 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
1119 ASSERT(String::IsOneByte(smart_chars.start(), this->length())); | 1119 DCHECK(String::IsOneByte(smart_chars.start(), this->length())); |
1120 } | 1120 } |
1121 ScopedVector<char> smart_chars(this->length()); | 1121 ScopedVector<char> smart_chars(this->length()); |
1122 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 1122 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
1123 ASSERT(memcmp(smart_chars.start(), | 1123 DCHECK(memcmp(smart_chars.start(), |
1124 resource->data(), | 1124 resource->data(), |
1125 resource->length() * sizeof(smart_chars[0])) == 0); | 1125 resource->length() * sizeof(smart_chars[0])) == 0); |
1126 } | 1126 } |
1127 #endif // DEBUG | 1127 #endif // DEBUG |
1128 Heap* heap = GetHeap(); | 1128 Heap* heap = GetHeap(); |
1129 int size = this->Size(); // Byte size of the original string. | 1129 int size = this->Size(); // Byte size of the original string. |
1130 if (size < ExternalString::kShortSize) { | 1130 if (size < ExternalString::kShortSize) { |
1131 return false; | 1131 return false; |
1132 } | 1132 } |
1133 bool is_internalized = this->IsInternalizedString(); | 1133 bool is_internalized = this->IsInternalizedString(); |
(...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1769 return map()->constructor_name(); | 1769 return map()->constructor_name(); |
1770 } | 1770 } |
1771 | 1771 |
1772 | 1772 |
1773 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, | 1773 MaybeHandle<Map> Map::CopyWithField(Handle<Map> map, |
1774 Handle<Name> name, | 1774 Handle<Name> name, |
1775 Handle<HeapType> type, | 1775 Handle<HeapType> type, |
1776 PropertyAttributes attributes, | 1776 PropertyAttributes attributes, |
1777 Representation representation, | 1777 Representation representation, |
1778 TransitionFlag flag) { | 1778 TransitionFlag flag) { |
1779 ASSERT(DescriptorArray::kNotFound == | 1779 DCHECK(DescriptorArray::kNotFound == |
1780 map->instance_descriptors()->Search( | 1780 map->instance_descriptors()->Search( |
1781 *name, map->NumberOfOwnDescriptors())); | 1781 *name, map->NumberOfOwnDescriptors())); |
1782 | 1782 |
1783 // Ensure the descriptor array does not get too big. | 1783 // Ensure the descriptor array does not get too big. |
1784 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { | 1784 if (map->NumberOfOwnDescriptors() >= kMaxNumberOfDescriptors) { |
1785 return MaybeHandle<Map>(); | 1785 return MaybeHandle<Map>(); |
1786 } | 1786 } |
1787 | 1787 |
1788 Isolate* isolate = map->GetIsolate(); | 1788 Isolate* isolate = map->GetIsolate(); |
1789 | 1789 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1821 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); | 1821 return Map::CopyAddDescriptor(map, &new_constant_desc, flag); |
1822 } | 1822 } |
1823 | 1823 |
1824 | 1824 |
1825 void JSObject::AddFastProperty(Handle<JSObject> object, | 1825 void JSObject::AddFastProperty(Handle<JSObject> object, |
1826 Handle<Name> name, | 1826 Handle<Name> name, |
1827 Handle<Object> value, | 1827 Handle<Object> value, |
1828 PropertyAttributes attributes, | 1828 PropertyAttributes attributes, |
1829 StoreFromKeyed store_mode, | 1829 StoreFromKeyed store_mode, |
1830 TransitionFlag flag) { | 1830 TransitionFlag flag) { |
1831 ASSERT(!object->IsJSGlobalProxy()); | 1831 DCHECK(!object->IsJSGlobalProxy()); |
1832 | 1832 |
1833 MaybeHandle<Map> maybe_map; | 1833 MaybeHandle<Map> maybe_map; |
1834 if (value->IsJSFunction()) { | 1834 if (value->IsJSFunction()) { |
1835 maybe_map = Map::CopyWithConstant( | 1835 maybe_map = Map::CopyWithConstant( |
1836 handle(object->map()), name, value, attributes, flag); | 1836 handle(object->map()), name, value, attributes, flag); |
1837 } else if (!object->map()->TooManyFastProperties(store_mode)) { | 1837 } else if (!object->map()->TooManyFastProperties(store_mode)) { |
1838 Isolate* isolate = object->GetIsolate(); | 1838 Isolate* isolate = object->GetIsolate(); |
1839 Representation representation = value->OptimalRepresentation(); | 1839 Representation representation = value->OptimalRepresentation(); |
1840 maybe_map = Map::CopyWithField( | 1840 maybe_map = Map::CopyWithField( |
1841 handle(object->map(), isolate), name, | 1841 handle(object->map(), isolate), name, |
1842 value->OptimalType(isolate, representation), | 1842 value->OptimalType(isolate, representation), |
1843 attributes, representation, flag); | 1843 attributes, representation, flag); |
1844 } | 1844 } |
1845 | 1845 |
1846 Handle<Map> new_map; | 1846 Handle<Map> new_map; |
1847 if (!maybe_map.ToHandle(&new_map)) { | 1847 if (!maybe_map.ToHandle(&new_map)) { |
1848 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 1848 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
1849 return; | 1849 return; |
1850 } | 1850 } |
1851 | 1851 |
1852 JSObject::MigrateToNewProperty(object, new_map, value); | 1852 JSObject::MigrateToNewProperty(object, new_map, value); |
1853 } | 1853 } |
1854 | 1854 |
1855 | 1855 |
1856 void JSObject::AddSlowProperty(Handle<JSObject> object, | 1856 void JSObject::AddSlowProperty(Handle<JSObject> object, |
1857 Handle<Name> name, | 1857 Handle<Name> name, |
1858 Handle<Object> value, | 1858 Handle<Object> value, |
1859 PropertyAttributes attributes) { | 1859 PropertyAttributes attributes) { |
1860 ASSERT(!object->HasFastProperties()); | 1860 DCHECK(!object->HasFastProperties()); |
1861 Isolate* isolate = object->GetIsolate(); | 1861 Isolate* isolate = object->GetIsolate(); |
1862 Handle<NameDictionary> dict(object->property_dictionary()); | 1862 Handle<NameDictionary> dict(object->property_dictionary()); |
1863 if (object->IsGlobalObject()) { | 1863 if (object->IsGlobalObject()) { |
1864 // In case name is an orphaned property reuse the cell. | 1864 // In case name is an orphaned property reuse the cell. |
1865 int entry = dict->FindEntry(name); | 1865 int entry = dict->FindEntry(name); |
1866 if (entry != NameDictionary::kNotFound) { | 1866 if (entry != NameDictionary::kNotFound) { |
1867 Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry))); | 1867 Handle<PropertyCell> cell(PropertyCell::cast(dict->ValueAt(entry))); |
1868 PropertyCell::SetValueInferType(cell, value); | 1868 PropertyCell::SetValueInferType(cell, value); |
1869 // Assign an enumeration index to the property and update | 1869 // Assign an enumeration index to the property and update |
1870 // SetNextEnumerationIndex. | 1870 // SetNextEnumerationIndex. |
(...skipping 11 matching lines...) Expand all Loading... |
1882 Handle<NameDictionary> result = | 1882 Handle<NameDictionary> result = |
1883 NameDictionary::Add(dict, name, value, details); | 1883 NameDictionary::Add(dict, name, value, details); |
1884 if (*dict != *result) object->set_properties(*result); | 1884 if (*dict != *result) object->set_properties(*result); |
1885 } | 1885 } |
1886 | 1886 |
1887 | 1887 |
1888 MaybeHandle<Object> JSObject::AddPropertyInternal( | 1888 MaybeHandle<Object> JSObject::AddPropertyInternal( |
1889 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, | 1889 Handle<JSObject> object, Handle<Name> name, Handle<Object> value, |
1890 PropertyAttributes attributes, JSReceiver::StoreFromKeyed store_mode, | 1890 PropertyAttributes attributes, JSReceiver::StoreFromKeyed store_mode, |
1891 ExtensibilityCheck extensibility_check, TransitionFlag transition_flag) { | 1891 ExtensibilityCheck extensibility_check, TransitionFlag transition_flag) { |
1892 ASSERT(!object->IsJSGlobalProxy()); | 1892 DCHECK(!object->IsJSGlobalProxy()); |
1893 Isolate* isolate = object->GetIsolate(); | 1893 Isolate* isolate = object->GetIsolate(); |
1894 | 1894 |
1895 if (!name->IsUniqueName()) { | 1895 if (!name->IsUniqueName()) { |
1896 name = isolate->factory()->InternalizeString( | 1896 name = isolate->factory()->InternalizeString( |
1897 Handle<String>::cast(name)); | 1897 Handle<String>::cast(name)); |
1898 } | 1898 } |
1899 | 1899 |
1900 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 1900 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
1901 !object->map()->is_extensible()) { | 1901 !object->map()->is_extensible()) { |
1902 Handle<Object> args[1] = {name}; | 1902 Handle<Object> args[1] = {name}; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1936 } | 1936 } |
1937 | 1937 |
1938 return function->context()->native_context(); | 1938 return function->context()->native_context(); |
1939 } | 1939 } |
1940 | 1940 |
1941 | 1941 |
1942 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, | 1942 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, |
1943 const char* type_str, | 1943 const char* type_str, |
1944 Handle<Name> name, | 1944 Handle<Name> name, |
1945 Handle<Object> old_value) { | 1945 Handle<Object> old_value) { |
1946 ASSERT(!object->IsJSGlobalProxy()); | 1946 DCHECK(!object->IsJSGlobalProxy()); |
1947 ASSERT(!object->IsJSGlobalObject()); | 1947 DCHECK(!object->IsJSGlobalObject()); |
1948 Isolate* isolate = object->GetIsolate(); | 1948 Isolate* isolate = object->GetIsolate(); |
1949 HandleScope scope(isolate); | 1949 HandleScope scope(isolate); |
1950 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); | 1950 Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); |
1951 Handle<Object> args[] = { type, object, name, old_value }; | 1951 Handle<Object> args[] = { type, object, name, old_value }; |
1952 int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4; | 1952 int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4; |
1953 | 1953 |
1954 Execution::Call(isolate, | 1954 Execution::Call(isolate, |
1955 Handle<JSFunction>(isolate->observers_notify_change()), | 1955 Handle<JSFunction>(isolate->observers_notify_change()), |
1956 isolate->factory()->undefined_value(), | 1956 isolate->factory()->undefined_value(), |
1957 argc, args).Assert(); | 1957 argc, args).Assert(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1996 Object** zap = reinterpret_cast<Object**>(new_end); | 1996 Object** zap = reinterpret_cast<Object**>(new_end); |
1997 zap++; // Header of filler must be at least one word so skip that. | 1997 zap++; // Header of filler must be at least one word so skip that. |
1998 for (int i = 1; i < to_trim; i++) { | 1998 for (int i = 1; i < to_trim; i++) { |
1999 *zap++ = Smi::FromInt(0); | 1999 *zap++ = Smi::FromInt(0); |
2000 } | 2000 } |
2001 } | 2001 } |
2002 | 2002 |
2003 | 2003 |
2004 template<Heap::InvocationMode mode> | 2004 template<Heap::InvocationMode mode> |
2005 static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) { | 2005 static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) { |
2006 ASSERT(elms->map() != heap->fixed_cow_array_map()); | 2006 DCHECK(elms->map() != heap->fixed_cow_array_map()); |
2007 // For now this trick is only applied to fixed arrays in new and paged space. | 2007 // For now this trick is only applied to fixed arrays in new and paged space. |
2008 ASSERT(!heap->lo_space()->Contains(elms)); | 2008 DCHECK(!heap->lo_space()->Contains(elms)); |
2009 | 2009 |
2010 const int len = elms->length(); | 2010 const int len = elms->length(); |
2011 | 2011 |
2012 ASSERT(to_trim < len); | 2012 DCHECK(to_trim < len); |
2013 | 2013 |
2014 Address new_end = elms->address() + FixedArray::SizeFor(len - to_trim); | 2014 Address new_end = elms->address() + FixedArray::SizeFor(len - to_trim); |
2015 | 2015 |
2016 if (mode != Heap::FROM_GC || Heap::ShouldZapGarbage()) { | 2016 if (mode != Heap::FROM_GC || Heap::ShouldZapGarbage()) { |
2017 ZapEndOfFixedArray(new_end, to_trim); | 2017 ZapEndOfFixedArray(new_end, to_trim); |
2018 } | 2018 } |
2019 | 2019 |
2020 int size_delta = to_trim * kPointerSize; | 2020 int size_delta = to_trim * kPointerSize; |
2021 | 2021 |
2022 // Technically in new space this write might be omitted (except for | 2022 // Technically in new space this write might be omitted (except for |
(...skipping 14 matching lines...) Expand all Loading... |
2037 profiler->UpdateObjectSizeEvent(elms->address(), elms->Size()); | 2037 profiler->UpdateObjectSizeEvent(elms->address(), elms->Size()); |
2038 } | 2038 } |
2039 } | 2039 } |
2040 | 2040 |
2041 | 2041 |
2042 bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, | 2042 bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, |
2043 int target_inobject, int target_unused, | 2043 int target_inobject, int target_unused, |
2044 int* old_number_of_fields) { | 2044 int* old_number_of_fields) { |
2045 // If fields were added (or removed), rewrite the instance. | 2045 // If fields were added (or removed), rewrite the instance. |
2046 *old_number_of_fields = NumberOfFields(); | 2046 *old_number_of_fields = NumberOfFields(); |
2047 ASSERT(target_number_of_fields >= *old_number_of_fields); | 2047 DCHECK(target_number_of_fields >= *old_number_of_fields); |
2048 if (target_number_of_fields != *old_number_of_fields) return true; | 2048 if (target_number_of_fields != *old_number_of_fields) return true; |
2049 | 2049 |
2050 // If smi descriptors were replaced by double descriptors, rewrite. | 2050 // If smi descriptors were replaced by double descriptors, rewrite. |
2051 DescriptorArray* old_desc = instance_descriptors(); | 2051 DescriptorArray* old_desc = instance_descriptors(); |
2052 DescriptorArray* new_desc = target->instance_descriptors(); | 2052 DescriptorArray* new_desc = target->instance_descriptors(); |
2053 int limit = NumberOfOwnDescriptors(); | 2053 int limit = NumberOfOwnDescriptors(); |
2054 for (int i = 0; i < limit; i++) { | 2054 for (int i = 0; i < limit; i++) { |
2055 if (new_desc->GetDetails(i).representation().IsDouble() != | 2055 if (new_desc->GetDetails(i).representation().IsDouble() != |
2056 old_desc->GetDetails(i).representation().IsDouble()) { | 2056 old_desc->GetDetails(i).representation().IsDouble()) { |
2057 return true; | 2057 return true; |
2058 } | 2058 } |
2059 } | 2059 } |
2060 | 2060 |
2061 // If no fields were added, and no inobject properties were removed, setting | 2061 // If no fields were added, and no inobject properties were removed, setting |
2062 // the map is sufficient. | 2062 // the map is sufficient. |
2063 if (target_inobject == inobject_properties()) return false; | 2063 if (target_inobject == inobject_properties()) return false; |
2064 // In-object slack tracking may have reduced the object size of the new map. | 2064 // In-object slack tracking may have reduced the object size of the new map. |
2065 // In that case, succeed if all existing fields were inobject, and they still | 2065 // In that case, succeed if all existing fields were inobject, and they still |
2066 // fit within the new inobject size. | 2066 // fit within the new inobject size. |
2067 ASSERT(target_inobject < inobject_properties()); | 2067 DCHECK(target_inobject < inobject_properties()); |
2068 if (target_number_of_fields <= target_inobject) { | 2068 if (target_number_of_fields <= target_inobject) { |
2069 ASSERT(target_number_of_fields + target_unused == target_inobject); | 2069 DCHECK(target_number_of_fields + target_unused == target_inobject); |
2070 return false; | 2070 return false; |
2071 } | 2071 } |
2072 // Otherwise, properties will need to be moved to the backing store. | 2072 // Otherwise, properties will need to be moved to the backing store. |
2073 return true; | 2073 return true; |
2074 } | 2074 } |
2075 | 2075 |
2076 | 2076 |
2077 Handle<TransitionArray> Map::SetElementsTransitionMap( | 2077 Handle<TransitionArray> Map::SetElementsTransitionMap( |
2078 Handle<Map> map, Handle<Map> transitioned_map) { | 2078 Handle<Map> map, Handle<Map> transitioned_map) { |
2079 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( | 2079 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2135 object->synchronized_set_map(*new_map); | 2135 object->synchronized_set_map(*new_map); |
2136 return; | 2136 return; |
2137 } | 2137 } |
2138 | 2138 |
2139 int total_size = number_of_fields + unused; | 2139 int total_size = number_of_fields + unused; |
2140 int external = total_size - inobject; | 2140 int external = total_size - inobject; |
2141 | 2141 |
2142 if ((old_map->unused_property_fields() == 0) && | 2142 if ((old_map->unused_property_fields() == 0) && |
2143 (number_of_fields != old_number_of_fields) && | 2143 (number_of_fields != old_number_of_fields) && |
2144 (new_map->GetBackPointer() == *old_map)) { | 2144 (new_map->GetBackPointer() == *old_map)) { |
2145 ASSERT(number_of_fields == old_number_of_fields + 1); | 2145 DCHECK(number_of_fields == old_number_of_fields + 1); |
2146 // This migration is a transition from a map that has run out out property | 2146 // This migration is a transition from a map that has run out out property |
2147 // space. Therefore it could be done by extending the backing store. | 2147 // space. Therefore it could be done by extending the backing store. |
2148 Handle<FixedArray> old_storage = handle(object->properties(), isolate); | 2148 Handle<FixedArray> old_storage = handle(object->properties(), isolate); |
2149 Handle<FixedArray> new_storage = | 2149 Handle<FixedArray> new_storage = |
2150 FixedArray::CopySize(old_storage, external); | 2150 FixedArray::CopySize(old_storage, external); |
2151 | 2151 |
2152 // Properly initialize newly added property. | 2152 // Properly initialize newly added property. |
2153 PropertyDetails details = new_map->GetLastDescriptorDetails(); | 2153 PropertyDetails details = new_map->GetLastDescriptorDetails(); |
2154 Handle<Object> value; | 2154 Handle<Object> value; |
2155 if (details.representation().IsDouble()) { | 2155 if (details.representation().IsDouble()) { |
2156 value = isolate->factory()->NewHeapNumber(0, MUTABLE); | 2156 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
2157 } else { | 2157 } else { |
2158 value = isolate->factory()->uninitialized_value(); | 2158 value = isolate->factory()->uninitialized_value(); |
2159 } | 2159 } |
2160 ASSERT(details.type() == FIELD); | 2160 DCHECK(details.type() == FIELD); |
2161 int target_index = details.field_index() - inobject; | 2161 int target_index = details.field_index() - inobject; |
2162 ASSERT(target_index >= 0); // Must be a backing store index. | 2162 DCHECK(target_index >= 0); // Must be a backing store index. |
2163 new_storage->set(target_index, *value); | 2163 new_storage->set(target_index, *value); |
2164 | 2164 |
2165 // From here on we cannot fail and we shouldn't GC anymore. | 2165 // From here on we cannot fail and we shouldn't GC anymore. |
2166 DisallowHeapAllocation no_allocation; | 2166 DisallowHeapAllocation no_allocation; |
2167 | 2167 |
2168 // Set the new property value and do the map transition. | 2168 // Set the new property value and do the map transition. |
2169 object->set_properties(*new_storage); | 2169 object->set_properties(*new_storage); |
2170 object->synchronized_set_map(*new_map); | 2170 object->synchronized_set_map(*new_map); |
2171 return; | 2171 return; |
2172 } | 2172 } |
2173 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size); | 2173 Handle<FixedArray> array = isolate->factory()->NewFixedArray(total_size); |
2174 | 2174 |
2175 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); | 2175 Handle<DescriptorArray> old_descriptors(old_map->instance_descriptors()); |
2176 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); | 2176 Handle<DescriptorArray> new_descriptors(new_map->instance_descriptors()); |
2177 int old_nof = old_map->NumberOfOwnDescriptors(); | 2177 int old_nof = old_map->NumberOfOwnDescriptors(); |
2178 int new_nof = new_map->NumberOfOwnDescriptors(); | 2178 int new_nof = new_map->NumberOfOwnDescriptors(); |
2179 | 2179 |
2180 // This method only supports generalizing instances to at least the same | 2180 // This method only supports generalizing instances to at least the same |
2181 // number of properties. | 2181 // number of properties. |
2182 ASSERT(old_nof <= new_nof); | 2182 DCHECK(old_nof <= new_nof); |
2183 | 2183 |
2184 for (int i = 0; i < old_nof; i++) { | 2184 for (int i = 0; i < old_nof; i++) { |
2185 PropertyDetails details = new_descriptors->GetDetails(i); | 2185 PropertyDetails details = new_descriptors->GetDetails(i); |
2186 if (details.type() != FIELD) continue; | 2186 if (details.type() != FIELD) continue; |
2187 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2187 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2188 if (old_details.type() == CALLBACKS) { | 2188 if (old_details.type() == CALLBACKS) { |
2189 ASSERT(details.representation().IsTagged()); | 2189 DCHECK(details.representation().IsTagged()); |
2190 continue; | 2190 continue; |
2191 } | 2191 } |
2192 ASSERT(old_details.type() == CONSTANT || | 2192 DCHECK(old_details.type() == CONSTANT || |
2193 old_details.type() == FIELD); | 2193 old_details.type() == FIELD); |
2194 Object* raw_value = old_details.type() == CONSTANT | 2194 Object* raw_value = old_details.type() == CONSTANT |
2195 ? old_descriptors->GetValue(i) | 2195 ? old_descriptors->GetValue(i) |
2196 : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i)); | 2196 : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i)); |
2197 Handle<Object> value(raw_value, isolate); | 2197 Handle<Object> value(raw_value, isolate); |
2198 if (!old_details.representation().IsDouble() && | 2198 if (!old_details.representation().IsDouble() && |
2199 details.representation().IsDouble()) { | 2199 details.representation().IsDouble()) { |
2200 if (old_details.representation().IsNone()) { | 2200 if (old_details.representation().IsNone()) { |
2201 value = handle(Smi::FromInt(0), isolate); | 2201 value = handle(Smi::FromInt(0), isolate); |
2202 } | 2202 } |
2203 value = Object::NewStorageFor(isolate, value, details.representation()); | 2203 value = Object::NewStorageFor(isolate, value, details.representation()); |
2204 } else if (old_details.representation().IsDouble() && | 2204 } else if (old_details.representation().IsDouble() && |
2205 !details.representation().IsDouble()) { | 2205 !details.representation().IsDouble()) { |
2206 value = Object::WrapForRead(isolate, value, old_details.representation()); | 2206 value = Object::WrapForRead(isolate, value, old_details.representation()); |
2207 } | 2207 } |
2208 ASSERT(!(details.representation().IsDouble() && value->IsSmi())); | 2208 DCHECK(!(details.representation().IsDouble() && value->IsSmi())); |
2209 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 2209 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
2210 if (target_index < 0) target_index += total_size; | 2210 if (target_index < 0) target_index += total_size; |
2211 array->set(target_index, *value); | 2211 array->set(target_index, *value); |
2212 } | 2212 } |
2213 | 2213 |
2214 for (int i = old_nof; i < new_nof; i++) { | 2214 for (int i = old_nof; i < new_nof; i++) { |
2215 PropertyDetails details = new_descriptors->GetDetails(i); | 2215 PropertyDetails details = new_descriptors->GetDetails(i); |
2216 if (details.type() != FIELD) continue; | 2216 if (details.type() != FIELD) continue; |
2217 Handle<Object> value; | 2217 Handle<Object> value; |
2218 if (details.representation().IsDouble()) { | 2218 if (details.representation().IsDouble()) { |
(...skipping 22 matching lines...) Expand all Loading... |
2241 // If there are properties in the new backing store, trim it to the correct | 2241 // If there are properties in the new backing store, trim it to the correct |
2242 // size and install the backing store into the object. | 2242 // size and install the backing store into the object. |
2243 if (external > 0) { | 2243 if (external > 0) { |
2244 RightTrimFixedArray<Heap::FROM_MUTATOR>(heap, *array, inobject); | 2244 RightTrimFixedArray<Heap::FROM_MUTATOR>(heap, *array, inobject); |
2245 object->set_properties(*array); | 2245 object->set_properties(*array); |
2246 } | 2246 } |
2247 | 2247 |
2248 // Create filler object past the new instance size. | 2248 // Create filler object past the new instance size. |
2249 int new_instance_size = new_map->instance_size(); | 2249 int new_instance_size = new_map->instance_size(); |
2250 int instance_size_delta = old_map->instance_size() - new_instance_size; | 2250 int instance_size_delta = old_map->instance_size() - new_instance_size; |
2251 ASSERT(instance_size_delta >= 0); | 2251 DCHECK(instance_size_delta >= 0); |
2252 | 2252 |
2253 if (instance_size_delta > 0) { | 2253 if (instance_size_delta > 0) { |
2254 Address address = object->address(); | 2254 Address address = object->address(); |
2255 heap->CreateFillerObjectAt( | 2255 heap->CreateFillerObjectAt( |
2256 address + new_instance_size, instance_size_delta); | 2256 address + new_instance_size, instance_size_delta); |
2257 heap->AdjustLiveBytes(address, -instance_size_delta, Heap::FROM_MUTATOR); | 2257 heap->AdjustLiveBytes(address, -instance_size_delta, Heap::FROM_MUTATOR); |
2258 } | 2258 } |
2259 | 2259 |
2260 // We are storing the new map using release store after creating a filler for | 2260 // We are storing the new map using release store after creating a filler for |
2261 // the left-over space to avoid races with the sweeper thread. | 2261 // the left-over space to avoid races with the sweeper thread. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2311 field_index, attributes, Representation::Tagged()); | 2311 field_index, attributes, Representation::Tagged()); |
2312 descriptors->Replace(modify_index, &d); | 2312 descriptors->Replace(modify_index, &d); |
2313 if (details.type() != FIELD) { | 2313 if (details.type() != FIELD) { |
2314 int unused_property_fields = new_map->unused_property_fields() - 1; | 2314 int unused_property_fields = new_map->unused_property_fields() - 1; |
2315 if (unused_property_fields < 0) { | 2315 if (unused_property_fields < 0) { |
2316 unused_property_fields += JSObject::kFieldsAdded; | 2316 unused_property_fields += JSObject::kFieldsAdded; |
2317 } | 2317 } |
2318 new_map->set_unused_property_fields(unused_property_fields); | 2318 new_map->set_unused_property_fields(unused_property_fields); |
2319 } | 2319 } |
2320 } else { | 2320 } else { |
2321 ASSERT(details.attributes() == attributes); | 2321 DCHECK(details.attributes() == attributes); |
2322 } | 2322 } |
2323 | 2323 |
2324 if (FLAG_trace_generalization) { | 2324 if (FLAG_trace_generalization) { |
2325 HeapType* field_type = (details.type() == FIELD) | 2325 HeapType* field_type = (details.type() == FIELD) |
2326 ? map->instance_descriptors()->GetFieldType(modify_index) | 2326 ? map->instance_descriptors()->GetFieldType(modify_index) |
2327 : NULL; | 2327 : NULL; |
2328 map->PrintGeneralization(stdout, reason, modify_index, | 2328 map->PrintGeneralization(stdout, reason, modify_index, |
2329 new_map->NumberOfOwnDescriptors(), | 2329 new_map->NumberOfOwnDescriptors(), |
2330 new_map->NumberOfOwnDescriptors(), | 2330 new_map->NumberOfOwnDescriptors(), |
2331 details.type() == CONSTANT && store_mode == FORCE_FIELD, | 2331 details.type() == CONSTANT && store_mode == FORCE_FIELD, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2402 } | 2402 } |
2403 } | 2403 } |
2404 | 2404 |
2405 | 2405 |
2406 Map* Map::FindLastMatchMap(int verbatim, | 2406 Map* Map::FindLastMatchMap(int verbatim, |
2407 int length, | 2407 int length, |
2408 DescriptorArray* descriptors) { | 2408 DescriptorArray* descriptors) { |
2409 DisallowHeapAllocation no_allocation; | 2409 DisallowHeapAllocation no_allocation; |
2410 | 2410 |
2411 // This can only be called on roots of transition trees. | 2411 // This can only be called on roots of transition trees. |
2412 ASSERT(GetBackPointer()->IsUndefined()); | 2412 DCHECK(GetBackPointer()->IsUndefined()); |
2413 | 2413 |
2414 Map* current = this; | 2414 Map* current = this; |
2415 | 2415 |
2416 for (int i = verbatim; i < length; i++) { | 2416 for (int i = verbatim; i < length; i++) { |
2417 if (!current->HasTransitionArray()) break; | 2417 if (!current->HasTransitionArray()) break; |
2418 Name* name = descriptors->GetKey(i); | 2418 Name* name = descriptors->GetKey(i); |
2419 TransitionArray* transitions = current->transitions(); | 2419 TransitionArray* transitions = current->transitions(); |
2420 int transition = transitions->Search(name); | 2420 int transition = transitions->Search(name); |
2421 if (transition == TransitionArray::kNotFound) break; | 2421 if (transition == TransitionArray::kNotFound) break; |
2422 | 2422 |
(...skipping 13 matching lines...) Expand all Loading... |
2436 } | 2436 } |
2437 | 2437 |
2438 current = next; | 2438 current = next; |
2439 } | 2439 } |
2440 return current; | 2440 return current; |
2441 } | 2441 } |
2442 | 2442 |
2443 | 2443 |
2444 Map* Map::FindFieldOwner(int descriptor) { | 2444 Map* Map::FindFieldOwner(int descriptor) { |
2445 DisallowHeapAllocation no_allocation; | 2445 DisallowHeapAllocation no_allocation; |
2446 ASSERT_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type()); | 2446 DCHECK_EQ(FIELD, instance_descriptors()->GetDetails(descriptor).type()); |
2447 Map* result = this; | 2447 Map* result = this; |
2448 while (true) { | 2448 while (true) { |
2449 Object* back = result->GetBackPointer(); | 2449 Object* back = result->GetBackPointer(); |
2450 if (back->IsUndefined()) break; | 2450 if (back->IsUndefined()) break; |
2451 Map* parent = Map::cast(back); | 2451 Map* parent = Map::cast(back); |
2452 if (parent->NumberOfOwnDescriptors() <= descriptor) break; | 2452 if (parent->NumberOfOwnDescriptors() <= descriptor) break; |
2453 result = parent; | 2453 result = parent; |
2454 } | 2454 } |
2455 return result; | 2455 return result; |
2456 } | 2456 } |
(...skipping 21 matching lines...) Expand all Loading... |
2478 // static | 2478 // static |
2479 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, | 2479 Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1, |
2480 Handle<HeapType> type2, | 2480 Handle<HeapType> type2, |
2481 Isolate* isolate) { | 2481 Isolate* isolate) { |
2482 static const int kMaxClassesPerFieldType = 5; | 2482 static const int kMaxClassesPerFieldType = 5; |
2483 if (type1->NowIs(type2)) return type2; | 2483 if (type1->NowIs(type2)) return type2; |
2484 if (type2->NowIs(type1)) return type1; | 2484 if (type2->NowIs(type1)) return type1; |
2485 if (type1->NowStable() && type2->NowStable()) { | 2485 if (type1->NowStable() && type2->NowStable()) { |
2486 Handle<HeapType> type = HeapType::Union(type1, type2, isolate); | 2486 Handle<HeapType> type = HeapType::Union(type1, type2, isolate); |
2487 if (type->NumClasses() <= kMaxClassesPerFieldType) { | 2487 if (type->NumClasses() <= kMaxClassesPerFieldType) { |
2488 ASSERT(type->NowStable()); | 2488 DCHECK(type->NowStable()); |
2489 ASSERT(type1->NowIs(type)); | 2489 DCHECK(type1->NowIs(type)); |
2490 ASSERT(type2->NowIs(type)); | 2490 DCHECK(type2->NowIs(type)); |
2491 return type; | 2491 return type; |
2492 } | 2492 } |
2493 } | 2493 } |
2494 return HeapType::Any(isolate); | 2494 return HeapType::Any(isolate); |
2495 } | 2495 } |
2496 | 2496 |
2497 | 2497 |
2498 // static | 2498 // static |
2499 void Map::GeneralizeFieldType(Handle<Map> map, | 2499 void Map::GeneralizeFieldType(Handle<Map> map, |
2500 int modify_index, | 2500 int modify_index, |
2501 Handle<HeapType> new_field_type) { | 2501 Handle<HeapType> new_field_type) { |
2502 Isolate* isolate = map->GetIsolate(); | 2502 Isolate* isolate = map->GetIsolate(); |
2503 | 2503 |
2504 // Check if we actually need to generalize the field type at all. | 2504 // Check if we actually need to generalize the field type at all. |
2505 Handle<HeapType> old_field_type( | 2505 Handle<HeapType> old_field_type( |
2506 map->instance_descriptors()->GetFieldType(modify_index), isolate); | 2506 map->instance_descriptors()->GetFieldType(modify_index), isolate); |
2507 if (new_field_type->NowIs(old_field_type)) { | 2507 if (new_field_type->NowIs(old_field_type)) { |
2508 ASSERT(Map::GeneralizeFieldType(old_field_type, | 2508 DCHECK(Map::GeneralizeFieldType(old_field_type, |
2509 new_field_type, | 2509 new_field_type, |
2510 isolate)->NowIs(old_field_type)); | 2510 isolate)->NowIs(old_field_type)); |
2511 return; | 2511 return; |
2512 } | 2512 } |
2513 | 2513 |
2514 // Determine the field owner. | 2514 // Determine the field owner. |
2515 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate); | 2515 Handle<Map> field_owner(map->FindFieldOwner(modify_index), isolate); |
2516 Handle<DescriptorArray> descriptors( | 2516 Handle<DescriptorArray> descriptors( |
2517 field_owner->instance_descriptors(), isolate); | 2517 field_owner->instance_descriptors(), isolate); |
2518 ASSERT_EQ(*old_field_type, descriptors->GetFieldType(modify_index)); | 2518 DCHECK_EQ(*old_field_type, descriptors->GetFieldType(modify_index)); |
2519 | 2519 |
2520 // Determine the generalized new field type. | 2520 // Determine the generalized new field type. |
2521 new_field_type = Map::GeneralizeFieldType( | 2521 new_field_type = Map::GeneralizeFieldType( |
2522 old_field_type, new_field_type, isolate); | 2522 old_field_type, new_field_type, isolate); |
2523 | 2523 |
2524 PropertyDetails details = descriptors->GetDetails(modify_index); | 2524 PropertyDetails details = descriptors->GetDetails(modify_index); |
2525 Handle<Name> name(descriptors->GetKey(modify_index)); | 2525 Handle<Name> name(descriptors->GetKey(modify_index)); |
2526 field_owner->UpdateFieldType(modify_index, name, new_field_type); | 2526 field_owner->UpdateFieldType(modify_index, name, new_field_type); |
2527 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( | 2527 field_owner->dependent_code()->DeoptimizeDependentCodeGroup( |
2528 isolate, DependentCode::kFieldTypeGroup); | 2528 isolate, DependentCode::kFieldTypeGroup); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2570 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2570 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2571 Representation old_representation = old_details.representation(); | 2571 Representation old_representation = old_details.representation(); |
2572 | 2572 |
2573 // It's fine to transition from None to anything but double without any | 2573 // It's fine to transition from None to anything but double without any |
2574 // modification to the object, because the default uninitialized value for | 2574 // modification to the object, because the default uninitialized value for |
2575 // representation None can be overwritten by both smi and tagged values. | 2575 // representation None can be overwritten by both smi and tagged values. |
2576 // Doubles, however, would require a box allocation. | 2576 // Doubles, however, would require a box allocation. |
2577 if (old_representation.IsNone() && | 2577 if (old_representation.IsNone() && |
2578 !new_representation.IsNone() && | 2578 !new_representation.IsNone() && |
2579 !new_representation.IsDouble()) { | 2579 !new_representation.IsDouble()) { |
2580 ASSERT(old_details.type() == FIELD); | 2580 DCHECK(old_details.type() == FIELD); |
2581 ASSERT(old_descriptors->GetFieldType(modify_index)->NowIs( | 2581 DCHECK(old_descriptors->GetFieldType(modify_index)->NowIs( |
2582 HeapType::None())); | 2582 HeapType::None())); |
2583 if (FLAG_trace_generalization) { | 2583 if (FLAG_trace_generalization) { |
2584 old_map->PrintGeneralization( | 2584 old_map->PrintGeneralization( |
2585 stdout, "uninitialized field", | 2585 stdout, "uninitialized field", |
2586 modify_index, old_map->NumberOfOwnDescriptors(), | 2586 modify_index, old_map->NumberOfOwnDescriptors(), |
2587 old_map->NumberOfOwnDescriptors(), false, | 2587 old_map->NumberOfOwnDescriptors(), false, |
2588 old_representation, new_representation, | 2588 old_representation, new_representation, |
2589 old_descriptors->GetFieldType(modify_index), *new_field_type); | 2589 old_descriptors->GetFieldType(modify_index), *new_field_type); |
2590 } | 2590 } |
2591 old_descriptors->SetRepresentation(modify_index, new_representation); | 2591 old_descriptors->SetRepresentation(modify_index, new_representation); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2648 old_field_type = GeneralizeFieldType( | 2648 old_field_type = GeneralizeFieldType( |
2649 new_field_type, old_field_type, isolate); | 2649 new_field_type, old_field_type, isolate); |
2650 } | 2650 } |
2651 GeneralizeFieldType(tmp_map, i, old_field_type); | 2651 GeneralizeFieldType(tmp_map, i, old_field_type); |
2652 } else if (tmp_type == CONSTANT) { | 2652 } else if (tmp_type == CONSTANT) { |
2653 if (old_type != CONSTANT || | 2653 if (old_type != CONSTANT || |
2654 old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) { | 2654 old_descriptors->GetConstant(i) != tmp_descriptors->GetConstant(i)) { |
2655 break; | 2655 break; |
2656 } | 2656 } |
2657 } else { | 2657 } else { |
2658 ASSERT_EQ(tmp_type, old_type); | 2658 DCHECK_EQ(tmp_type, old_type); |
2659 ASSERT_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i)); | 2659 DCHECK_EQ(tmp_descriptors->GetValue(i), old_descriptors->GetValue(i)); |
2660 } | 2660 } |
2661 target_map = tmp_map; | 2661 target_map = tmp_map; |
2662 } | 2662 } |
2663 | 2663 |
2664 // Directly change the map if the target map is more general. | 2664 // Directly change the map if the target map is more general. |
2665 Handle<DescriptorArray> target_descriptors( | 2665 Handle<DescriptorArray> target_descriptors( |
2666 target_map->instance_descriptors(), isolate); | 2666 target_map->instance_descriptors(), isolate); |
2667 int target_nof = target_map->NumberOfOwnDescriptors(); | 2667 int target_nof = target_map->NumberOfOwnDescriptors(); |
2668 if (target_nof == old_nof && | 2668 if (target_nof == old_nof && |
2669 (store_mode != FORCE_FIELD || | 2669 (store_mode != FORCE_FIELD || |
2670 target_descriptors->GetDetails(modify_index).type() == FIELD)) { | 2670 target_descriptors->GetDetails(modify_index).type() == FIELD)) { |
2671 ASSERT(modify_index < target_nof); | 2671 DCHECK(modify_index < target_nof); |
2672 ASSERT(new_representation.fits_into( | 2672 DCHECK(new_representation.fits_into( |
2673 target_descriptors->GetDetails(modify_index).representation())); | 2673 target_descriptors->GetDetails(modify_index).representation())); |
2674 ASSERT(target_descriptors->GetDetails(modify_index).type() != FIELD || | 2674 DCHECK(target_descriptors->GetDetails(modify_index).type() != FIELD || |
2675 new_field_type->NowIs( | 2675 new_field_type->NowIs( |
2676 target_descriptors->GetFieldType(modify_index))); | 2676 target_descriptors->GetFieldType(modify_index))); |
2677 return target_map; | 2677 return target_map; |
2678 } | 2678 } |
2679 | 2679 |
2680 // Find the last compatible target map in the transition tree. | 2680 // Find the last compatible target map in the transition tree. |
2681 for (int i = target_nof; i < old_nof; ++i) { | 2681 for (int i = target_nof; i < old_nof; ++i) { |
2682 int j = target_map->SearchTransition(old_descriptors->GetKey(i)); | 2682 int j = target_map->SearchTransition(old_descriptors->GetKey(i)); |
2683 if (j == TransitionArray::kNotFound) break; | 2683 if (j == TransitionArray::kNotFound) break; |
2684 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); | 2684 Handle<Map> tmp_map(target_map->GetTransition(j), isolate); |
(...skipping 15 matching lines...) Expand all Loading... |
2700 target_nof = target_map->NumberOfOwnDescriptors(); | 2700 target_nof = target_map->NumberOfOwnDescriptors(); |
2701 target_descriptors = handle(target_map->instance_descriptors(), isolate); | 2701 target_descriptors = handle(target_map->instance_descriptors(), isolate); |
2702 | 2702 |
2703 // Allocate a new descriptor array large enough to hold the required | 2703 // Allocate a new descriptor array large enough to hold the required |
2704 // descriptors, with minimally the exact same size as the old descriptor | 2704 // descriptors, with minimally the exact same size as the old descriptor |
2705 // array. | 2705 // array. |
2706 int new_slack = Max( | 2706 int new_slack = Max( |
2707 old_nof, old_descriptors->number_of_descriptors()) - old_nof; | 2707 old_nof, old_descriptors->number_of_descriptors()) - old_nof; |
2708 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate( | 2708 Handle<DescriptorArray> new_descriptors = DescriptorArray::Allocate( |
2709 isolate, old_nof, new_slack); | 2709 isolate, old_nof, new_slack); |
2710 ASSERT(new_descriptors->length() > target_descriptors->length() || | 2710 DCHECK(new_descriptors->length() > target_descriptors->length() || |
2711 new_descriptors->NumberOfSlackDescriptors() > 0 || | 2711 new_descriptors->NumberOfSlackDescriptors() > 0 || |
2712 new_descriptors->number_of_descriptors() == | 2712 new_descriptors->number_of_descriptors() == |
2713 old_descriptors->number_of_descriptors()); | 2713 old_descriptors->number_of_descriptors()); |
2714 ASSERT(new_descriptors->number_of_descriptors() == old_nof); | 2714 DCHECK(new_descriptors->number_of_descriptors() == old_nof); |
2715 | 2715 |
2716 // 0 -> |root_nof| | 2716 // 0 -> |root_nof| |
2717 int current_offset = 0; | 2717 int current_offset = 0; |
2718 for (int i = 0; i < root_nof; ++i) { | 2718 for (int i = 0; i < root_nof; ++i) { |
2719 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2719 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2720 if (old_details.type() == FIELD) current_offset++; | 2720 if (old_details.type() == FIELD) current_offset++; |
2721 Descriptor d(handle(old_descriptors->GetKey(i), isolate), | 2721 Descriptor d(handle(old_descriptors->GetKey(i), isolate), |
2722 handle(old_descriptors->GetValue(i), isolate), | 2722 handle(old_descriptors->GetValue(i), isolate), |
2723 old_details); | 2723 old_details); |
2724 new_descriptors->Set(i, &d); | 2724 new_descriptors->Set(i, &d); |
2725 } | 2725 } |
2726 | 2726 |
2727 // |root_nof| -> |target_nof| | 2727 // |root_nof| -> |target_nof| |
2728 for (int i = root_nof; i < target_nof; ++i) { | 2728 for (int i = root_nof; i < target_nof; ++i) { |
2729 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); | 2729 Handle<Name> target_key(target_descriptors->GetKey(i), isolate); |
2730 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2730 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2731 PropertyDetails target_details = target_descriptors->GetDetails(i); | 2731 PropertyDetails target_details = target_descriptors->GetDetails(i); |
2732 target_details = target_details.CopyWithRepresentation( | 2732 target_details = target_details.CopyWithRepresentation( |
2733 old_details.representation().generalize( | 2733 old_details.representation().generalize( |
2734 target_details.representation())); | 2734 target_details.representation())); |
2735 if (modify_index == i) { | 2735 if (modify_index == i) { |
2736 target_details = target_details.CopyWithRepresentation( | 2736 target_details = target_details.CopyWithRepresentation( |
2737 new_representation.generalize(target_details.representation())); | 2737 new_representation.generalize(target_details.representation())); |
2738 } | 2738 } |
2739 ASSERT_EQ(old_details.attributes(), target_details.attributes()); | 2739 DCHECK_EQ(old_details.attributes(), target_details.attributes()); |
2740 if (old_details.type() == FIELD || | 2740 if (old_details.type() == FIELD || |
2741 target_details.type() == FIELD || | 2741 target_details.type() == FIELD || |
2742 (modify_index == i && store_mode == FORCE_FIELD) || | 2742 (modify_index == i && store_mode == FORCE_FIELD) || |
2743 (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { | 2743 (target_descriptors->GetValue(i) != old_descriptors->GetValue(i))) { |
2744 Handle<HeapType> old_field_type = (old_details.type() == FIELD) | 2744 Handle<HeapType> old_field_type = (old_details.type() == FIELD) |
2745 ? handle(old_descriptors->GetFieldType(i), isolate) | 2745 ? handle(old_descriptors->GetFieldType(i), isolate) |
2746 : old_descriptors->GetValue(i)->OptimalType( | 2746 : old_descriptors->GetValue(i)->OptimalType( |
2747 isolate, target_details.representation()); | 2747 isolate, target_details.representation()); |
2748 Handle<HeapType> target_field_type = (target_details.type() == FIELD) | 2748 Handle<HeapType> target_field_type = (target_details.type() == FIELD) |
2749 ? handle(target_descriptors->GetFieldType(i), isolate) | 2749 ? handle(target_descriptors->GetFieldType(i), isolate) |
2750 : target_descriptors->GetValue(i)->OptimalType( | 2750 : target_descriptors->GetValue(i)->OptimalType( |
2751 isolate, target_details.representation()); | 2751 isolate, target_details.representation()); |
2752 target_field_type = GeneralizeFieldType( | 2752 target_field_type = GeneralizeFieldType( |
2753 target_field_type, old_field_type, isolate); | 2753 target_field_type, old_field_type, isolate); |
2754 if (modify_index == i) { | 2754 if (modify_index == i) { |
2755 target_field_type = GeneralizeFieldType( | 2755 target_field_type = GeneralizeFieldType( |
2756 target_field_type, new_field_type, isolate); | 2756 target_field_type, new_field_type, isolate); |
2757 } | 2757 } |
2758 FieldDescriptor d(target_key, | 2758 FieldDescriptor d(target_key, |
2759 current_offset++, | 2759 current_offset++, |
2760 target_field_type, | 2760 target_field_type, |
2761 target_details.attributes(), | 2761 target_details.attributes(), |
2762 target_details.representation()); | 2762 target_details.representation()); |
2763 new_descriptors->Set(i, &d); | 2763 new_descriptors->Set(i, &d); |
2764 } else { | 2764 } else { |
2765 ASSERT_NE(FIELD, target_details.type()); | 2765 DCHECK_NE(FIELD, target_details.type()); |
2766 Descriptor d(target_key, | 2766 Descriptor d(target_key, |
2767 handle(target_descriptors->GetValue(i), isolate), | 2767 handle(target_descriptors->GetValue(i), isolate), |
2768 target_details); | 2768 target_details); |
2769 new_descriptors->Set(i, &d); | 2769 new_descriptors->Set(i, &d); |
2770 } | 2770 } |
2771 } | 2771 } |
2772 | 2772 |
2773 // |target_nof| -> |old_nof| | 2773 // |target_nof| -> |old_nof| |
2774 for (int i = target_nof; i < old_nof; ++i) { | 2774 for (int i = target_nof; i < old_nof; ++i) { |
2775 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2775 PropertyDetails old_details = old_descriptors->GetDetails(i); |
2776 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); | 2776 Handle<Name> old_key(old_descriptors->GetKey(i), isolate); |
2777 if (modify_index == i) { | 2777 if (modify_index == i) { |
2778 old_details = old_details.CopyWithRepresentation( | 2778 old_details = old_details.CopyWithRepresentation( |
2779 new_representation.generalize(old_details.representation())); | 2779 new_representation.generalize(old_details.representation())); |
2780 } | 2780 } |
2781 if (old_details.type() == FIELD) { | 2781 if (old_details.type() == FIELD) { |
2782 Handle<HeapType> old_field_type( | 2782 Handle<HeapType> old_field_type( |
2783 old_descriptors->GetFieldType(i), isolate); | 2783 old_descriptors->GetFieldType(i), isolate); |
2784 if (modify_index == i) { | 2784 if (modify_index == i) { |
2785 old_field_type = GeneralizeFieldType( | 2785 old_field_type = GeneralizeFieldType( |
2786 old_field_type, new_field_type, isolate); | 2786 old_field_type, new_field_type, isolate); |
2787 } | 2787 } |
2788 FieldDescriptor d(old_key, | 2788 FieldDescriptor d(old_key, |
2789 current_offset++, | 2789 current_offset++, |
2790 old_field_type, | 2790 old_field_type, |
2791 old_details.attributes(), | 2791 old_details.attributes(), |
2792 old_details.representation()); | 2792 old_details.representation()); |
2793 new_descriptors->Set(i, &d); | 2793 new_descriptors->Set(i, &d); |
2794 } else { | 2794 } else { |
2795 ASSERT(old_details.type() == CONSTANT || old_details.type() == CALLBACKS); | 2795 DCHECK(old_details.type() == CONSTANT || old_details.type() == CALLBACKS); |
2796 if (modify_index == i && store_mode == FORCE_FIELD) { | 2796 if (modify_index == i && store_mode == FORCE_FIELD) { |
2797 FieldDescriptor d(old_key, | 2797 FieldDescriptor d(old_key, |
2798 current_offset++, | 2798 current_offset++, |
2799 GeneralizeFieldType( | 2799 GeneralizeFieldType( |
2800 old_descriptors->GetValue(i)->OptimalType( | 2800 old_descriptors->GetValue(i)->OptimalType( |
2801 isolate, old_details.representation()), | 2801 isolate, old_details.representation()), |
2802 new_field_type, isolate), | 2802 new_field_type, isolate), |
2803 old_details.attributes(), | 2803 old_details.attributes(), |
2804 old_details.representation()); | 2804 old_details.representation()); |
2805 new_descriptors->Set(i, &d); | 2805 new_descriptors->Set(i, &d); |
2806 } else { | 2806 } else { |
2807 ASSERT_NE(FIELD, old_details.type()); | 2807 DCHECK_NE(FIELD, old_details.type()); |
2808 Descriptor d(old_key, | 2808 Descriptor d(old_key, |
2809 handle(old_descriptors->GetValue(i), isolate), | 2809 handle(old_descriptors->GetValue(i), isolate), |
2810 old_details); | 2810 old_details); |
2811 new_descriptors->Set(i, &d); | 2811 new_descriptors->Set(i, &d); |
2812 } | 2812 } |
2813 } | 2813 } |
2814 } | 2814 } |
2815 | 2815 |
2816 new_descriptors->Sort(); | 2816 new_descriptors->Sort(); |
2817 | 2817 |
2818 ASSERT(store_mode != FORCE_FIELD || | 2818 DCHECK(store_mode != FORCE_FIELD || |
2819 new_descriptors->GetDetails(modify_index).type() == FIELD); | 2819 new_descriptors->GetDetails(modify_index).type() == FIELD); |
2820 | 2820 |
2821 Handle<Map> split_map(root_map->FindLastMatchMap( | 2821 Handle<Map> split_map(root_map->FindLastMatchMap( |
2822 root_nof, old_nof, *new_descriptors), isolate); | 2822 root_nof, old_nof, *new_descriptors), isolate); |
2823 int split_nof = split_map->NumberOfOwnDescriptors(); | 2823 int split_nof = split_map->NumberOfOwnDescriptors(); |
2824 ASSERT_NE(old_nof, split_nof); | 2824 DCHECK_NE(old_nof, split_nof); |
2825 | 2825 |
2826 split_map->DeprecateTarget( | 2826 split_map->DeprecateTarget( |
2827 old_descriptors->GetKey(split_nof), *new_descriptors); | 2827 old_descriptors->GetKey(split_nof), *new_descriptors); |
2828 | 2828 |
2829 if (FLAG_trace_generalization) { | 2829 if (FLAG_trace_generalization) { |
2830 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); | 2830 PropertyDetails old_details = old_descriptors->GetDetails(modify_index); |
2831 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); | 2831 PropertyDetails new_details = new_descriptors->GetDetails(modify_index); |
2832 Handle<HeapType> old_field_type = (old_details.type() == FIELD) | 2832 Handle<HeapType> old_field_type = (old_details.type() == FIELD) |
2833 ? handle(old_descriptors->GetFieldType(modify_index), isolate) | 2833 ? handle(old_descriptors->GetFieldType(modify_index), isolate) |
2834 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), | 2834 : HeapType::Constant(handle(old_descriptors->GetValue(modify_index), |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3087 } | 3087 } |
3088 | 3088 |
3089 | 3089 |
3090 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, | 3090 MaybeHandle<Object> Object::SetDataProperty(LookupIterator* it, |
3091 Handle<Object> value) { | 3091 Handle<Object> value) { |
3092 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot | 3092 // Proxies are handled on the WithHandler path. Other non-JSObjects cannot |
3093 // have own properties. | 3093 // have own properties. |
3094 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 3094 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
3095 | 3095 |
3096 // Store on the holder which may be hidden behind the receiver. | 3096 // Store on the holder which may be hidden behind the receiver. |
3097 ASSERT(it->HolderIsReceiverOrHiddenPrototype()); | 3097 DCHECK(it->HolderIsReceiverOrHiddenPrototype()); |
3098 | 3098 |
3099 // Old value for the observation change record. | 3099 // Old value for the observation change record. |
3100 // Fetch before transforming the object since the encoding may become | 3100 // Fetch before transforming the object since the encoding may become |
3101 // incompatible with what's cached in |it|. | 3101 // incompatible with what's cached in |it|. |
3102 bool is_observed = | 3102 bool is_observed = |
3103 receiver->map()->is_observed() && | 3103 receiver->map()->is_observed() && |
3104 !it->name().is_identical_to(it->factory()->hidden_string()); | 3104 !it->name().is_identical_to(it->factory()->hidden_string()); |
3105 MaybeHandle<Object> maybe_old; | 3105 MaybeHandle<Object> maybe_old; |
3106 if (is_observed) maybe_old = it->GetDataValue(); | 3106 if (is_observed) maybe_old = it->GetDataValue(); |
3107 | 3107 |
(...skipping 12 matching lines...) Expand all Loading... |
3120 | 3120 |
3121 return value; | 3121 return value; |
3122 } | 3122 } |
3123 | 3123 |
3124 | 3124 |
3125 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, | 3125 MaybeHandle<Object> Object::AddDataProperty(LookupIterator* it, |
3126 Handle<Object> value, | 3126 Handle<Object> value, |
3127 PropertyAttributes attributes, | 3127 PropertyAttributes attributes, |
3128 StrictMode strict_mode, | 3128 StrictMode strict_mode, |
3129 StoreFromKeyed store_mode) { | 3129 StoreFromKeyed store_mode) { |
3130 ASSERT(!it->GetReceiver()->IsJSProxy()); | 3130 DCHECK(!it->GetReceiver()->IsJSProxy()); |
3131 if (!it->GetReceiver()->IsJSObject()) { | 3131 if (!it->GetReceiver()->IsJSObject()) { |
3132 // TODO(verwaest): Throw a TypeError with a more specific message. | 3132 // TODO(verwaest): Throw a TypeError with a more specific message. |
3133 return WriteToReadOnlyProperty(it, value, strict_mode); | 3133 return WriteToReadOnlyProperty(it, value, strict_mode); |
3134 } | 3134 } |
3135 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); | 3135 Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
3136 | 3136 |
3137 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) | 3137 // If the receiver is a JSGlobalProxy, store on the prototype (JSGlobalObject) |
3138 // instead. If the prototype is Null, the proxy is detached. | 3138 // instead. If the prototype is Null, the proxy is detached. |
3139 if (receiver->IsJSGlobalProxy()) { | 3139 if (receiver->IsJSGlobalProxy()) { |
3140 // Trying to assign to a detached proxy. | 3140 // Trying to assign to a detached proxy. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3210 } | 3210 } |
3211 } | 3211 } |
3212 } | 3212 } |
3213 *found = false; | 3213 *found = false; |
3214 return isolate->factory()->the_hole_value(); | 3214 return isolate->factory()->the_hole_value(); |
3215 } | 3215 } |
3216 | 3216 |
3217 | 3217 |
3218 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { | 3218 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { |
3219 // Only supports adding slack to owned descriptors. | 3219 // Only supports adding slack to owned descriptors. |
3220 ASSERT(map->owns_descriptors()); | 3220 DCHECK(map->owns_descriptors()); |
3221 | 3221 |
3222 Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 3222 Handle<DescriptorArray> descriptors(map->instance_descriptors()); |
3223 int old_size = map->NumberOfOwnDescriptors(); | 3223 int old_size = map->NumberOfOwnDescriptors(); |
3224 if (slack <= descriptors->NumberOfSlackDescriptors()) return; | 3224 if (slack <= descriptors->NumberOfSlackDescriptors()) return; |
3225 | 3225 |
3226 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 3226 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
3227 descriptors, old_size, slack); | 3227 descriptors, old_size, slack); |
3228 | 3228 |
3229 if (old_size == 0) { | 3229 if (old_size == 0) { |
3230 map->set_instance_descriptors(*new_descriptors); | 3230 map->set_instance_descriptors(*new_descriptors); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3330 array->set(valid_descriptors, *entry); | 3330 array->set(valid_descriptors, *entry); |
3331 } | 3331 } |
3332 }; | 3332 }; |
3333 | 3333 |
3334 | 3334 |
3335 void Map::AppendCallbackDescriptors(Handle<Map> map, | 3335 void Map::AppendCallbackDescriptors(Handle<Map> map, |
3336 Handle<Object> descriptors) { | 3336 Handle<Object> descriptors) { |
3337 int nof = map->NumberOfOwnDescriptors(); | 3337 int nof = map->NumberOfOwnDescriptors(); |
3338 Handle<DescriptorArray> array(map->instance_descriptors()); | 3338 Handle<DescriptorArray> array(map->instance_descriptors()); |
3339 NeanderArray callbacks(descriptors); | 3339 NeanderArray callbacks(descriptors); |
3340 ASSERT(array->NumberOfSlackDescriptors() >= callbacks.length()); | 3340 DCHECK(array->NumberOfSlackDescriptors() >= callbacks.length()); |
3341 nof = AppendUniqueCallbacks<DescriptorArrayAppender>(&callbacks, array, nof); | 3341 nof = AppendUniqueCallbacks<DescriptorArrayAppender>(&callbacks, array, nof); |
3342 map->SetNumberOfOwnDescriptors(nof); | 3342 map->SetNumberOfOwnDescriptors(nof); |
3343 } | 3343 } |
3344 | 3344 |
3345 | 3345 |
3346 int AccessorInfo::AppendUnique(Handle<Object> descriptors, | 3346 int AccessorInfo::AppendUnique(Handle<Object> descriptors, |
3347 Handle<FixedArray> array, | 3347 Handle<FixedArray> array, |
3348 int valid_descriptors) { | 3348 int valid_descriptors) { |
3349 NeanderArray callbacks(descriptors); | 3349 NeanderArray callbacks(descriptors); |
3350 ASSERT(array->length() >= callbacks.length() + valid_descriptors); | 3350 DCHECK(array->length() >= callbacks.length() + valid_descriptors); |
3351 return AppendUniqueCallbacks<FixedArrayAppender>(&callbacks, | 3351 return AppendUniqueCallbacks<FixedArrayAppender>(&callbacks, |
3352 array, | 3352 array, |
3353 valid_descriptors); | 3353 valid_descriptors); |
3354 } | 3354 } |
3355 | 3355 |
3356 | 3356 |
3357 static bool ContainsMap(MapHandleList* maps, Handle<Map> map) { | 3357 static bool ContainsMap(MapHandleList* maps, Handle<Map> map) { |
3358 ASSERT(!map.is_null()); | 3358 DCHECK(!map.is_null()); |
3359 for (int i = 0; i < maps->length(); ++i) { | 3359 for (int i = 0; i < maps->length(); ++i) { |
3360 if (!maps->at(i).is_null() && maps->at(i).is_identical_to(map)) return true; | 3360 if (!maps->at(i).is_null() && maps->at(i).is_identical_to(map)) return true; |
3361 } | 3361 } |
3362 return false; | 3362 return false; |
3363 } | 3363 } |
3364 | 3364 |
3365 | 3365 |
3366 template <class T> | 3366 template <class T> |
3367 static Handle<T> MaybeNull(T* p) { | 3367 static Handle<T> MaybeNull(T* p) { |
3368 if (p == NULL) return Handle<T>::null(); | 3368 if (p == NULL) return Handle<T>::null(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3414 } | 3414 } |
3415 | 3415 |
3416 ElementsKind kind = map->elements_kind(); | 3416 ElementsKind kind = map->elements_kind(); |
3417 while (kind != target_kind) { | 3417 while (kind != target_kind) { |
3418 kind = GetNextTransitionElementsKind(kind); | 3418 kind = GetNextTransitionElementsKind(kind); |
3419 if (!current_map->HasElementsTransition()) return current_map; | 3419 if (!current_map->HasElementsTransition()) return current_map; |
3420 current_map = current_map->elements_transition_map(); | 3420 current_map = current_map->elements_transition_map(); |
3421 } | 3421 } |
3422 | 3422 |
3423 if (to_kind != kind && current_map->HasElementsTransition()) { | 3423 if (to_kind != kind && current_map->HasElementsTransition()) { |
3424 ASSERT(to_kind == DICTIONARY_ELEMENTS); | 3424 DCHECK(to_kind == DICTIONARY_ELEMENTS); |
3425 Map* next_map = current_map->elements_transition_map(); | 3425 Map* next_map = current_map->elements_transition_map(); |
3426 if (next_map->elements_kind() == to_kind) return next_map; | 3426 if (next_map->elements_kind() == to_kind) return next_map; |
3427 } | 3427 } |
3428 | 3428 |
3429 ASSERT(current_map->elements_kind() == target_kind); | 3429 DCHECK(current_map->elements_kind() == target_kind); |
3430 return current_map; | 3430 return current_map; |
3431 } | 3431 } |
3432 | 3432 |
3433 | 3433 |
3434 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { | 3434 Map* Map::LookupElementsTransitionMap(ElementsKind to_kind) { |
3435 Map* to_map = FindClosestElementsTransition(this, to_kind); | 3435 Map* to_map = FindClosestElementsTransition(this, to_kind); |
3436 if (to_map->elements_kind() == to_kind) return to_map; | 3436 if (to_map->elements_kind() == to_kind) return to_map; |
3437 return NULL; | 3437 return NULL; |
3438 } | 3438 } |
3439 | 3439 |
3440 | 3440 |
3441 bool Map::IsMapInArrayPrototypeChain() { | 3441 bool Map::IsMapInArrayPrototypeChain() { |
3442 Isolate* isolate = GetIsolate(); | 3442 Isolate* isolate = GetIsolate(); |
3443 if (isolate->initial_array_prototype()->map() == this) { | 3443 if (isolate->initial_array_prototype()->map() == this) { |
3444 return true; | 3444 return true; |
3445 } | 3445 } |
3446 | 3446 |
3447 if (isolate->initial_object_prototype()->map() == this) { | 3447 if (isolate->initial_object_prototype()->map() == this) { |
3448 return true; | 3448 return true; |
3449 } | 3449 } |
3450 | 3450 |
3451 return false; | 3451 return false; |
3452 } | 3452 } |
3453 | 3453 |
3454 | 3454 |
3455 static Handle<Map> AddMissingElementsTransitions(Handle<Map> map, | 3455 static Handle<Map> AddMissingElementsTransitions(Handle<Map> map, |
3456 ElementsKind to_kind) { | 3456 ElementsKind to_kind) { |
3457 ASSERT(IsTransitionElementsKind(map->elements_kind())); | 3457 DCHECK(IsTransitionElementsKind(map->elements_kind())); |
3458 | 3458 |
3459 Handle<Map> current_map = map; | 3459 Handle<Map> current_map = map; |
3460 | 3460 |
3461 ElementsKind kind = map->elements_kind(); | 3461 ElementsKind kind = map->elements_kind(); |
3462 while (kind != to_kind && !IsTerminalElementsKind(kind)) { | 3462 while (kind != to_kind && !IsTerminalElementsKind(kind)) { |
3463 kind = GetNextTransitionElementsKind(kind); | 3463 kind = GetNextTransitionElementsKind(kind); |
3464 current_map = Map::CopyAsElementsKind( | 3464 current_map = Map::CopyAsElementsKind( |
3465 current_map, kind, INSERT_TRANSITION); | 3465 current_map, kind, INSERT_TRANSITION); |
3466 } | 3466 } |
3467 | 3467 |
3468 // In case we are exiting the fast elements kind system, just add the map in | 3468 // In case we are exiting the fast elements kind system, just add the map in |
3469 // the end. | 3469 // the end. |
3470 if (kind != to_kind) { | 3470 if (kind != to_kind) { |
3471 current_map = Map::CopyAsElementsKind( | 3471 current_map = Map::CopyAsElementsKind( |
3472 current_map, to_kind, INSERT_TRANSITION); | 3472 current_map, to_kind, INSERT_TRANSITION); |
3473 } | 3473 } |
3474 | 3474 |
3475 ASSERT(current_map->elements_kind() == to_kind); | 3475 DCHECK(current_map->elements_kind() == to_kind); |
3476 return current_map; | 3476 return current_map; |
3477 } | 3477 } |
3478 | 3478 |
3479 | 3479 |
3480 Handle<Map> Map::TransitionElementsTo(Handle<Map> map, | 3480 Handle<Map> Map::TransitionElementsTo(Handle<Map> map, |
3481 ElementsKind to_kind) { | 3481 ElementsKind to_kind) { |
3482 ElementsKind from_kind = map->elements_kind(); | 3482 ElementsKind from_kind = map->elements_kind(); |
3483 if (from_kind == to_kind) return map; | 3483 if (from_kind == to_kind) return map; |
3484 | 3484 |
3485 Isolate* isolate = map->GetIsolate(); | 3485 Isolate* isolate = map->GetIsolate(); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3547 return Map::TransitionElementsTo(map, to_kind); | 3547 return Map::TransitionElementsTo(map, to_kind); |
3548 } | 3548 } |
3549 | 3549 |
3550 | 3550 |
3551 void JSObject::LookupOwnRealNamedProperty(Handle<Name> name, | 3551 void JSObject::LookupOwnRealNamedProperty(Handle<Name> name, |
3552 LookupResult* result) { | 3552 LookupResult* result) { |
3553 DisallowHeapAllocation no_gc; | 3553 DisallowHeapAllocation no_gc; |
3554 if (IsJSGlobalProxy()) { | 3554 if (IsJSGlobalProxy()) { |
3555 PrototypeIterator iter(GetIsolate(), this); | 3555 PrototypeIterator iter(GetIsolate(), this); |
3556 if (iter.IsAtEnd()) return result->NotFound(); | 3556 if (iter.IsAtEnd()) return result->NotFound(); |
3557 ASSERT(iter.GetCurrent()->IsJSGlobalObject()); | 3557 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
3558 return JSObject::cast(iter.GetCurrent()) | 3558 return JSObject::cast(iter.GetCurrent()) |
3559 ->LookupOwnRealNamedProperty(name, result); | 3559 ->LookupOwnRealNamedProperty(name, result); |
3560 } | 3560 } |
3561 | 3561 |
3562 if (HasFastProperties()) { | 3562 if (HasFastProperties()) { |
3563 map()->LookupDescriptor(this, *name, result); | 3563 map()->LookupDescriptor(this, *name, result); |
3564 // A property or a map transition was found. We return all of these result | 3564 // A property or a map transition was found. We return all of these result |
3565 // types because LookupOwnRealNamedProperty is used when setting | 3565 // types because LookupOwnRealNamedProperty is used when setting |
3566 // properties where map transitions are handled. | 3566 // properties where map transitions are handled. |
3567 ASSERT(!result->IsFound() || | 3567 DCHECK(!result->IsFound() || |
3568 (result->holder() == this && result->IsFastPropertyType())); | 3568 (result->holder() == this && result->IsFastPropertyType())); |
3569 return; | 3569 return; |
3570 } | 3570 } |
3571 | 3571 |
3572 int entry = property_dictionary()->FindEntry(name); | 3572 int entry = property_dictionary()->FindEntry(name); |
3573 if (entry != NameDictionary::kNotFound) { | 3573 if (entry != NameDictionary::kNotFound) { |
3574 Object* value = property_dictionary()->ValueAt(entry); | 3574 Object* value = property_dictionary()->ValueAt(entry); |
3575 if (IsGlobalObject()) { | 3575 if (IsGlobalObject()) { |
3576 PropertyDetails d = property_dictionary()->DetailsAt(entry); | 3576 PropertyDetails d = property_dictionary()->DetailsAt(entry); |
3577 if (d.IsDeleted() || PropertyCell::cast(value)->value()->IsTheHole()) { | 3577 if (d.IsDeleted() || PropertyCell::cast(value)->value()->IsTheHole()) { |
(...skipping 22 matching lines...) Expand all Loading... |
3600 | 3600 |
3601 void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name, | 3601 void JSObject::LookupRealNamedPropertyInPrototypes(Handle<Name> name, |
3602 LookupResult* result) { | 3602 LookupResult* result) { |
3603 DisallowHeapAllocation no_gc; | 3603 DisallowHeapAllocation no_gc; |
3604 Isolate* isolate = GetIsolate(); | 3604 Isolate* isolate = GetIsolate(); |
3605 for (PrototypeIterator iter(isolate, this); !iter.IsAtEnd(); iter.Advance()) { | 3605 for (PrototypeIterator iter(isolate, this); !iter.IsAtEnd(); iter.Advance()) { |
3606 if (iter.GetCurrent()->IsJSProxy()) { | 3606 if (iter.GetCurrent()->IsJSProxy()) { |
3607 return result->HandlerResult(JSProxy::cast(iter.GetCurrent())); | 3607 return result->HandlerResult(JSProxy::cast(iter.GetCurrent())); |
3608 } | 3608 } |
3609 JSObject::cast(iter.GetCurrent())->LookupOwnRealNamedProperty(name, result); | 3609 JSObject::cast(iter.GetCurrent())->LookupOwnRealNamedProperty(name, result); |
3610 ASSERT(!(result->IsFound() && result->type() == INTERCEPTOR)); | 3610 DCHECK(!(result->IsFound() && result->type() == INTERCEPTOR)); |
3611 if (result->IsFound()) return; | 3611 if (result->IsFound()) return; |
3612 } | 3612 } |
3613 result->NotFound(); | 3613 result->NotFound(); |
3614 } | 3614 } |
3615 | 3615 |
3616 | 3616 |
3617 Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, | 3617 Maybe<bool> JSProxy::HasPropertyWithHandler(Handle<JSProxy> proxy, |
3618 Handle<Name> name) { | 3618 Handle<Name> name) { |
3619 Isolate* isolate = proxy->GetIsolate(); | 3619 Isolate* isolate = proxy->GetIsolate(); |
3620 | 3620 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3696 ARRAY_SIZE(argv), | 3696 ARRAY_SIZE(argv), |
3697 argv), | 3697 argv), |
3698 Object); | 3698 Object); |
3699 | 3699 |
3700 // [[GetProperty]] requires to check that all properties are configurable. | 3700 // [[GetProperty]] requires to check that all properties are configurable. |
3701 Handle<String> configurable_name = | 3701 Handle<String> configurable_name = |
3702 isolate->factory()->InternalizeOneByteString( | 3702 isolate->factory()->InternalizeOneByteString( |
3703 STATIC_ASCII_VECTOR("configurable_")); | 3703 STATIC_ASCII_VECTOR("configurable_")); |
3704 Handle<Object> configurable = | 3704 Handle<Object> configurable = |
3705 Object::GetProperty(desc, configurable_name).ToHandleChecked(); | 3705 Object::GetProperty(desc, configurable_name).ToHandleChecked(); |
3706 ASSERT(configurable->IsBoolean()); | 3706 DCHECK(configurable->IsBoolean()); |
3707 if (configurable->IsFalse()) { | 3707 if (configurable->IsFalse()) { |
3708 Handle<String> trap = | 3708 Handle<String> trap = |
3709 isolate->factory()->InternalizeOneByteString( | 3709 isolate->factory()->InternalizeOneByteString( |
3710 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 3710 STATIC_ASCII_VECTOR("getPropertyDescriptor")); |
3711 Handle<Object> args[] = { handler, trap, name }; | 3711 Handle<Object> args[] = { handler, trap, name }; |
3712 Handle<Object> error = isolate->factory()->NewTypeError( | 3712 Handle<Object> error = isolate->factory()->NewTypeError( |
3713 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | 3713 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); |
3714 return isolate->Throw<Object>(error); | 3714 return isolate->Throw<Object>(error); |
3715 } | 3715 } |
3716 ASSERT(configurable->IsTrue()); | 3716 DCHECK(configurable->IsTrue()); |
3717 | 3717 |
3718 // Check for DataDescriptor. | 3718 // Check for DataDescriptor. |
3719 Handle<String> hasWritable_name = | 3719 Handle<String> hasWritable_name = |
3720 isolate->factory()->InternalizeOneByteString( | 3720 isolate->factory()->InternalizeOneByteString( |
3721 STATIC_ASCII_VECTOR("hasWritable_")); | 3721 STATIC_ASCII_VECTOR("hasWritable_")); |
3722 Handle<Object> hasWritable = | 3722 Handle<Object> hasWritable = |
3723 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); | 3723 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); |
3724 ASSERT(hasWritable->IsBoolean()); | 3724 DCHECK(hasWritable->IsBoolean()); |
3725 if (hasWritable->IsTrue()) { | 3725 if (hasWritable->IsTrue()) { |
3726 Handle<String> writable_name = | 3726 Handle<String> writable_name = |
3727 isolate->factory()->InternalizeOneByteString( | 3727 isolate->factory()->InternalizeOneByteString( |
3728 STATIC_ASCII_VECTOR("writable_")); | 3728 STATIC_ASCII_VECTOR("writable_")); |
3729 Handle<Object> writable = | 3729 Handle<Object> writable = |
3730 Object::GetProperty(desc, writable_name).ToHandleChecked(); | 3730 Object::GetProperty(desc, writable_name).ToHandleChecked(); |
3731 ASSERT(writable->IsBoolean()); | 3731 DCHECK(writable->IsBoolean()); |
3732 *done = writable->IsFalse(); | 3732 *done = writable->IsFalse(); |
3733 if (!*done) return isolate->factory()->the_hole_value(); | 3733 if (!*done) return isolate->factory()->the_hole_value(); |
3734 if (strict_mode == SLOPPY) return value; | 3734 if (strict_mode == SLOPPY) return value; |
3735 Handle<Object> args[] = { name, receiver }; | 3735 Handle<Object> args[] = { name, receiver }; |
3736 Handle<Object> error = isolate->factory()->NewTypeError( | 3736 Handle<Object> error = isolate->factory()->NewTypeError( |
3737 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 3737 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
3738 return isolate->Throw<Object>(error); | 3738 return isolate->Throw<Object>(error); |
3739 } | 3739 } |
3740 | 3740 |
3741 // We have an AccessorDescriptor. | 3741 // We have an AccessorDescriptor. |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3883 | 3883 |
3884 // Save identity hash. | 3884 // Save identity hash. |
3885 Handle<Object> hash(proxy->GetIdentityHash(), isolate); | 3885 Handle<Object> hash(proxy->GetIdentityHash(), isolate); |
3886 | 3886 |
3887 if (proxy->IsJSFunctionProxy()) { | 3887 if (proxy->IsJSFunctionProxy()) { |
3888 isolate->factory()->BecomeJSFunction(proxy); | 3888 isolate->factory()->BecomeJSFunction(proxy); |
3889 // Code will be set on the JavaScript side. | 3889 // Code will be set on the JavaScript side. |
3890 } else { | 3890 } else { |
3891 isolate->factory()->BecomeJSObject(proxy); | 3891 isolate->factory()->BecomeJSObject(proxy); |
3892 } | 3892 } |
3893 ASSERT(proxy->IsJSObject()); | 3893 DCHECK(proxy->IsJSObject()); |
3894 | 3894 |
3895 // Inherit identity, if it was present. | 3895 // Inherit identity, if it was present. |
3896 if (hash->IsSmi()) { | 3896 if (hash->IsSmi()) { |
3897 JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy), | 3897 JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy), |
3898 Handle<Smi>::cast(hash)); | 3898 Handle<Smi>::cast(hash)); |
3899 } | 3899 } |
3900 } | 3900 } |
3901 | 3901 |
3902 | 3902 |
3903 MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, | 3903 MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, |
(...skipping 19 matching lines...) Expand all Loading... |
3923 return isolate->Throw<Object>(error); | 3923 return isolate->Throw<Object>(error); |
3924 } | 3924 } |
3925 trap = Handle<Object>(derived); | 3925 trap = Handle<Object>(derived); |
3926 } | 3926 } |
3927 | 3927 |
3928 return Execution::Call(isolate, trap, handler, argc, argv); | 3928 return Execution::Call(isolate, trap, handler, argc, argv); |
3929 } | 3929 } |
3930 | 3930 |
3931 | 3931 |
3932 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { | 3932 void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) { |
3933 ASSERT(object->map()->inobject_properties() == map->inobject_properties()); | 3933 DCHECK(object->map()->inobject_properties() == map->inobject_properties()); |
3934 ElementsKind obj_kind = object->map()->elements_kind(); | 3934 ElementsKind obj_kind = object->map()->elements_kind(); |
3935 ElementsKind map_kind = map->elements_kind(); | 3935 ElementsKind map_kind = map->elements_kind(); |
3936 if (map_kind != obj_kind) { | 3936 if (map_kind != obj_kind) { |
3937 ElementsKind to_kind = map_kind; | 3937 ElementsKind to_kind = map_kind; |
3938 if (IsMoreGeneralElementsKindTransition(map_kind, obj_kind) || | 3938 if (IsMoreGeneralElementsKindTransition(map_kind, obj_kind) || |
3939 IsDictionaryElementsKind(obj_kind)) { | 3939 IsDictionaryElementsKind(obj_kind)) { |
3940 to_kind = obj_kind; | 3940 to_kind = obj_kind; |
3941 } | 3941 } |
3942 if (IsDictionaryElementsKind(to_kind)) { | 3942 if (IsDictionaryElementsKind(to_kind)) { |
3943 NormalizeElements(object); | 3943 NormalizeElements(object); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4025 object->WriteToField(map->LastAdded(), *value); | 4025 object->WriteToField(map->LastAdded(), *value); |
4026 } | 4026 } |
4027 | 4027 |
4028 | 4028 |
4029 void JSObject::WriteToField(int descriptor, Object* value) { | 4029 void JSObject::WriteToField(int descriptor, Object* value) { |
4030 DisallowHeapAllocation no_gc; | 4030 DisallowHeapAllocation no_gc; |
4031 | 4031 |
4032 DescriptorArray* desc = map()->instance_descriptors(); | 4032 DescriptorArray* desc = map()->instance_descriptors(); |
4033 PropertyDetails details = desc->GetDetails(descriptor); | 4033 PropertyDetails details = desc->GetDetails(descriptor); |
4034 | 4034 |
4035 ASSERT(details.type() == FIELD); | 4035 DCHECK(details.type() == FIELD); |
4036 | 4036 |
4037 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); | 4037 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); |
4038 if (details.representation().IsDouble()) { | 4038 if (details.representation().IsDouble()) { |
4039 // Nothing more to be done. | 4039 // Nothing more to be done. |
4040 if (value->IsUninitialized()) return; | 4040 if (value->IsUninitialized()) return; |
4041 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); | 4041 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); |
4042 ASSERT(box->IsMutableHeapNumber()); | 4042 DCHECK(box->IsMutableHeapNumber()); |
4043 box->set_value(value->Number()); | 4043 box->set_value(value->Number()); |
4044 } else { | 4044 } else { |
4045 FastPropertyAtPut(index, value); | 4045 FastPropertyAtPut(index, value); |
4046 } | 4046 } |
4047 } | 4047 } |
4048 | 4048 |
4049 | 4049 |
4050 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { | 4050 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { |
4051 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { | 4051 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { |
4052 Representation field_representation = value->OptimalRepresentation(); | 4052 Representation field_representation = value->OptimalRepresentation(); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4101 ConvertAndSetOwnProperty(lookup, name, value, attributes); | 4101 ConvertAndSetOwnProperty(lookup, name, value, attributes); |
4102 } | 4102 } |
4103 } | 4103 } |
4104 | 4104 |
4105 | 4105 |
4106 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, | 4106 void JSObject::AddProperty(Handle<JSObject> object, Handle<Name> name, |
4107 Handle<Object> value, | 4107 Handle<Object> value, |
4108 PropertyAttributes attributes) { | 4108 PropertyAttributes attributes) { |
4109 #ifdef DEBUG | 4109 #ifdef DEBUG |
4110 uint32_t index; | 4110 uint32_t index; |
4111 ASSERT(!object->IsJSProxy()); | 4111 DCHECK(!object->IsJSProxy()); |
4112 ASSERT(!name->AsArrayIndex(&index)); | 4112 DCHECK(!name->AsArrayIndex(&index)); |
4113 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); | 4113 LookupIterator it(object, name, LookupIterator::CHECK_OWN_REAL); |
4114 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it); | 4114 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it); |
4115 ASSERT(maybe.has_value); | 4115 DCHECK(maybe.has_value); |
4116 ASSERT(!it.IsFound()); | 4116 DCHECK(!it.IsFound()); |
4117 ASSERT(object->map()->is_extensible()); | 4117 DCHECK(object->map()->is_extensible()); |
4118 #endif | 4118 #endif |
4119 SetOwnPropertyIgnoreAttributes(object, name, value, attributes, | 4119 SetOwnPropertyIgnoreAttributes(object, name, value, attributes, |
4120 OMIT_EXTENSIBILITY_CHECK).Check(); | 4120 OMIT_EXTENSIBILITY_CHECK).Check(); |
4121 } | 4121 } |
4122 | 4122 |
4123 | 4123 |
4124 // Reconfigures a property to a data property with attributes, even if it is not | 4124 // Reconfigures a property to a data property with attributes, even if it is not |
4125 // reconfigurable. | 4125 // reconfigurable. |
4126 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( | 4126 MaybeHandle<Object> JSObject::SetOwnPropertyIgnoreAttributes( |
4127 Handle<JSObject> object, | 4127 Handle<JSObject> object, |
4128 Handle<Name> name, | 4128 Handle<Name> name, |
4129 Handle<Object> value, | 4129 Handle<Object> value, |
4130 PropertyAttributes attributes, | 4130 PropertyAttributes attributes, |
4131 ExtensibilityCheck extensibility_check, | 4131 ExtensibilityCheck extensibility_check, |
4132 StoreFromKeyed store_from_keyed, | 4132 StoreFromKeyed store_from_keyed, |
4133 ExecutableAccessorInfoHandling handling) { | 4133 ExecutableAccessorInfoHandling handling) { |
4134 ASSERT(!value->IsTheHole()); | 4134 DCHECK(!value->IsTheHole()); |
4135 Isolate* isolate = object->GetIsolate(); | 4135 Isolate* isolate = object->GetIsolate(); |
4136 | 4136 |
4137 // Make sure that the top context does not change when doing callbacks or | 4137 // Make sure that the top context does not change when doing callbacks or |
4138 // interceptor calls. | 4138 // interceptor calls. |
4139 AssertNoContextChange ncc(isolate); | 4139 AssertNoContextChange ncc(isolate); |
4140 | 4140 |
4141 LookupResult lookup(isolate); | 4141 LookupResult lookup(isolate); |
4142 object->LookupOwn(name, &lookup, true); | 4142 object->LookupOwn(name, &lookup, true); |
4143 if (!lookup.IsFound()) { | 4143 if (!lookup.IsFound()) { |
4144 object->map()->LookupTransition(*object, *name, &lookup); | 4144 object->map()->LookupTransition(*object, *name, &lookup); |
4145 } | 4145 } |
4146 | 4146 |
4147 // Check access rights if needed. | 4147 // Check access rights if needed. |
4148 if (object->IsAccessCheckNeeded()) { | 4148 if (object->IsAccessCheckNeeded()) { |
4149 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 4149 if (!isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
4150 LookupIterator it(object, name, LookupIterator::CHECK_OWN); | 4150 LookupIterator it(object, name, LookupIterator::CHECK_OWN); |
4151 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); | 4151 return SetPropertyWithFailedAccessCheck(&it, value, SLOPPY); |
4152 } | 4152 } |
4153 } | 4153 } |
4154 | 4154 |
4155 if (object->IsJSGlobalProxy()) { | 4155 if (object->IsJSGlobalProxy()) { |
4156 PrototypeIterator iter(isolate, object); | 4156 PrototypeIterator iter(isolate, object); |
4157 if (iter.IsAtEnd()) return value; | 4157 if (iter.IsAtEnd()) return value; |
4158 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 4158 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
4159 return SetOwnPropertyIgnoreAttributes( | 4159 return SetOwnPropertyIgnoreAttributes( |
4160 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), name, | 4160 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), name, |
4161 value, attributes, extensibility_check); | 4161 value, attributes, extensibility_check); |
4162 } | 4162 } |
4163 | 4163 |
4164 if (lookup.IsInterceptor() || | 4164 if (lookup.IsInterceptor() || |
4165 (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) { | 4165 (lookup.IsDescriptorOrDictionary() && lookup.type() == CALLBACKS)) { |
4166 object->LookupOwnRealNamedProperty(name, &lookup); | 4166 object->LookupOwnRealNamedProperty(name, &lookup); |
4167 } | 4167 } |
4168 | 4168 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4303 PropertyCallbackArguments args( | 4303 PropertyCallbackArguments args( |
4304 isolate, interceptor->data(), *receiver, *holder); | 4304 isolate, interceptor->data(), *receiver, *holder); |
4305 if (!interceptor->query()->IsUndefined()) { | 4305 if (!interceptor->query()->IsUndefined()) { |
4306 v8::NamedPropertyQueryCallback query = | 4306 v8::NamedPropertyQueryCallback query = |
4307 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query()); | 4307 v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query()); |
4308 LOG(isolate, | 4308 LOG(isolate, |
4309 ApiNamedPropertyAccess("interceptor-named-has", *holder, *name)); | 4309 ApiNamedPropertyAccess("interceptor-named-has", *holder, *name)); |
4310 v8::Handle<v8::Integer> result = | 4310 v8::Handle<v8::Integer> result = |
4311 args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name))); | 4311 args.Call(query, v8::Utils::ToLocal(Handle<String>::cast(name))); |
4312 if (!result.IsEmpty()) { | 4312 if (!result.IsEmpty()) { |
4313 ASSERT(result->IsInt32()); | 4313 DCHECK(result->IsInt32()); |
4314 return maybe(static_cast<PropertyAttributes>(result->Int32Value())); | 4314 return maybe(static_cast<PropertyAttributes>(result->Int32Value())); |
4315 } | 4315 } |
4316 } else if (!interceptor->getter()->IsUndefined()) { | 4316 } else if (!interceptor->getter()->IsUndefined()) { |
4317 v8::NamedPropertyGetterCallback getter = | 4317 v8::NamedPropertyGetterCallback getter = |
4318 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); | 4318 v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter()); |
4319 LOG(isolate, | 4319 LOG(isolate, |
4320 ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name)); | 4320 ApiNamedPropertyAccess("interceptor-named-get-has", *holder, *name)); |
4321 v8::Handle<v8::Value> result = | 4321 v8::Handle<v8::Value> result = |
4322 args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name))); | 4322 args.Call(getter, v8::Utils::ToLocal(Handle<String>::cast(name))); |
4323 if (!result.IsEmpty()) return maybe(DONT_ENUM); | 4323 if (!result.IsEmpty()) return maybe(DONT_ENUM); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4381 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { | 4381 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_HAS)) { |
4382 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); | 4382 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); |
4383 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>()); | 4383 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<PropertyAttributes>()); |
4384 return maybe(ABSENT); | 4384 return maybe(ABSENT); |
4385 } | 4385 } |
4386 } | 4386 } |
4387 | 4387 |
4388 if (object->IsJSGlobalProxy()) { | 4388 if (object->IsJSGlobalProxy()) { |
4389 PrototypeIterator iter(isolate, object); | 4389 PrototypeIterator iter(isolate, object); |
4390 if (iter.IsAtEnd()) return maybe(ABSENT); | 4390 if (iter.IsAtEnd()) return maybe(ABSENT); |
4391 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 4391 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
4392 return JSObject::GetElementAttributeWithReceiver( | 4392 return JSObject::GetElementAttributeWithReceiver( |
4393 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver, | 4393 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), receiver, |
4394 index, check_prototype); | 4394 index, check_prototype); |
4395 } | 4395 } |
4396 | 4396 |
4397 // Check for lookup interceptor except when bootstrapping. | 4397 // Check for lookup interceptor except when bootstrapping. |
4398 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { | 4398 if (object->HasIndexedInterceptor() && !isolate->bootstrapper()->IsActive()) { |
4399 return JSObject::GetElementAttributeWithInterceptor( | 4399 return JSObject::GetElementAttributeWithInterceptor( |
4400 object, receiver, index, check_prototype); | 4400 object, receiver, index, check_prototype); |
4401 } | 4401 } |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4484 !Map::cast(value)->EquivalentToForNormalization(*fast_map, mode)) { | 4484 !Map::cast(value)->EquivalentToForNormalization(*fast_map, mode)) { |
4485 return MaybeHandle<Map>(); | 4485 return MaybeHandle<Map>(); |
4486 } | 4486 } |
4487 return handle(Map::cast(value)); | 4487 return handle(Map::cast(value)); |
4488 } | 4488 } |
4489 | 4489 |
4490 | 4490 |
4491 void NormalizedMapCache::Set(Handle<Map> fast_map, | 4491 void NormalizedMapCache::Set(Handle<Map> fast_map, |
4492 Handle<Map> normalized_map) { | 4492 Handle<Map> normalized_map) { |
4493 DisallowHeapAllocation no_gc; | 4493 DisallowHeapAllocation no_gc; |
4494 ASSERT(normalized_map->is_dictionary_map()); | 4494 DCHECK(normalized_map->is_dictionary_map()); |
4495 FixedArray::set(GetIndex(fast_map), *normalized_map); | 4495 FixedArray::set(GetIndex(fast_map), *normalized_map); |
4496 } | 4496 } |
4497 | 4497 |
4498 | 4498 |
4499 void NormalizedMapCache::Clear() { | 4499 void NormalizedMapCache::Clear() { |
4500 int entries = length(); | 4500 int entries = length(); |
4501 for (int i = 0; i != entries; i++) { | 4501 for (int i = 0; i != entries; i++) { |
4502 set_undefined(i); | 4502 set_undefined(i); |
4503 } | 4503 } |
4504 } | 4504 } |
(...skipping 16 matching lines...) Expand all Loading... |
4521 Handle<Map> new_map = Map::Normalize(map, mode); | 4521 Handle<Map> new_map = Map::Normalize(map, mode); |
4522 | 4522 |
4523 MigrateFastToSlow(object, new_map, expected_additional_properties); | 4523 MigrateFastToSlow(object, new_map, expected_additional_properties); |
4524 } | 4524 } |
4525 | 4525 |
4526 | 4526 |
4527 void JSObject::MigrateFastToSlow(Handle<JSObject> object, | 4527 void JSObject::MigrateFastToSlow(Handle<JSObject> object, |
4528 Handle<Map> new_map, | 4528 Handle<Map> new_map, |
4529 int expected_additional_properties) { | 4529 int expected_additional_properties) { |
4530 // The global object is always normalized. | 4530 // The global object is always normalized. |
4531 ASSERT(!object->IsGlobalObject()); | 4531 DCHECK(!object->IsGlobalObject()); |
4532 // JSGlobalProxy must never be normalized | 4532 // JSGlobalProxy must never be normalized |
4533 ASSERT(!object->IsJSGlobalProxy()); | 4533 DCHECK(!object->IsJSGlobalProxy()); |
4534 | 4534 |
4535 Isolate* isolate = object->GetIsolate(); | 4535 Isolate* isolate = object->GetIsolate(); |
4536 HandleScope scope(isolate); | 4536 HandleScope scope(isolate); |
4537 Handle<Map> map(object->map()); | 4537 Handle<Map> map(object->map()); |
4538 | 4538 |
4539 // Allocate new content. | 4539 // Allocate new content. |
4540 int real_size = map->NumberOfOwnDescriptors(); | 4540 int real_size = map->NumberOfOwnDescriptors(); |
4541 int property_count = real_size; | 4541 int property_count = real_size; |
4542 if (expected_additional_properties > 0) { | 4542 if (expected_additional_properties > 0) { |
4543 property_count += expected_additional_properties; | 4543 property_count += expected_additional_properties; |
(...skipping 14 matching lines...) Expand all Loading... |
4558 details.attributes(), NORMAL, i + 1); | 4558 details.attributes(), NORMAL, i + 1); |
4559 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4559 dictionary = NameDictionary::Add(dictionary, key, value, d); |
4560 break; | 4560 break; |
4561 } | 4561 } |
4562 case FIELD: { | 4562 case FIELD: { |
4563 Handle<Name> key(descs->GetKey(i)); | 4563 Handle<Name> key(descs->GetKey(i)); |
4564 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 4564 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
4565 Handle<Object> value( | 4565 Handle<Object> value( |
4566 object->RawFastPropertyAt(index), isolate); | 4566 object->RawFastPropertyAt(index), isolate); |
4567 if (details.representation().IsDouble()) { | 4567 if (details.representation().IsDouble()) { |
4568 ASSERT(value->IsMutableHeapNumber()); | 4568 DCHECK(value->IsMutableHeapNumber()); |
4569 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); | 4569 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); |
4570 value = isolate->factory()->NewHeapNumber(old->value()); | 4570 value = isolate->factory()->NewHeapNumber(old->value()); |
4571 } | 4571 } |
4572 PropertyDetails d = | 4572 PropertyDetails d = |
4573 PropertyDetails(details.attributes(), NORMAL, i + 1); | 4573 PropertyDetails(details.attributes(), NORMAL, i + 1); |
4574 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4574 dictionary = NameDictionary::Add(dictionary, key, value, d); |
4575 break; | 4575 break; |
4576 } | 4576 } |
4577 case CALLBACKS: { | 4577 case CALLBACKS: { |
4578 Handle<Name> key(descs->GetKey(i)); | 4578 Handle<Name> key(descs->GetKey(i)); |
(...skipping 15 matching lines...) Expand all Loading... |
4594 | 4594 |
4595 // Copy the next enumeration index from instance descriptor. | 4595 // Copy the next enumeration index from instance descriptor. |
4596 dictionary->SetNextEnumerationIndex(real_size + 1); | 4596 dictionary->SetNextEnumerationIndex(real_size + 1); |
4597 | 4597 |
4598 // From here on we cannot fail and we shouldn't GC anymore. | 4598 // From here on we cannot fail and we shouldn't GC anymore. |
4599 DisallowHeapAllocation no_allocation; | 4599 DisallowHeapAllocation no_allocation; |
4600 | 4600 |
4601 // Resize the object in the heap if necessary. | 4601 // Resize the object in the heap if necessary. |
4602 int new_instance_size = new_map->instance_size(); | 4602 int new_instance_size = new_map->instance_size(); |
4603 int instance_size_delta = map->instance_size() - new_instance_size; | 4603 int instance_size_delta = map->instance_size() - new_instance_size; |
4604 ASSERT(instance_size_delta >= 0); | 4604 DCHECK(instance_size_delta >= 0); |
4605 | 4605 |
4606 if (instance_size_delta > 0) { | 4606 if (instance_size_delta > 0) { |
4607 Heap* heap = isolate->heap(); | 4607 Heap* heap = isolate->heap(); |
4608 heap->CreateFillerObjectAt(object->address() + new_instance_size, | 4608 heap->CreateFillerObjectAt(object->address() + new_instance_size, |
4609 instance_size_delta); | 4609 instance_size_delta); |
4610 heap->AdjustLiveBytes(object->address(), -instance_size_delta, | 4610 heap->AdjustLiveBytes(object->address(), -instance_size_delta, |
4611 Heap::FROM_MUTATOR); | 4611 Heap::FROM_MUTATOR); |
4612 } | 4612 } |
4613 | 4613 |
4614 // We are storing the new map using release store after creating a filler for | 4614 // We are storing the new map using release store after creating a filler for |
(...skipping 10 matching lines...) Expand all Loading... |
4625 os << "Object properties have been normalized:\n"; | 4625 os << "Object properties have been normalized:\n"; |
4626 object->Print(os); | 4626 object->Print(os); |
4627 } | 4627 } |
4628 #endif | 4628 #endif |
4629 } | 4629 } |
4630 | 4630 |
4631 | 4631 |
4632 void JSObject::MigrateSlowToFast(Handle<JSObject> object, | 4632 void JSObject::MigrateSlowToFast(Handle<JSObject> object, |
4633 int unused_property_fields) { | 4633 int unused_property_fields) { |
4634 if (object->HasFastProperties()) return; | 4634 if (object->HasFastProperties()) return; |
4635 ASSERT(!object->IsGlobalObject()); | 4635 DCHECK(!object->IsGlobalObject()); |
4636 Isolate* isolate = object->GetIsolate(); | 4636 Isolate* isolate = object->GetIsolate(); |
4637 Factory* factory = isolate->factory(); | 4637 Factory* factory = isolate->factory(); |
4638 Handle<NameDictionary> dictionary(object->property_dictionary()); | 4638 Handle<NameDictionary> dictionary(object->property_dictionary()); |
4639 | 4639 |
4640 // Make sure we preserve dictionary representation if there are too many | 4640 // Make sure we preserve dictionary representation if there are too many |
4641 // descriptors. | 4641 // descriptors. |
4642 int number_of_elements = dictionary->NumberOfElements(); | 4642 int number_of_elements = dictionary->NumberOfElements(); |
4643 if (number_of_elements > kMaxNumberOfDescriptors) return; | 4643 if (number_of_elements > kMaxNumberOfDescriptors) return; |
4644 | 4644 |
4645 if (number_of_elements != dictionary->NextEnumerationIndex()) { | 4645 if (number_of_elements != dictionary->NextEnumerationIndex()) { |
4646 NameDictionary::DoGenerateNewEnumerationIndices(dictionary); | 4646 NameDictionary::DoGenerateNewEnumerationIndices(dictionary); |
4647 } | 4647 } |
4648 | 4648 |
4649 int instance_descriptor_length = 0; | 4649 int instance_descriptor_length = 0; |
4650 int number_of_fields = 0; | 4650 int number_of_fields = 0; |
4651 | 4651 |
4652 // Compute the length of the instance descriptor. | 4652 // Compute the length of the instance descriptor. |
4653 int capacity = dictionary->Capacity(); | 4653 int capacity = dictionary->Capacity(); |
4654 for (int i = 0; i < capacity; i++) { | 4654 for (int i = 0; i < capacity; i++) { |
4655 Object* k = dictionary->KeyAt(i); | 4655 Object* k = dictionary->KeyAt(i); |
4656 if (dictionary->IsKey(k)) { | 4656 if (dictionary->IsKey(k)) { |
4657 Object* value = dictionary->ValueAt(i); | 4657 Object* value = dictionary->ValueAt(i); |
4658 PropertyType type = dictionary->DetailsAt(i).type(); | 4658 PropertyType type = dictionary->DetailsAt(i).type(); |
4659 ASSERT(type != FIELD); | 4659 DCHECK(type != FIELD); |
4660 instance_descriptor_length++; | 4660 instance_descriptor_length++; |
4661 if (type == NORMAL && !value->IsJSFunction()) { | 4661 if (type == NORMAL && !value->IsJSFunction()) { |
4662 number_of_fields += 1; | 4662 number_of_fields += 1; |
4663 } | 4663 } |
4664 } | 4664 } |
4665 } | 4665 } |
4666 | 4666 |
4667 int inobject_props = object->map()->inobject_properties(); | 4667 int inobject_props = object->map()->inobject_properties(); |
4668 | 4668 |
4669 // Allocate new map. | 4669 // Allocate new map. |
4670 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 4670 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
4671 new_map->set_dictionary_map(false); | 4671 new_map->set_dictionary_map(false); |
4672 | 4672 |
4673 if (instance_descriptor_length == 0) { | 4673 if (instance_descriptor_length == 0) { |
4674 DisallowHeapAllocation no_gc; | 4674 DisallowHeapAllocation no_gc; |
4675 ASSERT_LE(unused_property_fields, inobject_props); | 4675 DCHECK_LE(unused_property_fields, inobject_props); |
4676 // Transform the object. | 4676 // Transform the object. |
4677 new_map->set_unused_property_fields(inobject_props); | 4677 new_map->set_unused_property_fields(inobject_props); |
4678 object->synchronized_set_map(*new_map); | 4678 object->synchronized_set_map(*new_map); |
4679 object->set_properties(isolate->heap()->empty_fixed_array()); | 4679 object->set_properties(isolate->heap()->empty_fixed_array()); |
4680 // Check that it really works. | 4680 // Check that it really works. |
4681 ASSERT(object->HasFastProperties()); | 4681 DCHECK(object->HasFastProperties()); |
4682 return; | 4682 return; |
4683 } | 4683 } |
4684 | 4684 |
4685 // Allocate the instance descriptor. | 4685 // Allocate the instance descriptor. |
4686 Handle<DescriptorArray> descriptors = DescriptorArray::Allocate( | 4686 Handle<DescriptorArray> descriptors = DescriptorArray::Allocate( |
4687 isolate, instance_descriptor_length); | 4687 isolate, instance_descriptor_length); |
4688 | 4688 |
4689 int number_of_allocated_fields = | 4689 int number_of_allocated_fields = |
4690 number_of_fields + unused_property_fields - inobject_props; | 4690 number_of_fields + unused_property_fields - inobject_props; |
4691 if (number_of_allocated_fields < 0) { | 4691 if (number_of_allocated_fields < 0) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4740 } else if (type == CALLBACKS) { | 4740 } else if (type == CALLBACKS) { |
4741 CallbacksDescriptor d(key, | 4741 CallbacksDescriptor d(key, |
4742 handle(value, isolate), | 4742 handle(value, isolate), |
4743 details.attributes()); | 4743 details.attributes()); |
4744 descriptors->Set(enumeration_index - 1, &d); | 4744 descriptors->Set(enumeration_index - 1, &d); |
4745 } else { | 4745 } else { |
4746 UNREACHABLE(); | 4746 UNREACHABLE(); |
4747 } | 4747 } |
4748 } | 4748 } |
4749 } | 4749 } |
4750 ASSERT(current_offset == number_of_fields); | 4750 DCHECK(current_offset == number_of_fields); |
4751 | 4751 |
4752 descriptors->Sort(); | 4752 descriptors->Sort(); |
4753 | 4753 |
4754 DisallowHeapAllocation no_gc; | 4754 DisallowHeapAllocation no_gc; |
4755 new_map->InitializeDescriptors(*descriptors); | 4755 new_map->InitializeDescriptors(*descriptors); |
4756 new_map->set_unused_property_fields(unused_property_fields); | 4756 new_map->set_unused_property_fields(unused_property_fields); |
4757 | 4757 |
4758 // Transform the object. | 4758 // Transform the object. |
4759 object->synchronized_set_map(*new_map); | 4759 object->synchronized_set_map(*new_map); |
4760 | 4760 |
4761 object->set_properties(*fields); | 4761 object->set_properties(*fields); |
4762 ASSERT(object->IsJSObject()); | 4762 DCHECK(object->IsJSObject()); |
4763 | 4763 |
4764 // Check that it really works. | 4764 // Check that it really works. |
4765 ASSERT(object->HasFastProperties()); | 4765 DCHECK(object->HasFastProperties()); |
4766 } | 4766 } |
4767 | 4767 |
4768 | 4768 |
4769 void JSObject::ResetElements(Handle<JSObject> object) { | 4769 void JSObject::ResetElements(Handle<JSObject> object) { |
4770 Heap* heap = object->GetIsolate()->heap(); | 4770 Heap* heap = object->GetIsolate()->heap(); |
4771 CHECK(object->map() != heap->sloppy_arguments_elements_map()); | 4771 CHECK(object->map() != heap->sloppy_arguments_elements_map()); |
4772 object->set_elements(object->map()->GetInitialElements()); | 4772 object->set_elements(object->map()->GetInitialElements()); |
4773 } | 4773 } |
4774 | 4774 |
4775 | 4775 |
(...skipping 22 matching lines...) Expand all Loading... |
4798 dictionary = | 4798 dictionary = |
4799 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); | 4799 SeededNumberDictionary::AddNumberEntry(dictionary, i, value, details); |
4800 } | 4800 } |
4801 } | 4801 } |
4802 return dictionary; | 4802 return dictionary; |
4803 } | 4803 } |
4804 | 4804 |
4805 | 4805 |
4806 Handle<SeededNumberDictionary> JSObject::NormalizeElements( | 4806 Handle<SeededNumberDictionary> JSObject::NormalizeElements( |
4807 Handle<JSObject> object) { | 4807 Handle<JSObject> object) { |
4808 ASSERT(!object->HasExternalArrayElements() && | 4808 DCHECK(!object->HasExternalArrayElements() && |
4809 !object->HasFixedTypedArrayElements()); | 4809 !object->HasFixedTypedArrayElements()); |
4810 Isolate* isolate = object->GetIsolate(); | 4810 Isolate* isolate = object->GetIsolate(); |
4811 | 4811 |
4812 // Find the backing store. | 4812 // Find the backing store. |
4813 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); | 4813 Handle<FixedArrayBase> array(FixedArrayBase::cast(object->elements())); |
4814 bool is_arguments = | 4814 bool is_arguments = |
4815 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); | 4815 (array->map() == isolate->heap()->sloppy_arguments_elements_map()); |
4816 if (is_arguments) { | 4816 if (is_arguments) { |
4817 array = handle(FixedArrayBase::cast( | 4817 array = handle(FixedArrayBase::cast( |
4818 Handle<FixedArray>::cast(array)->get(1))); | 4818 Handle<FixedArray>::cast(array)->get(1))); |
4819 } | 4819 } |
4820 if (array->IsDictionary()) return Handle<SeededNumberDictionary>::cast(array); | 4820 if (array->IsDictionary()) return Handle<SeededNumberDictionary>::cast(array); |
4821 | 4821 |
4822 ASSERT(object->HasFastSmiOrObjectElements() || | 4822 DCHECK(object->HasFastSmiOrObjectElements() || |
4823 object->HasFastDoubleElements() || | 4823 object->HasFastDoubleElements() || |
4824 object->HasFastArgumentsElements()); | 4824 object->HasFastArgumentsElements()); |
4825 // Compute the effective length and allocate a new backing store. | 4825 // Compute the effective length and allocate a new backing store. |
4826 int length = object->IsJSArray() | 4826 int length = object->IsJSArray() |
4827 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() | 4827 ? Smi::cast(Handle<JSArray>::cast(object)->length())->value() |
4828 : array->length(); | 4828 : array->length(); |
4829 int old_capacity = 0; | 4829 int old_capacity = 0; |
4830 int used_elements = 0; | 4830 int used_elements = 0; |
4831 object->GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 4831 object->GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
4832 Handle<SeededNumberDictionary> dictionary = | 4832 Handle<SeededNumberDictionary> dictionary = |
(...skipping 17 matching lines...) Expand all Loading... |
4850 isolate->counters()->elements_to_dictionary()->Increment(); | 4850 isolate->counters()->elements_to_dictionary()->Increment(); |
4851 | 4851 |
4852 #ifdef DEBUG | 4852 #ifdef DEBUG |
4853 if (FLAG_trace_normalization) { | 4853 if (FLAG_trace_normalization) { |
4854 OFStream os(stdout); | 4854 OFStream os(stdout); |
4855 os << "Object elements have been normalized:\n"; | 4855 os << "Object elements have been normalized:\n"; |
4856 object->Print(os); | 4856 object->Print(os); |
4857 } | 4857 } |
4858 #endif | 4858 #endif |
4859 | 4859 |
4860 ASSERT(object->HasDictionaryElements() || | 4860 DCHECK(object->HasDictionaryElements() || |
4861 object->HasDictionaryArgumentsElements()); | 4861 object->HasDictionaryArgumentsElements()); |
4862 return dictionary; | 4862 return dictionary; |
4863 } | 4863 } |
4864 | 4864 |
4865 | 4865 |
4866 static Smi* GenerateIdentityHash(Isolate* isolate) { | 4866 static Smi* GenerateIdentityHash(Isolate* isolate) { |
4867 int hash_value; | 4867 int hash_value; |
4868 int attempts = 0; | 4868 int attempts = 0; |
4869 do { | 4869 do { |
4870 // Generate a random 32-bit hash value but limit range to fit | 4870 // Generate a random 32-bit hash value but limit range to fit |
4871 // within a smi. | 4871 // within a smi. |
4872 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; | 4872 hash_value = isolate->random_number_generator()->NextInt() & Smi::kMaxValue; |
4873 attempts++; | 4873 attempts++; |
4874 } while (hash_value == 0 && attempts < 30); | 4874 } while (hash_value == 0 && attempts < 30); |
4875 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 | 4875 hash_value = hash_value != 0 ? hash_value : 1; // never return 0 |
4876 | 4876 |
4877 return Smi::FromInt(hash_value); | 4877 return Smi::FromInt(hash_value); |
4878 } | 4878 } |
4879 | 4879 |
4880 | 4880 |
4881 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { | 4881 void JSObject::SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash) { |
4882 ASSERT(!object->IsJSGlobalProxy()); | 4882 DCHECK(!object->IsJSGlobalProxy()); |
4883 Isolate* isolate = object->GetIsolate(); | 4883 Isolate* isolate = object->GetIsolate(); |
4884 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); | 4884 SetHiddenProperty(object, isolate->factory()->identity_hash_string(), hash); |
4885 } | 4885 } |
4886 | 4886 |
4887 | 4887 |
4888 template<typename ProxyType> | 4888 template<typename ProxyType> |
4889 static Handle<Smi> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) { | 4889 static Handle<Smi> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) { |
4890 Isolate* isolate = proxy->GetIsolate(); | 4890 Isolate* isolate = proxy->GetIsolate(); |
4891 | 4891 |
4892 Handle<Object> maybe_hash(proxy->hash(), isolate); | 4892 Handle<Object> maybe_hash(proxy->hash(), isolate); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4933 } | 4933 } |
4934 | 4934 |
4935 | 4935 |
4936 Handle<Smi> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { | 4936 Handle<Smi> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) { |
4937 return GetOrCreateIdentityHashHelper(proxy); | 4937 return GetOrCreateIdentityHashHelper(proxy); |
4938 } | 4938 } |
4939 | 4939 |
4940 | 4940 |
4941 Object* JSObject::GetHiddenProperty(Handle<Name> key) { | 4941 Object* JSObject::GetHiddenProperty(Handle<Name> key) { |
4942 DisallowHeapAllocation no_gc; | 4942 DisallowHeapAllocation no_gc; |
4943 ASSERT(key->IsUniqueName()); | 4943 DCHECK(key->IsUniqueName()); |
4944 if (IsJSGlobalProxy()) { | 4944 if (IsJSGlobalProxy()) { |
4945 // JSGlobalProxies store their hash internally. | 4945 // JSGlobalProxies store their hash internally. |
4946 ASSERT(*key != GetHeap()->identity_hash_string()); | 4946 DCHECK(*key != GetHeap()->identity_hash_string()); |
4947 // For a proxy, use the prototype as target object. | 4947 // For a proxy, use the prototype as target object. |
4948 PrototypeIterator iter(GetIsolate(), this); | 4948 PrototypeIterator iter(GetIsolate(), this); |
4949 // If the proxy is detached, return undefined. | 4949 // If the proxy is detached, return undefined. |
4950 if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); | 4950 if (iter.IsAtEnd()) return GetHeap()->the_hole_value(); |
4951 ASSERT(iter.GetCurrent()->IsJSGlobalObject()); | 4951 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
4952 return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key); | 4952 return JSObject::cast(iter.GetCurrent())->GetHiddenProperty(key); |
4953 } | 4953 } |
4954 ASSERT(!IsJSGlobalProxy()); | 4954 DCHECK(!IsJSGlobalProxy()); |
4955 Object* inline_value = GetHiddenPropertiesHashTable(); | 4955 Object* inline_value = GetHiddenPropertiesHashTable(); |
4956 | 4956 |
4957 if (inline_value->IsSmi()) { | 4957 if (inline_value->IsSmi()) { |
4958 // Handle inline-stored identity hash. | 4958 // Handle inline-stored identity hash. |
4959 if (*key == GetHeap()->identity_hash_string()) { | 4959 if (*key == GetHeap()->identity_hash_string()) { |
4960 return inline_value; | 4960 return inline_value; |
4961 } else { | 4961 } else { |
4962 return GetHeap()->the_hole_value(); | 4962 return GetHeap()->the_hole_value(); |
4963 } | 4963 } |
4964 } | 4964 } |
4965 | 4965 |
4966 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); | 4966 if (inline_value->IsUndefined()) return GetHeap()->the_hole_value(); |
4967 | 4967 |
4968 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); | 4968 ObjectHashTable* hashtable = ObjectHashTable::cast(inline_value); |
4969 Object* entry = hashtable->Lookup(key); | 4969 Object* entry = hashtable->Lookup(key); |
4970 return entry; | 4970 return entry; |
4971 } | 4971 } |
4972 | 4972 |
4973 | 4973 |
4974 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, | 4974 Handle<Object> JSObject::SetHiddenProperty(Handle<JSObject> object, |
4975 Handle<Name> key, | 4975 Handle<Name> key, |
4976 Handle<Object> value) { | 4976 Handle<Object> value) { |
4977 Isolate* isolate = object->GetIsolate(); | 4977 Isolate* isolate = object->GetIsolate(); |
4978 | 4978 |
4979 ASSERT(key->IsUniqueName()); | 4979 DCHECK(key->IsUniqueName()); |
4980 if (object->IsJSGlobalProxy()) { | 4980 if (object->IsJSGlobalProxy()) { |
4981 // JSGlobalProxies store their hash internally. | 4981 // JSGlobalProxies store their hash internally. |
4982 ASSERT(*key != *isolate->factory()->identity_hash_string()); | 4982 DCHECK(*key != *isolate->factory()->identity_hash_string()); |
4983 // For a proxy, use the prototype as target object. | 4983 // For a proxy, use the prototype as target object. |
4984 PrototypeIterator iter(isolate, object); | 4984 PrototypeIterator iter(isolate, object); |
4985 // If the proxy is detached, return undefined. | 4985 // If the proxy is detached, return undefined. |
4986 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); | 4986 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); |
4987 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 4987 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
4988 return SetHiddenProperty( | 4988 return SetHiddenProperty( |
4989 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key, | 4989 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key, |
4990 value); | 4990 value); |
4991 } | 4991 } |
4992 ASSERT(!object->IsJSGlobalProxy()); | 4992 DCHECK(!object->IsJSGlobalProxy()); |
4993 | 4993 |
4994 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); | 4994 Handle<Object> inline_value(object->GetHiddenPropertiesHashTable(), isolate); |
4995 | 4995 |
4996 // If there is no backing store yet, store the identity hash inline. | 4996 // If there is no backing store yet, store the identity hash inline. |
4997 if (value->IsSmi() && | 4997 if (value->IsSmi() && |
4998 *key == *isolate->factory()->identity_hash_string() && | 4998 *key == *isolate->factory()->identity_hash_string() && |
4999 (inline_value->IsUndefined() || inline_value->IsSmi())) { | 4999 (inline_value->IsUndefined() || inline_value->IsSmi())) { |
5000 return JSObject::SetHiddenPropertiesHashTable(object, value); | 5000 return JSObject::SetHiddenPropertiesHashTable(object, value); |
5001 } | 5001 } |
5002 | 5002 |
5003 Handle<ObjectHashTable> hashtable = | 5003 Handle<ObjectHashTable> hashtable = |
5004 GetOrCreateHiddenPropertiesHashtable(object); | 5004 GetOrCreateHiddenPropertiesHashtable(object); |
5005 | 5005 |
5006 // If it was found, check if the key is already in the dictionary. | 5006 // If it was found, check if the key is already in the dictionary. |
5007 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, | 5007 Handle<ObjectHashTable> new_table = ObjectHashTable::Put(hashtable, key, |
5008 value); | 5008 value); |
5009 if (*new_table != *hashtable) { | 5009 if (*new_table != *hashtable) { |
5010 // If adding the key expanded the dictionary (i.e., Add returned a new | 5010 // If adding the key expanded the dictionary (i.e., Add returned a new |
5011 // dictionary), store it back to the object. | 5011 // dictionary), store it back to the object. |
5012 SetHiddenPropertiesHashTable(object, new_table); | 5012 SetHiddenPropertiesHashTable(object, new_table); |
5013 } | 5013 } |
5014 | 5014 |
5015 // Return this to mark success. | 5015 // Return this to mark success. |
5016 return object; | 5016 return object; |
5017 } | 5017 } |
5018 | 5018 |
5019 | 5019 |
5020 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { | 5020 void JSObject::DeleteHiddenProperty(Handle<JSObject> object, Handle<Name> key) { |
5021 Isolate* isolate = object->GetIsolate(); | 5021 Isolate* isolate = object->GetIsolate(); |
5022 ASSERT(key->IsUniqueName()); | 5022 DCHECK(key->IsUniqueName()); |
5023 | 5023 |
5024 if (object->IsJSGlobalProxy()) { | 5024 if (object->IsJSGlobalProxy()) { |
5025 PrototypeIterator iter(isolate, object); | 5025 PrototypeIterator iter(isolate, object); |
5026 if (iter.IsAtEnd()) return; | 5026 if (iter.IsAtEnd()) return; |
5027 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5027 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
5028 return DeleteHiddenProperty( | 5028 return DeleteHiddenProperty( |
5029 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); | 5029 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), key); |
5030 } | 5030 } |
5031 | 5031 |
5032 Object* inline_value = object->GetHiddenPropertiesHashTable(); | 5032 Object* inline_value = object->GetHiddenPropertiesHashTable(); |
5033 | 5033 |
5034 // We never delete (inline-stored) identity hashes. | 5034 // We never delete (inline-stored) identity hashes. |
5035 ASSERT(*key != *isolate->factory()->identity_hash_string()); | 5035 DCHECK(*key != *isolate->factory()->identity_hash_string()); |
5036 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; | 5036 if (inline_value->IsUndefined() || inline_value->IsSmi()) return; |
5037 | 5037 |
5038 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); | 5038 Handle<ObjectHashTable> hashtable(ObjectHashTable::cast(inline_value)); |
5039 bool was_present = false; | 5039 bool was_present = false; |
5040 ObjectHashTable::Remove(hashtable, key, &was_present); | 5040 ObjectHashTable::Remove(hashtable, key, &was_present); |
5041 } | 5041 } |
5042 | 5042 |
5043 | 5043 |
5044 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { | 5044 bool JSObject::HasHiddenProperties(Handle<JSObject> object) { |
5045 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); | 5045 Handle<Name> hidden = object->GetIsolate()->factory()->hidden_string(); |
5046 LookupIterator it(object, hidden, LookupIterator::CHECK_OWN_REAL); | 5046 LookupIterator it(object, hidden, LookupIterator::CHECK_OWN_REAL); |
5047 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it); | 5047 Maybe<PropertyAttributes> maybe = GetPropertyAttributes(&it); |
5048 // Cannot get an exception since the hidden_string isn't accessible to JS. | 5048 // Cannot get an exception since the hidden_string isn't accessible to JS. |
5049 ASSERT(maybe.has_value); | 5049 DCHECK(maybe.has_value); |
5050 return maybe.value != ABSENT; | 5050 return maybe.value != ABSENT; |
5051 } | 5051 } |
5052 | 5052 |
5053 | 5053 |
5054 Object* JSObject::GetHiddenPropertiesHashTable() { | 5054 Object* JSObject::GetHiddenPropertiesHashTable() { |
5055 ASSERT(!IsJSGlobalProxy()); | 5055 DCHECK(!IsJSGlobalProxy()); |
5056 if (HasFastProperties()) { | 5056 if (HasFastProperties()) { |
5057 // If the object has fast properties, check whether the first slot | 5057 // If the object has fast properties, check whether the first slot |
5058 // in the descriptor array matches the hidden string. Since the | 5058 // in the descriptor array matches the hidden string. Since the |
5059 // hidden strings hash code is zero (and no other name has hash | 5059 // hidden strings hash code is zero (and no other name has hash |
5060 // code zero) it will always occupy the first entry if present. | 5060 // code zero) it will always occupy the first entry if present. |
5061 DescriptorArray* descriptors = this->map()->instance_descriptors(); | 5061 DescriptorArray* descriptors = this->map()->instance_descriptors(); |
5062 if (descriptors->number_of_descriptors() > 0) { | 5062 if (descriptors->number_of_descriptors() > 0) { |
5063 int sorted_index = descriptors->GetSortedKeyIndex(0); | 5063 int sorted_index = descriptors->GetSortedKeyIndex(0); |
5064 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && | 5064 if (descriptors->GetKey(sorted_index) == GetHeap()->hidden_string() && |
5065 sorted_index < map()->NumberOfOwnDescriptors()) { | 5065 sorted_index < map()->NumberOfOwnDescriptors()) { |
5066 ASSERT(descriptors->GetType(sorted_index) == FIELD); | 5066 DCHECK(descriptors->GetType(sorted_index) == FIELD); |
5067 ASSERT(descriptors->GetDetails(sorted_index).representation(). | 5067 DCHECK(descriptors->GetDetails(sorted_index).representation(). |
5068 IsCompatibleForLoad(Representation::Tagged())); | 5068 IsCompatibleForLoad(Representation::Tagged())); |
5069 FieldIndex index = FieldIndex::ForDescriptor(this->map(), | 5069 FieldIndex index = FieldIndex::ForDescriptor(this->map(), |
5070 sorted_index); | 5070 sorted_index); |
5071 return this->RawFastPropertyAt(index); | 5071 return this->RawFastPropertyAt(index); |
5072 } else { | 5072 } else { |
5073 return GetHeap()->undefined_value(); | 5073 return GetHeap()->undefined_value(); |
5074 } | 5074 } |
5075 } else { | 5075 } else { |
5076 return GetHeap()->undefined_value(); | 5076 return GetHeap()->undefined_value(); |
5077 } | 5077 } |
5078 } else { | 5078 } else { |
5079 Isolate* isolate = GetIsolate(); | 5079 Isolate* isolate = GetIsolate(); |
5080 LookupResult result(isolate); | 5080 LookupResult result(isolate); |
5081 LookupOwnRealNamedProperty(isolate->factory()->hidden_string(), &result); | 5081 LookupOwnRealNamedProperty(isolate->factory()->hidden_string(), &result); |
5082 if (result.IsFound()) { | 5082 if (result.IsFound()) { |
5083 ASSERT(result.IsNormal()); | 5083 DCHECK(result.IsNormal()); |
5084 ASSERT(result.holder() == this); | 5084 DCHECK(result.holder() == this); |
5085 return GetNormalizedProperty(&result); | 5085 return GetNormalizedProperty(&result); |
5086 } | 5086 } |
5087 return GetHeap()->undefined_value(); | 5087 return GetHeap()->undefined_value(); |
5088 } | 5088 } |
5089 } | 5089 } |
5090 | 5090 |
5091 Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable( | 5091 Handle<ObjectHashTable> JSObject::GetOrCreateHiddenPropertiesHashtable( |
5092 Handle<JSObject> object) { | 5092 Handle<JSObject> object) { |
5093 Isolate* isolate = object->GetIsolate(); | 5093 Isolate* isolate = object->GetIsolate(); |
5094 | 5094 |
(...skipping 17 matching lines...) Expand all Loading... |
5112 JSObject::SetOwnPropertyIgnoreAttributes( | 5112 JSObject::SetOwnPropertyIgnoreAttributes( |
5113 object, isolate->factory()->hidden_string(), | 5113 object, isolate->factory()->hidden_string(), |
5114 hashtable, DONT_ENUM).Assert(); | 5114 hashtable, DONT_ENUM).Assert(); |
5115 | 5115 |
5116 return hashtable; | 5116 return hashtable; |
5117 } | 5117 } |
5118 | 5118 |
5119 | 5119 |
5120 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, | 5120 Handle<Object> JSObject::SetHiddenPropertiesHashTable(Handle<JSObject> object, |
5121 Handle<Object> value) { | 5121 Handle<Object> value) { |
5122 ASSERT(!object->IsJSGlobalProxy()); | 5122 DCHECK(!object->IsJSGlobalProxy()); |
5123 | 5123 |
5124 Isolate* isolate = object->GetIsolate(); | 5124 Isolate* isolate = object->GetIsolate(); |
5125 | 5125 |
5126 // We can store the identity hash inline iff there is no backing store | 5126 // We can store the identity hash inline iff there is no backing store |
5127 // for hidden properties yet. | 5127 // for hidden properties yet. |
5128 ASSERT(JSObject::HasHiddenProperties(object) != value->IsSmi()); | 5128 DCHECK(JSObject::HasHiddenProperties(object) != value->IsSmi()); |
5129 if (object->HasFastProperties()) { | 5129 if (object->HasFastProperties()) { |
5130 // If the object has fast properties, check whether the first slot | 5130 // If the object has fast properties, check whether the first slot |
5131 // in the descriptor array matches the hidden string. Since the | 5131 // in the descriptor array matches the hidden string. Since the |
5132 // hidden strings hash code is zero (and no other name has hash | 5132 // hidden strings hash code is zero (and no other name has hash |
5133 // code zero) it will always occupy the first entry if present. | 5133 // code zero) it will always occupy the first entry if present. |
5134 DescriptorArray* descriptors = object->map()->instance_descriptors(); | 5134 DescriptorArray* descriptors = object->map()->instance_descriptors(); |
5135 if (descriptors->number_of_descriptors() > 0) { | 5135 if (descriptors->number_of_descriptors() > 0) { |
5136 int sorted_index = descriptors->GetSortedKeyIndex(0); | 5136 int sorted_index = descriptors->GetSortedKeyIndex(0); |
5137 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() | 5137 if (descriptors->GetKey(sorted_index) == isolate->heap()->hidden_string() |
5138 && sorted_index < object->map()->NumberOfOwnDescriptors()) { | 5138 && sorted_index < object->map()->NumberOfOwnDescriptors()) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5177 v8::NamedPropertyDeleterCallback deleter = | 5177 v8::NamedPropertyDeleterCallback deleter = |
5178 v8::ToCData<v8::NamedPropertyDeleterCallback>(interceptor->deleter()); | 5178 v8::ToCData<v8::NamedPropertyDeleterCallback>(interceptor->deleter()); |
5179 LOG(isolate, | 5179 LOG(isolate, |
5180 ApiNamedPropertyAccess("interceptor-named-delete", *object, *name)); | 5180 ApiNamedPropertyAccess("interceptor-named-delete", *object, *name)); |
5181 PropertyCallbackArguments args( | 5181 PropertyCallbackArguments args( |
5182 isolate, interceptor->data(), *object, *object); | 5182 isolate, interceptor->data(), *object, *object); |
5183 v8::Handle<v8::Boolean> result = | 5183 v8::Handle<v8::Boolean> result = |
5184 args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name))); | 5184 args.Call(deleter, v8::Utils::ToLocal(Handle<String>::cast(name))); |
5185 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5185 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5186 if (!result.IsEmpty()) { | 5186 if (!result.IsEmpty()) { |
5187 ASSERT(result->IsBoolean()); | 5187 DCHECK(result->IsBoolean()); |
5188 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 5188 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
5189 result_internal->VerifyApiCallResultType(); | 5189 result_internal->VerifyApiCallResultType(); |
5190 // Rebox CustomArguments::kReturnValueOffset before returning. | 5190 // Rebox CustomArguments::kReturnValueOffset before returning. |
5191 return handle(*result_internal, isolate); | 5191 return handle(*result_internal, isolate); |
5192 } | 5192 } |
5193 } | 5193 } |
5194 Handle<Object> result = | 5194 Handle<Object> result = |
5195 DeletePropertyPostInterceptor(object, name, NORMAL_DELETION); | 5195 DeletePropertyPostInterceptor(object, name, NORMAL_DELETION); |
5196 return result; | 5196 return result; |
5197 } | 5197 } |
(...skipping 13 matching lines...) Expand all Loading... |
5211 if (interceptor->deleter()->IsUndefined()) return factory->false_value(); | 5211 if (interceptor->deleter()->IsUndefined()) return factory->false_value(); |
5212 v8::IndexedPropertyDeleterCallback deleter = | 5212 v8::IndexedPropertyDeleterCallback deleter = |
5213 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); | 5213 v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter()); |
5214 LOG(isolate, | 5214 LOG(isolate, |
5215 ApiIndexedPropertyAccess("interceptor-indexed-delete", *object, index)); | 5215 ApiIndexedPropertyAccess("interceptor-indexed-delete", *object, index)); |
5216 PropertyCallbackArguments args( | 5216 PropertyCallbackArguments args( |
5217 isolate, interceptor->data(), *object, *object); | 5217 isolate, interceptor->data(), *object, *object); |
5218 v8::Handle<v8::Boolean> result = args.Call(deleter, index); | 5218 v8::Handle<v8::Boolean> result = args.Call(deleter, index); |
5219 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5219 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5220 if (!result.IsEmpty()) { | 5220 if (!result.IsEmpty()) { |
5221 ASSERT(result->IsBoolean()); | 5221 DCHECK(result->IsBoolean()); |
5222 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); | 5222 Handle<Object> result_internal = v8::Utils::OpenHandle(*result); |
5223 result_internal->VerifyApiCallResultType(); | 5223 result_internal->VerifyApiCallResultType(); |
5224 // Rebox CustomArguments::kReturnValueOffset before returning. | 5224 // Rebox CustomArguments::kReturnValueOffset before returning. |
5225 return handle(*result_internal, isolate); | 5225 return handle(*result_internal, isolate); |
5226 } | 5226 } |
5227 MaybeHandle<Object> delete_result = object->GetElementsAccessor()->Delete( | 5227 MaybeHandle<Object> delete_result = object->GetElementsAccessor()->Delete( |
5228 object, index, NORMAL_DELETION); | 5228 object, index, NORMAL_DELETION); |
5229 return delete_result; | 5229 return delete_result; |
5230 } | 5230 } |
5231 | 5231 |
(...skipping 22 matching lines...) Expand all Loading... |
5254 HandleVector(args, 2)); | 5254 HandleVector(args, 2)); |
5255 isolate->Throw(*error); | 5255 isolate->Throw(*error); |
5256 return Handle<Object>(); | 5256 return Handle<Object>(); |
5257 } | 5257 } |
5258 return factory->false_value(); | 5258 return factory->false_value(); |
5259 } | 5259 } |
5260 | 5260 |
5261 if (object->IsJSGlobalProxy()) { | 5261 if (object->IsJSGlobalProxy()) { |
5262 PrototypeIterator iter(isolate, object); | 5262 PrototypeIterator iter(isolate, object); |
5263 if (iter.IsAtEnd()) return factory->false_value(); | 5263 if (iter.IsAtEnd()) return factory->false_value(); |
5264 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5264 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
5265 return DeleteElement( | 5265 return DeleteElement( |
5266 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, | 5266 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, |
5267 mode); | 5267 mode); |
5268 } | 5268 } |
5269 | 5269 |
5270 Handle<Object> old_value; | 5270 Handle<Object> old_value; |
5271 bool should_enqueue_change_record = false; | 5271 bool should_enqueue_change_record = false; |
5272 if (object->map()->is_observed()) { | 5272 if (object->map()->is_observed()) { |
5273 Maybe<bool> maybe = HasOwnElement(object, index); | 5273 Maybe<bool> maybe = HasOwnElement(object, index); |
5274 if (!maybe.has_value) return MaybeHandle<Object>(); | 5274 if (!maybe.has_value) return MaybeHandle<Object>(); |
(...skipping 29 matching lines...) Expand all Loading... |
5304 | 5304 |
5305 return result; | 5305 return result; |
5306 } | 5306 } |
5307 | 5307 |
5308 | 5308 |
5309 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, | 5309 MaybeHandle<Object> JSObject::DeleteProperty(Handle<JSObject> object, |
5310 Handle<Name> name, | 5310 Handle<Name> name, |
5311 DeleteMode mode) { | 5311 DeleteMode mode) { |
5312 Isolate* isolate = object->GetIsolate(); | 5312 Isolate* isolate = object->GetIsolate(); |
5313 // ECMA-262, 3rd, 8.6.2.5 | 5313 // ECMA-262, 3rd, 8.6.2.5 |
5314 ASSERT(name->IsName()); | 5314 DCHECK(name->IsName()); |
5315 | 5315 |
5316 // Check access rights if needed. | 5316 // Check access rights if needed. |
5317 if (object->IsAccessCheckNeeded() && | 5317 if (object->IsAccessCheckNeeded() && |
5318 !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) { | 5318 !isolate->MayNamedAccess(object, name, v8::ACCESS_DELETE)) { |
5319 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); | 5319 isolate->ReportFailedAccessCheck(object, v8::ACCESS_DELETE); |
5320 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5320 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5321 return isolate->factory()->false_value(); | 5321 return isolate->factory()->false_value(); |
5322 } | 5322 } |
5323 | 5323 |
5324 if (object->IsJSGlobalProxy()) { | 5324 if (object->IsJSGlobalProxy()) { |
5325 PrototypeIterator iter(isolate, object); | 5325 PrototypeIterator iter(isolate, object); |
5326 if (iter.IsAtEnd()) return isolate->factory()->false_value(); | 5326 if (iter.IsAtEnd()) return isolate->factory()->false_value(); |
5327 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5327 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
5328 return JSGlobalObject::DeleteProperty( | 5328 return JSGlobalObject::DeleteProperty( |
5329 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)), name, | 5329 Handle<JSGlobalObject>::cast(PrototypeIterator::GetCurrent(iter)), name, |
5330 mode); | 5330 mode); |
5331 } | 5331 } |
5332 | 5332 |
5333 uint32_t index = 0; | 5333 uint32_t index = 0; |
5334 if (name->AsArrayIndex(&index)) { | 5334 if (name->AsArrayIndex(&index)) { |
5335 return DeleteElement(object, index, mode); | 5335 return DeleteElement(object, index, mode); |
5336 } | 5336 } |
5337 | 5337 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5407 return JSProxy::DeletePropertyWithHandler( | 5407 return JSProxy::DeletePropertyWithHandler( |
5408 Handle<JSProxy>::cast(object), name, mode); | 5408 Handle<JSProxy>::cast(object), name, mode); |
5409 } | 5409 } |
5410 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode); | 5410 return JSObject::DeleteProperty(Handle<JSObject>::cast(object), name, mode); |
5411 } | 5411 } |
5412 | 5412 |
5413 | 5413 |
5414 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, | 5414 bool JSObject::ReferencesObjectFromElements(FixedArray* elements, |
5415 ElementsKind kind, | 5415 ElementsKind kind, |
5416 Object* object) { | 5416 Object* object) { |
5417 ASSERT(IsFastObjectElementsKind(kind) || | 5417 DCHECK(IsFastObjectElementsKind(kind) || |
5418 kind == DICTIONARY_ELEMENTS); | 5418 kind == DICTIONARY_ELEMENTS); |
5419 if (IsFastObjectElementsKind(kind)) { | 5419 if (IsFastObjectElementsKind(kind)) { |
5420 int length = IsJSArray() | 5420 int length = IsJSArray() |
5421 ? Smi::cast(JSArray::cast(this)->length())->value() | 5421 ? Smi::cast(JSArray::cast(this)->length())->value() |
5422 : elements->length(); | 5422 : elements->length(); |
5423 for (int i = 0; i < length; ++i) { | 5423 for (int i = 0; i < length; ++i) { |
5424 Object* element = elements->get(i); | 5424 Object* element = elements->get(i); |
5425 if (!element->IsTheHole() && element == object) return true; | 5425 if (!element->IsTheHole() && element == object) return true; |
5426 } | 5426 } |
5427 } else { | 5427 } else { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5555 !isolate->MayNamedAccess( | 5555 !isolate->MayNamedAccess( |
5556 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5556 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
5557 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5557 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
5558 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5558 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5559 return isolate->factory()->false_value(); | 5559 return isolate->factory()->false_value(); |
5560 } | 5560 } |
5561 | 5561 |
5562 if (object->IsJSGlobalProxy()) { | 5562 if (object->IsJSGlobalProxy()) { |
5563 PrototypeIterator iter(isolate, object); | 5563 PrototypeIterator iter(isolate, object); |
5564 if (iter.IsAtEnd()) return object; | 5564 if (iter.IsAtEnd()) return object; |
5565 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5565 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
5566 return PreventExtensions( | 5566 return PreventExtensions( |
5567 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); | 5567 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); |
5568 } | 5568 } |
5569 | 5569 |
5570 // It's not possible to seal objects with external array elements | 5570 // It's not possible to seal objects with external array elements |
5571 if (object->HasExternalArrayElements() || | 5571 if (object->HasExternalArrayElements() || |
5572 object->HasFixedTypedArrayElements()) { | 5572 object->HasFixedTypedArrayElements()) { |
5573 Handle<Object> error = | 5573 Handle<Object> error = |
5574 isolate->factory()->NewTypeError( | 5574 isolate->factory()->NewTypeError( |
5575 "cant_prevent_ext_external_array_elements", | 5575 "cant_prevent_ext_external_array_elements", |
5576 HandleVector(&object, 1)); | 5576 HandleVector(&object, 1)); |
5577 return isolate->Throw<Object>(error); | 5577 return isolate->Throw<Object>(error); |
5578 } | 5578 } |
5579 | 5579 |
5580 // If there are fast elements we normalize. | 5580 // If there are fast elements we normalize. |
5581 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 5581 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
5582 ASSERT(object->HasDictionaryElements() || | 5582 DCHECK(object->HasDictionaryElements() || |
5583 object->HasDictionaryArgumentsElements()); | 5583 object->HasDictionaryArgumentsElements()); |
5584 | 5584 |
5585 // Make sure that we never go back to fast case. | 5585 // Make sure that we never go back to fast case. |
5586 dictionary->set_requires_slow_elements(); | 5586 dictionary->set_requires_slow_elements(); |
5587 | 5587 |
5588 // Do a map transition, other objects with this map may still | 5588 // Do a map transition, other objects with this map may still |
5589 // be extensible. | 5589 // be extensible. |
5590 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5590 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
5591 Handle<Map> new_map = Map::Copy(handle(object->map())); | 5591 Handle<Map> new_map = Map::Copy(handle(object->map())); |
5592 | 5592 |
5593 new_map->set_is_extensible(false); | 5593 new_map->set_is_extensible(false); |
5594 JSObject::MigrateToMap(object, new_map); | 5594 JSObject::MigrateToMap(object, new_map); |
5595 ASSERT(!object->map()->is_extensible()); | 5595 DCHECK(!object->map()->is_extensible()); |
5596 | 5596 |
5597 if (object->map()->is_observed()) { | 5597 if (object->map()->is_observed()) { |
5598 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), | 5598 EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
5599 isolate->factory()->the_hole_value()); | 5599 isolate->factory()->the_hole_value()); |
5600 } | 5600 } |
5601 return object; | 5601 return object; |
5602 } | 5602 } |
5603 | 5603 |
5604 | 5604 |
5605 template<typename Dictionary> | 5605 template<typename Dictionary> |
(...skipping 16 matching lines...) Expand all Loading... |
5622 details = details.CopyAddAttributes( | 5622 details = details.CopyAddAttributes( |
5623 static_cast<PropertyAttributes>(attrs)); | 5623 static_cast<PropertyAttributes>(attrs)); |
5624 dictionary->DetailsAtPut(i, details); | 5624 dictionary->DetailsAtPut(i, details); |
5625 } | 5625 } |
5626 } | 5626 } |
5627 } | 5627 } |
5628 | 5628 |
5629 | 5629 |
5630 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { | 5630 MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) { |
5631 // Freezing sloppy arguments should be handled elsewhere. | 5631 // Freezing sloppy arguments should be handled elsewhere. |
5632 ASSERT(!object->HasSloppyArgumentsElements()); | 5632 DCHECK(!object->HasSloppyArgumentsElements()); |
5633 ASSERT(!object->map()->is_observed()); | 5633 DCHECK(!object->map()->is_observed()); |
5634 | 5634 |
5635 if (object->map()->is_frozen()) return object; | 5635 if (object->map()->is_frozen()) return object; |
5636 | 5636 |
5637 Isolate* isolate = object->GetIsolate(); | 5637 Isolate* isolate = object->GetIsolate(); |
5638 if (object->IsAccessCheckNeeded() && | 5638 if (object->IsAccessCheckNeeded() && |
5639 !isolate->MayNamedAccess( | 5639 !isolate->MayNamedAccess( |
5640 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { | 5640 object, isolate->factory()->undefined_value(), v8::ACCESS_KEYS)) { |
5641 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); | 5641 isolate->ReportFailedAccessCheck(object, v8::ACCESS_KEYS); |
5642 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 5642 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
5643 return isolate->factory()->false_value(); | 5643 return isolate->factory()->false_value(); |
5644 } | 5644 } |
5645 | 5645 |
5646 if (object->IsJSGlobalProxy()) { | 5646 if (object->IsJSGlobalProxy()) { |
5647 PrototypeIterator iter(isolate, object); | 5647 PrototypeIterator iter(isolate, object); |
5648 if (iter.IsAtEnd()) return object; | 5648 if (iter.IsAtEnd()) return object; |
5649 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 5649 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
5650 return Freeze(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); | 5650 return Freeze(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); |
5651 } | 5651 } |
5652 | 5652 |
5653 // It's not possible to freeze objects with external array elements | 5653 // It's not possible to freeze objects with external array elements |
5654 if (object->HasExternalArrayElements() || | 5654 if (object->HasExternalArrayElements() || |
5655 object->HasFixedTypedArrayElements()) { | 5655 object->HasFixedTypedArrayElements()) { |
5656 Handle<Object> error = | 5656 Handle<Object> error = |
5657 isolate->factory()->NewTypeError( | 5657 isolate->factory()->NewTypeError( |
5658 "cant_prevent_ext_external_array_elements", | 5658 "cant_prevent_ext_external_array_elements", |
5659 HandleVector(&object, 1)); | 5659 HandleVector(&object, 1)); |
(...skipping 20 matching lines...) Expand all Loading... |
5680 new_element_dictionary = | 5680 new_element_dictionary = |
5681 isolate->factory()->empty_slow_element_dictionary(); | 5681 isolate->factory()->empty_slow_element_dictionary(); |
5682 } | 5682 } |
5683 } | 5683 } |
5684 | 5684 |
5685 Handle<Map> old_map(object->map(), isolate); | 5685 Handle<Map> old_map(object->map(), isolate); |
5686 int transition_index = old_map->SearchTransition( | 5686 int transition_index = old_map->SearchTransition( |
5687 isolate->heap()->frozen_symbol()); | 5687 isolate->heap()->frozen_symbol()); |
5688 if (transition_index != TransitionArray::kNotFound) { | 5688 if (transition_index != TransitionArray::kNotFound) { |
5689 Handle<Map> transition_map(old_map->GetTransition(transition_index)); | 5689 Handle<Map> transition_map(old_map->GetTransition(transition_index)); |
5690 ASSERT(transition_map->has_dictionary_elements()); | 5690 DCHECK(transition_map->has_dictionary_elements()); |
5691 ASSERT(transition_map->is_frozen()); | 5691 DCHECK(transition_map->is_frozen()); |
5692 ASSERT(!transition_map->is_extensible()); | 5692 DCHECK(!transition_map->is_extensible()); |
5693 JSObject::MigrateToMap(object, transition_map); | 5693 JSObject::MigrateToMap(object, transition_map); |
5694 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { | 5694 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { |
5695 // Create a new descriptor array with fully-frozen properties | 5695 // Create a new descriptor array with fully-frozen properties |
5696 Handle<Map> new_map = Map::CopyForFreeze(old_map); | 5696 Handle<Map> new_map = Map::CopyForFreeze(old_map); |
5697 JSObject::MigrateToMap(object, new_map); | 5697 JSObject::MigrateToMap(object, new_map); |
5698 } else { | 5698 } else { |
5699 // Slow path: need to normalize properties for safety | 5699 // Slow path: need to normalize properties for safety |
5700 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 5700 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
5701 | 5701 |
5702 // Create a new map, since other objects with this map may be extensible. | 5702 // Create a new map, since other objects with this map may be extensible. |
5703 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. | 5703 // TODO(adamk): Extend the NormalizedMapCache to handle non-extensible maps. |
5704 Handle<Map> new_map = Map::Copy(handle(object->map())); | 5704 Handle<Map> new_map = Map::Copy(handle(object->map())); |
5705 new_map->freeze(); | 5705 new_map->freeze(); |
5706 new_map->set_is_extensible(false); | 5706 new_map->set_is_extensible(false); |
5707 new_map->set_elements_kind(DICTIONARY_ELEMENTS); | 5707 new_map->set_elements_kind(DICTIONARY_ELEMENTS); |
5708 JSObject::MigrateToMap(object, new_map); | 5708 JSObject::MigrateToMap(object, new_map); |
5709 | 5709 |
5710 // Freeze dictionary-mode properties | 5710 // Freeze dictionary-mode properties |
5711 FreezeDictionary(object->property_dictionary()); | 5711 FreezeDictionary(object->property_dictionary()); |
5712 } | 5712 } |
5713 | 5713 |
5714 ASSERT(object->map()->has_dictionary_elements()); | 5714 DCHECK(object->map()->has_dictionary_elements()); |
5715 if (!new_element_dictionary.is_null()) { | 5715 if (!new_element_dictionary.is_null()) { |
5716 object->set_elements(*new_element_dictionary); | 5716 object->set_elements(*new_element_dictionary); |
5717 } | 5717 } |
5718 | 5718 |
5719 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { | 5719 if (object->elements() != isolate->heap()->empty_slow_element_dictionary()) { |
5720 SeededNumberDictionary* dictionary = object->element_dictionary(); | 5720 SeededNumberDictionary* dictionary = object->element_dictionary(); |
5721 // Make sure we never go back to the fast case | 5721 // Make sure we never go back to the fast case |
5722 dictionary->set_requires_slow_elements(); | 5722 dictionary->set_requires_slow_elements(); |
5723 // Freeze all elements in the dictionary | 5723 // Freeze all elements in the dictionary |
5724 FreezeDictionary(dictionary); | 5724 FreezeDictionary(dictionary); |
5725 } | 5725 } |
5726 | 5726 |
5727 return object; | 5727 return object; |
5728 } | 5728 } |
5729 | 5729 |
5730 | 5730 |
5731 void JSObject::SetObserved(Handle<JSObject> object) { | 5731 void JSObject::SetObserved(Handle<JSObject> object) { |
5732 ASSERT(!object->IsJSGlobalProxy()); | 5732 DCHECK(!object->IsJSGlobalProxy()); |
5733 ASSERT(!object->IsJSGlobalObject()); | 5733 DCHECK(!object->IsJSGlobalObject()); |
5734 Isolate* isolate = object->GetIsolate(); | 5734 Isolate* isolate = object->GetIsolate(); |
5735 Handle<Map> new_map; | 5735 Handle<Map> new_map; |
5736 Handle<Map> old_map(object->map(), isolate); | 5736 Handle<Map> old_map(object->map(), isolate); |
5737 ASSERT(!old_map->is_observed()); | 5737 DCHECK(!old_map->is_observed()); |
5738 int transition_index = old_map->SearchTransition( | 5738 int transition_index = old_map->SearchTransition( |
5739 isolate->heap()->observed_symbol()); | 5739 isolate->heap()->observed_symbol()); |
5740 if (transition_index != TransitionArray::kNotFound) { | 5740 if (transition_index != TransitionArray::kNotFound) { |
5741 new_map = handle(old_map->GetTransition(transition_index), isolate); | 5741 new_map = handle(old_map->GetTransition(transition_index), isolate); |
5742 ASSERT(new_map->is_observed()); | 5742 DCHECK(new_map->is_observed()); |
5743 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { | 5743 } else if (object->HasFastProperties() && old_map->CanHaveMoreTransitions()) { |
5744 new_map = Map::CopyForObserved(old_map); | 5744 new_map = Map::CopyForObserved(old_map); |
5745 } else { | 5745 } else { |
5746 new_map = Map::Copy(old_map); | 5746 new_map = Map::Copy(old_map); |
5747 new_map->set_is_observed(); | 5747 new_map->set_is_observed(); |
5748 } | 5748 } |
5749 JSObject::MigrateToMap(object, new_map); | 5749 JSObject::MigrateToMap(object, new_map); |
5750 } | 5750 } |
5751 | 5751 |
5752 | 5752 |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5817 Handle<AllocationSite> site_to_pass; | 5817 Handle<AllocationSite> site_to_pass; |
5818 if (site_context()->ShouldCreateMemento(object)) { | 5818 if (site_context()->ShouldCreateMemento(object)) { |
5819 site_to_pass = site_context()->current(); | 5819 site_to_pass = site_context()->current(); |
5820 } | 5820 } |
5821 copy = isolate->factory()->CopyJSObjectWithAllocationSite( | 5821 copy = isolate->factory()->CopyJSObjectWithAllocationSite( |
5822 object, site_to_pass); | 5822 object, site_to_pass); |
5823 } else { | 5823 } else { |
5824 copy = object; | 5824 copy = object; |
5825 } | 5825 } |
5826 | 5826 |
5827 ASSERT(copying || copy.is_identical_to(object)); | 5827 DCHECK(copying || copy.is_identical_to(object)); |
5828 | 5828 |
5829 ElementsKind kind = copy->GetElementsKind(); | 5829 ElementsKind kind = copy->GetElementsKind(); |
5830 if (copying && IsFastSmiOrObjectElementsKind(kind) && | 5830 if (copying && IsFastSmiOrObjectElementsKind(kind) && |
5831 FixedArray::cast(copy->elements())->map() == | 5831 FixedArray::cast(copy->elements())->map() == |
5832 isolate->heap()->fixed_cow_array_map()) { | 5832 isolate->heap()->fixed_cow_array_map()) { |
5833 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 5833 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
5834 } | 5834 } |
5835 | 5835 |
5836 if (!shallow) { | 5836 if (!shallow) { |
5837 HandleScope scope(isolate); | 5837 HandleScope scope(isolate); |
(...skipping 18 matching lines...) Expand all Loading... |
5856 } | 5856 } |
5857 if (copying) { | 5857 if (copying) { |
5858 copy->FastPropertyAtPut(index, *value); | 5858 copy->FastPropertyAtPut(index, *value); |
5859 } | 5859 } |
5860 } | 5860 } |
5861 } else { | 5861 } else { |
5862 Handle<FixedArray> names = | 5862 Handle<FixedArray> names = |
5863 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); | 5863 isolate->factory()->NewFixedArray(copy->NumberOfOwnProperties()); |
5864 copy->GetOwnPropertyNames(*names, 0); | 5864 copy->GetOwnPropertyNames(*names, 0); |
5865 for (int i = 0; i < names->length(); i++) { | 5865 for (int i = 0; i < names->length(); i++) { |
5866 ASSERT(names->get(i)->IsString()); | 5866 DCHECK(names->get(i)->IsString()); |
5867 Handle<String> key_string(String::cast(names->get(i))); | 5867 Handle<String> key_string(String::cast(names->get(i))); |
5868 Maybe<PropertyAttributes> maybe = | 5868 Maybe<PropertyAttributes> maybe = |
5869 JSReceiver::GetOwnPropertyAttributes(copy, key_string); | 5869 JSReceiver::GetOwnPropertyAttributes(copy, key_string); |
5870 ASSERT(maybe.has_value); | 5870 DCHECK(maybe.has_value); |
5871 PropertyAttributes attributes = maybe.value; | 5871 PropertyAttributes attributes = maybe.value; |
5872 // Only deep copy fields from the object literal expression. | 5872 // Only deep copy fields from the object literal expression. |
5873 // In particular, don't try to copy the length attribute of | 5873 // In particular, don't try to copy the length attribute of |
5874 // an array. | 5874 // an array. |
5875 if (attributes != NONE) continue; | 5875 if (attributes != NONE) continue; |
5876 Handle<Object> value = | 5876 Handle<Object> value = |
5877 Object::GetProperty(copy, key_string).ToHandleChecked(); | 5877 Object::GetProperty(copy, key_string).ToHandleChecked(); |
5878 if (value->IsJSObject()) { | 5878 if (value->IsJSObject()) { |
5879 Handle<JSObject> result; | 5879 Handle<JSObject> result; |
5880 ASSIGN_RETURN_ON_EXCEPTION( | 5880 ASSIGN_RETURN_ON_EXCEPTION( |
5881 isolate, result, | 5881 isolate, result, |
5882 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 5882 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
5883 JSObject); | 5883 JSObject); |
5884 if (copying) { | 5884 if (copying) { |
5885 // Creating object copy for literals. No strict mode needed. | 5885 // Creating object copy for literals. No strict mode needed. |
5886 JSObject::SetProperty(copy, key_string, result, SLOPPY).Assert(); | 5886 JSObject::SetProperty(copy, key_string, result, SLOPPY).Assert(); |
5887 } | 5887 } |
5888 } | 5888 } |
5889 } | 5889 } |
5890 } | 5890 } |
5891 | 5891 |
5892 // Deep copy own elements. | 5892 // Deep copy own elements. |
5893 // Pixel elements cannot be created using an object literal. | 5893 // Pixel elements cannot be created using an object literal. |
5894 ASSERT(!copy->HasExternalArrayElements()); | 5894 DCHECK(!copy->HasExternalArrayElements()); |
5895 switch (kind) { | 5895 switch (kind) { |
5896 case FAST_SMI_ELEMENTS: | 5896 case FAST_SMI_ELEMENTS: |
5897 case FAST_ELEMENTS: | 5897 case FAST_ELEMENTS: |
5898 case FAST_HOLEY_SMI_ELEMENTS: | 5898 case FAST_HOLEY_SMI_ELEMENTS: |
5899 case FAST_HOLEY_ELEMENTS: { | 5899 case FAST_HOLEY_ELEMENTS: { |
5900 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); | 5900 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); |
5901 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { | 5901 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { |
5902 #ifdef DEBUG | 5902 #ifdef DEBUG |
5903 for (int i = 0; i < elements->length(); i++) { | 5903 for (int i = 0; i < elements->length(); i++) { |
5904 ASSERT(!elements->get(i)->IsJSObject()); | 5904 DCHECK(!elements->get(i)->IsJSObject()); |
5905 } | 5905 } |
5906 #endif | 5906 #endif |
5907 } else { | 5907 } else { |
5908 for (int i = 0; i < elements->length(); i++) { | 5908 for (int i = 0; i < elements->length(); i++) { |
5909 Handle<Object> value(elements->get(i), isolate); | 5909 Handle<Object> value(elements->get(i), isolate); |
5910 ASSERT(value->IsSmi() || | 5910 DCHECK(value->IsSmi() || |
5911 value->IsTheHole() || | 5911 value->IsTheHole() || |
5912 (IsFastObjectElementsKind(copy->GetElementsKind()))); | 5912 (IsFastObjectElementsKind(copy->GetElementsKind()))); |
5913 if (value->IsJSObject()) { | 5913 if (value->IsJSObject()) { |
5914 Handle<JSObject> result; | 5914 Handle<JSObject> result; |
5915 ASSIGN_RETURN_ON_EXCEPTION( | 5915 ASSIGN_RETURN_ON_EXCEPTION( |
5916 isolate, result, | 5916 isolate, result, |
5917 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), | 5917 VisitElementOrProperty(copy, Handle<JSObject>::cast(value)), |
5918 JSObject); | 5918 JSObject); |
5919 if (copying) { | 5919 if (copying) { |
5920 elements->set(i, *result); | 5920 elements->set(i, *result); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5969 } | 5969 } |
5970 | 5970 |
5971 | 5971 |
5972 MaybeHandle<JSObject> JSObject::DeepWalk( | 5972 MaybeHandle<JSObject> JSObject::DeepWalk( |
5973 Handle<JSObject> object, | 5973 Handle<JSObject> object, |
5974 AllocationSiteCreationContext* site_context) { | 5974 AllocationSiteCreationContext* site_context) { |
5975 JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false, | 5975 JSObjectWalkVisitor<AllocationSiteCreationContext> v(site_context, false, |
5976 kNoHints); | 5976 kNoHints); |
5977 MaybeHandle<JSObject> result = v.StructureWalk(object); | 5977 MaybeHandle<JSObject> result = v.StructureWalk(object); |
5978 Handle<JSObject> for_assert; | 5978 Handle<JSObject> for_assert; |
5979 ASSERT(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object)); | 5979 DCHECK(!result.ToHandle(&for_assert) || for_assert.is_identical_to(object)); |
5980 return result; | 5980 return result; |
5981 } | 5981 } |
5982 | 5982 |
5983 | 5983 |
5984 MaybeHandle<JSObject> JSObject::DeepCopy( | 5984 MaybeHandle<JSObject> JSObject::DeepCopy( |
5985 Handle<JSObject> object, | 5985 Handle<JSObject> object, |
5986 AllocationSiteUsageContext* site_context, | 5986 AllocationSiteUsageContext* site_context, |
5987 DeepCopyHints hints) { | 5987 DeepCopyHints hints) { |
5988 JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints); | 5988 JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints); |
5989 MaybeHandle<JSObject> copy = v.StructureWalk(object); | 5989 MaybeHandle<JSObject> copy = v.StructureWalk(object); |
5990 Handle<JSObject> for_assert; | 5990 Handle<JSObject> for_assert; |
5991 ASSERT(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object)); | 5991 DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object)); |
5992 return copy; | 5992 return copy; |
5993 } | 5993 } |
5994 | 5994 |
5995 | 5995 |
5996 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object, | 5996 Handle<Object> JSObject::GetDataProperty(Handle<JSObject> object, |
5997 Handle<Name> key) { | 5997 Handle<Name> key) { |
5998 Isolate* isolate = object->GetIsolate(); | 5998 Isolate* isolate = object->GetIsolate(); |
5999 LookupResult lookup(isolate); | 5999 LookupResult lookup(isolate); |
6000 { | 6000 { |
6001 DisallowHeapAllocation no_allocation; | 6001 DisallowHeapAllocation no_allocation; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6035 // - No prototype has enumerable properties/elements. | 6035 // - No prototype has enumerable properties/elements. |
6036 bool JSReceiver::IsSimpleEnum() { | 6036 bool JSReceiver::IsSimpleEnum() { |
6037 for (PrototypeIterator iter(GetIsolate(), this, | 6037 for (PrototypeIterator iter(GetIsolate(), this, |
6038 PrototypeIterator::START_AT_RECEIVER); | 6038 PrototypeIterator::START_AT_RECEIVER); |
6039 !iter.IsAtEnd(); iter.Advance()) { | 6039 !iter.IsAtEnd(); iter.Advance()) { |
6040 if (!iter.GetCurrent()->IsJSObject()) return false; | 6040 if (!iter.GetCurrent()->IsJSObject()) return false; |
6041 JSObject* curr = JSObject::cast(iter.GetCurrent()); | 6041 JSObject* curr = JSObject::cast(iter.GetCurrent()); |
6042 int enum_length = curr->map()->EnumLength(); | 6042 int enum_length = curr->map()->EnumLength(); |
6043 if (enum_length == kInvalidEnumCacheSentinel) return false; | 6043 if (enum_length == kInvalidEnumCacheSentinel) return false; |
6044 if (curr->IsAccessCheckNeeded()) return false; | 6044 if (curr->IsAccessCheckNeeded()) return false; |
6045 ASSERT(!curr->HasNamedInterceptor()); | 6045 DCHECK(!curr->HasNamedInterceptor()); |
6046 ASSERT(!curr->HasIndexedInterceptor()); | 6046 DCHECK(!curr->HasIndexedInterceptor()); |
6047 if (curr->NumberOfEnumElements() > 0) return false; | 6047 if (curr->NumberOfEnumElements() > 0) return false; |
6048 if (curr != this && enum_length != 0) return false; | 6048 if (curr != this && enum_length != 0) return false; |
6049 } | 6049 } |
6050 return true; | 6050 return true; |
6051 } | 6051 } |
6052 | 6052 |
6053 | 6053 |
6054 static bool FilterKey(Object* key, PropertyAttributes filter) { | 6054 static bool FilterKey(Object* key, PropertyAttributes filter) { |
6055 if ((filter & SYMBOLIC) && key->IsSymbol()) { | 6055 if ((filter & SYMBOLIC) && key->IsSymbol()) { |
6056 return true; | 6056 return true; |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6096 if (current_index > max_index) max_index = current_index; | 6096 if (current_index > max_index) max_index = current_index; |
6097 } | 6097 } |
6098 } | 6098 } |
6099 return max_index + 1; | 6099 return max_index + 1; |
6100 } | 6100 } |
6101 | 6101 |
6102 | 6102 |
6103 void JSReceiver::LookupOwn( | 6103 void JSReceiver::LookupOwn( |
6104 Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) { | 6104 Handle<Name> name, LookupResult* result, bool search_hidden_prototypes) { |
6105 DisallowHeapAllocation no_gc; | 6105 DisallowHeapAllocation no_gc; |
6106 ASSERT(name->IsName()); | 6106 DCHECK(name->IsName()); |
6107 | 6107 |
6108 if (IsJSGlobalProxy()) { | 6108 if (IsJSGlobalProxy()) { |
6109 PrototypeIterator iter(GetIsolate(), this); | 6109 PrototypeIterator iter(GetIsolate(), this); |
6110 if (iter.IsAtEnd()) return result->NotFound(); | 6110 if (iter.IsAtEnd()) return result->NotFound(); |
6111 ASSERT(iter.GetCurrent()->IsJSGlobalObject()); | 6111 DCHECK(iter.GetCurrent()->IsJSGlobalObject()); |
6112 return JSReceiver::cast(iter.GetCurrent()) | 6112 return JSReceiver::cast(iter.GetCurrent()) |
6113 ->LookupOwn(name, result, search_hidden_prototypes); | 6113 ->LookupOwn(name, result, search_hidden_prototypes); |
6114 } | 6114 } |
6115 | 6115 |
6116 if (IsJSProxy()) { | 6116 if (IsJSProxy()) { |
6117 result->HandlerResult(JSProxy::cast(this)); | 6117 result->HandlerResult(JSProxy::cast(this)); |
6118 return; | 6118 return; |
6119 } | 6119 } |
6120 | 6120 |
6121 // Do not use inline caching if the object is a non-global object | 6121 // Do not use inline caching if the object is a non-global object |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6163 for (int i = 0; i < len; i++) { | 6163 for (int i = 0; i < len; i++) { |
6164 Object* e = array->get(i); | 6164 Object* e = array->get(i); |
6165 if (!(e->IsString() || e->IsNumber())) return false; | 6165 if (!(e->IsString() || e->IsNumber())) return false; |
6166 } | 6166 } |
6167 return true; | 6167 return true; |
6168 } | 6168 } |
6169 | 6169 |
6170 | 6170 |
6171 static Handle<FixedArray> ReduceFixedArrayTo( | 6171 static Handle<FixedArray> ReduceFixedArrayTo( |
6172 Handle<FixedArray> array, int length) { | 6172 Handle<FixedArray> array, int length) { |
6173 ASSERT(array->length() >= length); | 6173 DCHECK(array->length() >= length); |
6174 if (array->length() == length) return array; | 6174 if (array->length() == length) return array; |
6175 | 6175 |
6176 Handle<FixedArray> new_array = | 6176 Handle<FixedArray> new_array = |
6177 array->GetIsolate()->factory()->NewFixedArray(length); | 6177 array->GetIsolate()->factory()->NewFixedArray(length); |
6178 for (int i = 0; i < length; ++i) new_array->set(i, array->get(i)); | 6178 for (int i = 0; i < length; ++i) new_array->set(i, array->get(i)); |
6179 return new_array; | 6179 return new_array; |
6180 } | 6180 } |
6181 | 6181 |
6182 | 6182 |
6183 static Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, | 6183 static Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, |
6184 bool cache_result) { | 6184 bool cache_result) { |
6185 Isolate* isolate = object->GetIsolate(); | 6185 Isolate* isolate = object->GetIsolate(); |
6186 if (object->HasFastProperties()) { | 6186 if (object->HasFastProperties()) { |
6187 int own_property_count = object->map()->EnumLength(); | 6187 int own_property_count = object->map()->EnumLength(); |
6188 // If the enum length of the given map is set to kInvalidEnumCache, this | 6188 // If the enum length of the given map is set to kInvalidEnumCache, this |
6189 // means that the map itself has never used the present enum cache. The | 6189 // means that the map itself has never used the present enum cache. The |
6190 // first step to using the cache is to set the enum length of the map by | 6190 // first step to using the cache is to set the enum length of the map by |
6191 // counting the number of own descriptors that are not DONT_ENUM or | 6191 // counting the number of own descriptors that are not DONT_ENUM or |
6192 // SYMBOLIC. | 6192 // SYMBOLIC. |
6193 if (own_property_count == kInvalidEnumCacheSentinel) { | 6193 if (own_property_count == kInvalidEnumCacheSentinel) { |
6194 own_property_count = object->map()->NumberOfDescribedProperties( | 6194 own_property_count = object->map()->NumberOfDescribedProperties( |
6195 OWN_DESCRIPTORS, DONT_SHOW); | 6195 OWN_DESCRIPTORS, DONT_SHOW); |
6196 } else { | 6196 } else { |
6197 ASSERT(own_property_count == object->map()->NumberOfDescribedProperties( | 6197 DCHECK(own_property_count == object->map()->NumberOfDescribedProperties( |
6198 OWN_DESCRIPTORS, DONT_SHOW)); | 6198 OWN_DESCRIPTORS, DONT_SHOW)); |
6199 } | 6199 } |
6200 | 6200 |
6201 if (object->map()->instance_descriptors()->HasEnumCache()) { | 6201 if (object->map()->instance_descriptors()->HasEnumCache()) { |
6202 DescriptorArray* desc = object->map()->instance_descriptors(); | 6202 DescriptorArray* desc = object->map()->instance_descriptors(); |
6203 Handle<FixedArray> keys(desc->GetEnumCache(), isolate); | 6203 Handle<FixedArray> keys(desc->GetEnumCache(), isolate); |
6204 | 6204 |
6205 // In case the number of properties required in the enum are actually | 6205 // In case the number of properties required in the enum are actually |
6206 // present, we can reuse the enum cache. Otherwise, this means that the | 6206 // present, we can reuse the enum cache. Otherwise, this means that the |
6207 // enum cache was generated for a previous (smaller) version of the | 6207 // enum cache was generated for a previous (smaller) version of the |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6244 indices = Handle<FixedArray>(); | 6244 indices = Handle<FixedArray>(); |
6245 } else { | 6245 } else { |
6246 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i); | 6246 FieldIndex field_index = FieldIndex::ForDescriptor(*map, i); |
6247 int load_by_field_index = field_index.GetLoadByFieldIndex(); | 6247 int load_by_field_index = field_index.GetLoadByFieldIndex(); |
6248 indices->set(index, Smi::FromInt(load_by_field_index)); | 6248 indices->set(index, Smi::FromInt(load_by_field_index)); |
6249 } | 6249 } |
6250 } | 6250 } |
6251 index++; | 6251 index++; |
6252 } | 6252 } |
6253 } | 6253 } |
6254 ASSERT(index == storage->length()); | 6254 DCHECK(index == storage->length()); |
6255 | 6255 |
6256 Handle<FixedArray> bridge_storage = | 6256 Handle<FixedArray> bridge_storage = |
6257 isolate->factory()->NewFixedArray( | 6257 isolate->factory()->NewFixedArray( |
6258 DescriptorArray::kEnumCacheBridgeLength); | 6258 DescriptorArray::kEnumCacheBridgeLength); |
6259 DescriptorArray* desc = object->map()->instance_descriptors(); | 6259 DescriptorArray* desc = object->map()->instance_descriptors(); |
6260 desc->SetEnumCache(*bridge_storage, | 6260 desc->SetEnumCache(*bridge_storage, |
6261 *storage, | 6261 *storage, |
6262 indices.is_null() ? Object::cast(Smi::FromInt(0)) | 6262 indices.is_null() ? Object::cast(Smi::FromInt(0)) |
6263 : Object::cast(*indices)); | 6263 : Object::cast(*indices)); |
6264 if (cache_result) { | 6264 if (cache_result) { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6324 } | 6324 } |
6325 | 6325 |
6326 // Compute the element keys. | 6326 // Compute the element keys. |
6327 Handle<FixedArray> element_keys = | 6327 Handle<FixedArray> element_keys = |
6328 isolate->factory()->NewFixedArray(current->NumberOfEnumElements()); | 6328 isolate->factory()->NewFixedArray(current->NumberOfEnumElements()); |
6329 current->GetEnumElementKeys(*element_keys); | 6329 current->GetEnumElementKeys(*element_keys); |
6330 ASSIGN_RETURN_ON_EXCEPTION( | 6330 ASSIGN_RETURN_ON_EXCEPTION( |
6331 isolate, content, | 6331 isolate, content, |
6332 FixedArray::UnionOfKeys(content, element_keys), | 6332 FixedArray::UnionOfKeys(content, element_keys), |
6333 FixedArray); | 6333 FixedArray); |
6334 ASSERT(ContainsOnlyValidKeys(content)); | 6334 DCHECK(ContainsOnlyValidKeys(content)); |
6335 | 6335 |
6336 // Add the element keys from the interceptor. | 6336 // Add the element keys from the interceptor. |
6337 if (current->HasIndexedInterceptor()) { | 6337 if (current->HasIndexedInterceptor()) { |
6338 Handle<JSObject> result; | 6338 Handle<JSObject> result; |
6339 if (JSObject::GetKeysForIndexedInterceptor( | 6339 if (JSObject::GetKeysForIndexedInterceptor( |
6340 current, object).ToHandle(&result)) { | 6340 current, object).ToHandle(&result)) { |
6341 ASSIGN_RETURN_ON_EXCEPTION( | 6341 ASSIGN_RETURN_ON_EXCEPTION( |
6342 isolate, content, | 6342 isolate, content, |
6343 FixedArray::AddKeysFromArrayLike(content, result), | 6343 FixedArray::AddKeysFromArrayLike(content, result), |
6344 FixedArray); | 6344 FixedArray); |
6345 } | 6345 } |
6346 ASSERT(ContainsOnlyValidKeys(content)); | 6346 DCHECK(ContainsOnlyValidKeys(content)); |
6347 } | 6347 } |
6348 | 6348 |
6349 // We can cache the computed property keys if access checks are | 6349 // We can cache the computed property keys if access checks are |
6350 // not needed and no interceptors are involved. | 6350 // not needed and no interceptors are involved. |
6351 // | 6351 // |
6352 // We do not use the cache if the object has elements and | 6352 // We do not use the cache if the object has elements and |
6353 // therefore it does not make sense to cache the property names | 6353 // therefore it does not make sense to cache the property names |
6354 // for arguments objects. Arguments objects will always have | 6354 // for arguments objects. Arguments objects will always have |
6355 // elements. | 6355 // elements. |
6356 // Wrapped strings have elements, but don't have an elements | 6356 // Wrapped strings have elements, but don't have an elements |
6357 // array or dictionary. So the fast inline test for whether to | 6357 // array or dictionary. So the fast inline test for whether to |
6358 // use the cache says yes, so we should not create a cache. | 6358 // use the cache says yes, so we should not create a cache. |
6359 bool cache_enum_keys = | 6359 bool cache_enum_keys = |
6360 ((current->map()->constructor() != *arguments_function) && | 6360 ((current->map()->constructor() != *arguments_function) && |
6361 !current->IsJSValue() && | 6361 !current->IsJSValue() && |
6362 !current->IsAccessCheckNeeded() && | 6362 !current->IsAccessCheckNeeded() && |
6363 !current->HasNamedInterceptor() && | 6363 !current->HasNamedInterceptor() && |
6364 !current->HasIndexedInterceptor()); | 6364 !current->HasIndexedInterceptor()); |
6365 // Compute the property keys and cache them if possible. | 6365 // Compute the property keys and cache them if possible. |
6366 ASSIGN_RETURN_ON_EXCEPTION( | 6366 ASSIGN_RETURN_ON_EXCEPTION( |
6367 isolate, content, | 6367 isolate, content, |
6368 FixedArray::UnionOfKeys( | 6368 FixedArray::UnionOfKeys( |
6369 content, GetEnumPropertyKeys(current, cache_enum_keys)), | 6369 content, GetEnumPropertyKeys(current, cache_enum_keys)), |
6370 FixedArray); | 6370 FixedArray); |
6371 ASSERT(ContainsOnlyValidKeys(content)); | 6371 DCHECK(ContainsOnlyValidKeys(content)); |
6372 | 6372 |
6373 // Add the property keys from the interceptor. | 6373 // Add the property keys from the interceptor. |
6374 if (current->HasNamedInterceptor()) { | 6374 if (current->HasNamedInterceptor()) { |
6375 Handle<JSObject> result; | 6375 Handle<JSObject> result; |
6376 if (JSObject::GetKeysForNamedInterceptor( | 6376 if (JSObject::GetKeysForNamedInterceptor( |
6377 current, object).ToHandle(&result)) { | 6377 current, object).ToHandle(&result)) { |
6378 ASSIGN_RETURN_ON_EXCEPTION( | 6378 ASSIGN_RETURN_ON_EXCEPTION( |
6379 isolate, content, | 6379 isolate, content, |
6380 FixedArray::AddKeysFromArrayLike(content, result), | 6380 FixedArray::AddKeysFromArrayLike(content, result), |
6381 FixedArray); | 6381 FixedArray); |
6382 } | 6382 } |
6383 ASSERT(ContainsOnlyValidKeys(content)); | 6383 DCHECK(ContainsOnlyValidKeys(content)); |
6384 } | 6384 } |
6385 | 6385 |
6386 // If we only want own properties we bail out after the first | 6386 // If we only want own properties we bail out after the first |
6387 // iteration. | 6387 // iteration. |
6388 if (type == OWN_ONLY) break; | 6388 if (type == OWN_ONLY) break; |
6389 } | 6389 } |
6390 return content; | 6390 return content; |
6391 } | 6391 } |
6392 | 6392 |
6393 | 6393 |
6394 // Try to update an accessor in an elements dictionary. Return true if the | 6394 // Try to update an accessor in an elements dictionary. Return true if the |
6395 // update succeeded, and false otherwise. | 6395 // update succeeded, and false otherwise. |
6396 static bool UpdateGetterSetterInDictionary( | 6396 static bool UpdateGetterSetterInDictionary( |
6397 SeededNumberDictionary* dictionary, | 6397 SeededNumberDictionary* dictionary, |
6398 uint32_t index, | 6398 uint32_t index, |
6399 Object* getter, | 6399 Object* getter, |
6400 Object* setter, | 6400 Object* setter, |
6401 PropertyAttributes attributes) { | 6401 PropertyAttributes attributes) { |
6402 int entry = dictionary->FindEntry(index); | 6402 int entry = dictionary->FindEntry(index); |
6403 if (entry != SeededNumberDictionary::kNotFound) { | 6403 if (entry != SeededNumberDictionary::kNotFound) { |
6404 Object* result = dictionary->ValueAt(entry); | 6404 Object* result = dictionary->ValueAt(entry); |
6405 PropertyDetails details = dictionary->DetailsAt(entry); | 6405 PropertyDetails details = dictionary->DetailsAt(entry); |
6406 if (details.type() == CALLBACKS && result->IsAccessorPair()) { | 6406 if (details.type() == CALLBACKS && result->IsAccessorPair()) { |
6407 ASSERT(!details.IsDontDelete()); | 6407 DCHECK(!details.IsDontDelete()); |
6408 if (details.attributes() != attributes) { | 6408 if (details.attributes() != attributes) { |
6409 dictionary->DetailsAtPut( | 6409 dictionary->DetailsAtPut( |
6410 entry, | 6410 entry, |
6411 PropertyDetails(attributes, CALLBACKS, index)); | 6411 PropertyDetails(attributes, CALLBACKS, index)); |
6412 } | 6412 } |
6413 AccessorPair::cast(result)->SetComponents(getter, setter); | 6413 AccessorPair::cast(result)->SetComponents(getter, setter); |
6414 return true; | 6414 return true; |
6415 } | 6415 } |
6416 } | 6416 } |
6417 return false; | 6417 return false; |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6553 void JSObject::SetElementCallback(Handle<JSObject> object, | 6553 void JSObject::SetElementCallback(Handle<JSObject> object, |
6554 uint32_t index, | 6554 uint32_t index, |
6555 Handle<Object> structure, | 6555 Handle<Object> structure, |
6556 PropertyAttributes attributes) { | 6556 PropertyAttributes attributes) { |
6557 Heap* heap = object->GetHeap(); | 6557 Heap* heap = object->GetHeap(); |
6558 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6558 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
6559 | 6559 |
6560 // Normalize elements to make this operation simple. | 6560 // Normalize elements to make this operation simple. |
6561 bool had_dictionary_elements = object->HasDictionaryElements(); | 6561 bool had_dictionary_elements = object->HasDictionaryElements(); |
6562 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); | 6562 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object); |
6563 ASSERT(object->HasDictionaryElements() || | 6563 DCHECK(object->HasDictionaryElements() || |
6564 object->HasDictionaryArgumentsElements()); | 6564 object->HasDictionaryArgumentsElements()); |
6565 // Update the dictionary with the new CALLBACKS property. | 6565 // Update the dictionary with the new CALLBACKS property. |
6566 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, | 6566 dictionary = SeededNumberDictionary::Set(dictionary, index, structure, |
6567 details); | 6567 details); |
6568 dictionary->set_requires_slow_elements(); | 6568 dictionary->set_requires_slow_elements(); |
6569 | 6569 |
6570 // Update the dictionary backing store on the object. | 6570 // Update the dictionary backing store on the object. |
6571 if (object->elements()->map() == heap->sloppy_arguments_elements_map()) { | 6571 if (object->elements()->map() == heap->sloppy_arguments_elements_map()) { |
6572 // Also delete any parameter alias. | 6572 // Also delete any parameter alias. |
6573 // | 6573 // |
(...skipping 20 matching lines...) Expand all Loading... |
6594 Handle<Name> name, | 6594 Handle<Name> name, |
6595 Handle<Object> structure, | 6595 Handle<Object> structure, |
6596 PropertyAttributes attributes) { | 6596 PropertyAttributes attributes) { |
6597 // Normalize object to make this operation simple. | 6597 // Normalize object to make this operation simple. |
6598 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 6598 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); |
6599 | 6599 |
6600 // For the global object allocate a new map to invalidate the global inline | 6600 // For the global object allocate a new map to invalidate the global inline |
6601 // caches which have a global property cell reference directly in the code. | 6601 // caches which have a global property cell reference directly in the code. |
6602 if (object->IsGlobalObject()) { | 6602 if (object->IsGlobalObject()) { |
6603 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); | 6603 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map())); |
6604 ASSERT(new_map->is_dictionary_map()); | 6604 DCHECK(new_map->is_dictionary_map()); |
6605 JSObject::MigrateToMap(object, new_map); | 6605 JSObject::MigrateToMap(object, new_map); |
6606 | 6606 |
6607 // When running crankshaft, changing the map is not enough. We | 6607 // When running crankshaft, changing the map is not enough. We |
6608 // need to deoptimize all functions that rely on this global | 6608 // need to deoptimize all functions that rely on this global |
6609 // object. | 6609 // object. |
6610 Deoptimizer::DeoptimizeGlobalObject(*object); | 6610 Deoptimizer::DeoptimizeGlobalObject(*object); |
6611 } | 6611 } |
6612 | 6612 |
6613 // Update the dictionary with the new CALLBACKS property. | 6613 // Update the dictionary with the new CALLBACKS property. |
6614 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); | 6614 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); |
(...skipping 11 matching lines...) Expand all Loading... |
6626 if (object->IsAccessCheckNeeded() && | 6626 if (object->IsAccessCheckNeeded() && |
6627 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 6627 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
6628 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 6628 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
6629 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 6629 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
6630 return isolate->factory()->undefined_value(); | 6630 return isolate->factory()->undefined_value(); |
6631 } | 6631 } |
6632 | 6632 |
6633 if (object->IsJSGlobalProxy()) { | 6633 if (object->IsJSGlobalProxy()) { |
6634 PrototypeIterator iter(isolate, object); | 6634 PrototypeIterator iter(isolate, object); |
6635 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); | 6635 if (iter.IsAtEnd()) return isolate->factory()->undefined_value(); |
6636 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 6636 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
6637 DefineAccessor(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), | 6637 DefineAccessor(Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), |
6638 name, getter, setter, attributes); | 6638 name, getter, setter, attributes); |
6639 return isolate->factory()->undefined_value(); | 6639 return isolate->factory()->undefined_value(); |
6640 } | 6640 } |
6641 | 6641 |
6642 // Make sure that the top context does not change when doing callbacks or | 6642 // Make sure that the top context does not change when doing callbacks or |
6643 // interceptor calls. | 6643 // interceptor calls. |
6644 AssertNoContextChange ncc(isolate); | 6644 AssertNoContextChange ncc(isolate); |
6645 | 6645 |
6646 // Try to flatten before operating on the string. | 6646 // Try to flatten before operating on the string. |
6647 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 6647 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
6648 | 6648 |
6649 uint32_t index = 0; | 6649 uint32_t index = 0; |
6650 bool is_element = name->AsArrayIndex(&index); | 6650 bool is_element = name->AsArrayIndex(&index); |
6651 | 6651 |
6652 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 6652 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
6653 bool is_observed = object->map()->is_observed() && | 6653 bool is_observed = object->map()->is_observed() && |
6654 *name != isolate->heap()->hidden_string(); | 6654 *name != isolate->heap()->hidden_string(); |
6655 bool preexists = false; | 6655 bool preexists = false; |
6656 if (is_observed) { | 6656 if (is_observed) { |
6657 if (is_element) { | 6657 if (is_element) { |
6658 Maybe<bool> maybe = HasOwnElement(object, index); | 6658 Maybe<bool> maybe = HasOwnElement(object, index); |
6659 // Workaround for a GCC 4.4.3 bug which leads to "‘preexists’ may be used | 6659 // Workaround for a GCC 4.4.3 bug which leads to "‘preexists’ may be used |
6660 // uninitialized in this function". | 6660 // uninitialized in this function". |
6661 if (!maybe.has_value) { | 6661 if (!maybe.has_value) { |
6662 ASSERT(false); | 6662 DCHECK(false); |
6663 return isolate->factory()->undefined_value(); | 6663 return isolate->factory()->undefined_value(); |
6664 } | 6664 } |
6665 preexists = maybe.value; | 6665 preexists = maybe.value; |
6666 if (preexists && GetOwnElementAccessorPair(object, index).is_null()) { | 6666 if (preexists && GetOwnElementAccessorPair(object, index).is_null()) { |
6667 old_value = | 6667 old_value = |
6668 Object::GetElement(isolate, object, index).ToHandleChecked(); | 6668 Object::GetElement(isolate, object, index).ToHandleChecked(); |
6669 } | 6669 } |
6670 } else { | 6670 } else { |
6671 LookupResult lookup(isolate); | 6671 LookupResult lookup(isolate); |
6672 object->LookupOwn(name, &lookup, true); | 6672 object->LookupOwn(name, &lookup, true); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6720 // the slow case. | 6720 // the slow case. |
6721 return false; | 6721 return false; |
6722 } | 6722 } |
6723 | 6723 |
6724 | 6724 |
6725 bool JSObject::DefineFastAccessor(Handle<JSObject> object, | 6725 bool JSObject::DefineFastAccessor(Handle<JSObject> object, |
6726 Handle<Name> name, | 6726 Handle<Name> name, |
6727 AccessorComponent component, | 6727 AccessorComponent component, |
6728 Handle<Object> accessor, | 6728 Handle<Object> accessor, |
6729 PropertyAttributes attributes) { | 6729 PropertyAttributes attributes) { |
6730 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); | 6730 DCHECK(accessor->IsSpecFunction() || accessor->IsUndefined()); |
6731 Isolate* isolate = object->GetIsolate(); | 6731 Isolate* isolate = object->GetIsolate(); |
6732 LookupResult result(isolate); | 6732 LookupResult result(isolate); |
6733 object->LookupOwn(name, &result); | 6733 object->LookupOwn(name, &result); |
6734 | 6734 |
6735 if (result.IsFound() && !result.IsPropertyCallbacks()) { | 6735 if (result.IsFound() && !result.IsPropertyCallbacks()) { |
6736 return false; | 6736 return false; |
6737 } | 6737 } |
6738 | 6738 |
6739 // Return success if the same accessor with the same attributes already exist. | 6739 // Return success if the same accessor with the same attributes already exist. |
6740 AccessorPair* source_accessors = NULL; | 6740 AccessorPair* source_accessors = NULL; |
6741 if (result.IsPropertyCallbacks()) { | 6741 if (result.IsPropertyCallbacks()) { |
6742 Object* callback_value = result.GetCallbackObject(); | 6742 Object* callback_value = result.GetCallbackObject(); |
6743 if (callback_value->IsAccessorPair()) { | 6743 if (callback_value->IsAccessorPair()) { |
6744 source_accessors = AccessorPair::cast(callback_value); | 6744 source_accessors = AccessorPair::cast(callback_value); |
6745 Object* entry = source_accessors->get(component); | 6745 Object* entry = source_accessors->get(component); |
6746 if (entry == *accessor && result.GetAttributes() == attributes) { | 6746 if (entry == *accessor && result.GetAttributes() == attributes) { |
6747 return true; | 6747 return true; |
6748 } | 6748 } |
6749 } else { | 6749 } else { |
6750 return false; | 6750 return false; |
6751 } | 6751 } |
6752 | 6752 |
6753 int descriptor_number = result.GetDescriptorIndex(); | 6753 int descriptor_number = result.GetDescriptorIndex(); |
6754 | 6754 |
6755 object->map()->LookupTransition(*object, *name, &result); | 6755 object->map()->LookupTransition(*object, *name, &result); |
6756 | 6756 |
6757 if (result.IsFound()) { | 6757 if (result.IsFound()) { |
6758 Handle<Map> target(result.GetTransitionTarget()); | 6758 Handle<Map> target(result.GetTransitionTarget()); |
6759 ASSERT(target->NumberOfOwnDescriptors() == | 6759 DCHECK(target->NumberOfOwnDescriptors() == |
6760 object->map()->NumberOfOwnDescriptors()); | 6760 object->map()->NumberOfOwnDescriptors()); |
6761 // This works since descriptors are sorted in order of addition. | 6761 // This works since descriptors are sorted in order of addition. |
6762 ASSERT(Name::Equals( | 6762 DCHECK(Name::Equals( |
6763 handle(object->map()->instance_descriptors()->GetKey( | 6763 handle(object->map()->instance_descriptors()->GetKey( |
6764 descriptor_number)), | 6764 descriptor_number)), |
6765 name)); | 6765 name)); |
6766 return TryAccessorTransition(object, target, descriptor_number, | 6766 return TryAccessorTransition(object, target, descriptor_number, |
6767 component, accessor, attributes); | 6767 component, accessor, attributes); |
6768 } | 6768 } |
6769 } else { | 6769 } else { |
6770 // If not, lookup a transition. | 6770 // If not, lookup a transition. |
6771 object->map()->LookupTransition(*object, *name, &result); | 6771 object->map()->LookupTransition(*object, *name, &result); |
6772 | 6772 |
6773 // If there is a transition, try to follow it. | 6773 // If there is a transition, try to follow it. |
6774 if (result.IsFound()) { | 6774 if (result.IsFound()) { |
6775 Handle<Map> target(result.GetTransitionTarget()); | 6775 Handle<Map> target(result.GetTransitionTarget()); |
6776 int descriptor_number = target->LastAdded(); | 6776 int descriptor_number = target->LastAdded(); |
6777 ASSERT(Name::Equals(name, | 6777 DCHECK(Name::Equals(name, |
6778 handle(target->instance_descriptors()->GetKey(descriptor_number)))); | 6778 handle(target->instance_descriptors()->GetKey(descriptor_number)))); |
6779 return TryAccessorTransition(object, target, descriptor_number, | 6779 return TryAccessorTransition(object, target, descriptor_number, |
6780 component, accessor, attributes); | 6780 component, accessor, attributes); |
6781 } | 6781 } |
6782 } | 6782 } |
6783 | 6783 |
6784 // If there is no transition yet, add a transition to the a new accessor pair | 6784 // If there is no transition yet, add a transition to the a new accessor pair |
6785 // containing the accessor. Allocate a new pair if there were no source | 6785 // containing the accessor. Allocate a new pair if there were no source |
6786 // accessors. Otherwise, copy the pair and modify the accessor. | 6786 // accessors. Otherwise, copy the pair and modify the accessor. |
6787 Handle<AccessorPair> accessors = source_accessors != NULL | 6787 Handle<AccessorPair> accessors = source_accessors != NULL |
(...skipping 20 matching lines...) Expand all Loading... |
6808 if (object->IsAccessCheckNeeded() && | 6808 if (object->IsAccessCheckNeeded() && |
6809 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { | 6809 !isolate->MayNamedAccess(object, name, v8::ACCESS_SET)) { |
6810 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 6810 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
6811 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 6811 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
6812 return factory->undefined_value(); | 6812 return factory->undefined_value(); |
6813 } | 6813 } |
6814 | 6814 |
6815 if (object->IsJSGlobalProxy()) { | 6815 if (object->IsJSGlobalProxy()) { |
6816 PrototypeIterator iter(isolate, object); | 6816 PrototypeIterator iter(isolate, object); |
6817 if (iter.IsAtEnd()) return object; | 6817 if (iter.IsAtEnd()) return object; |
6818 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 6818 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
6819 return SetAccessor( | 6819 return SetAccessor( |
6820 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), info); | 6820 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), info); |
6821 } | 6821 } |
6822 | 6822 |
6823 // Make sure that the top context does not change when doing callbacks or | 6823 // Make sure that the top context does not change when doing callbacks or |
6824 // interceptor calls. | 6824 // interceptor calls. |
6825 AssertNoContextChange ncc(isolate); | 6825 AssertNoContextChange ncc(isolate); |
6826 | 6826 |
6827 // Try to flatten before operating on the string. | 6827 // Try to flatten before operating on the string. |
6828 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); | 6828 if (name->IsString()) name = String::Flatten(Handle<String>::cast(name)); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6943 | 6943 |
6944 Object* JSObject::SlowReverseLookup(Object* value) { | 6944 Object* JSObject::SlowReverseLookup(Object* value) { |
6945 if (HasFastProperties()) { | 6945 if (HasFastProperties()) { |
6946 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); | 6946 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); |
6947 DescriptorArray* descs = map()->instance_descriptors(); | 6947 DescriptorArray* descs = map()->instance_descriptors(); |
6948 for (int i = 0; i < number_of_own_descriptors; i++) { | 6948 for (int i = 0; i < number_of_own_descriptors; i++) { |
6949 if (descs->GetType(i) == FIELD) { | 6949 if (descs->GetType(i) == FIELD) { |
6950 Object* property = | 6950 Object* property = |
6951 RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i)); | 6951 RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i)); |
6952 if (descs->GetDetails(i).representation().IsDouble()) { | 6952 if (descs->GetDetails(i).representation().IsDouble()) { |
6953 ASSERT(property->IsMutableHeapNumber()); | 6953 DCHECK(property->IsMutableHeapNumber()); |
6954 if (value->IsNumber() && property->Number() == value->Number()) { | 6954 if (value->IsNumber() && property->Number() == value->Number()) { |
6955 return descs->GetKey(i); | 6955 return descs->GetKey(i); |
6956 } | 6956 } |
6957 } else if (property == value) { | 6957 } else if (property == value) { |
6958 return descs->GetKey(i); | 6958 return descs->GetKey(i); |
6959 } | 6959 } |
6960 } else if (descs->GetType(i) == CONSTANT) { | 6960 } else if (descs->GetType(i) == CONSTANT) { |
6961 if (descs->GetConstant(i) == value) { | 6961 if (descs->GetConstant(i) == value) { |
6962 return descs->GetKey(i); | 6962 return descs->GetKey(i); |
6963 } | 6963 } |
(...skipping 24 matching lines...) Expand all Loading... |
6988 } | 6988 } |
6989 new_bit_field3 = ConstructionCount::update(new_bit_field3, | 6989 new_bit_field3 = ConstructionCount::update(new_bit_field3, |
6990 JSFunction::kNoSlackTracking); | 6990 JSFunction::kNoSlackTracking); |
6991 result->set_bit_field3(new_bit_field3); | 6991 result->set_bit_field3(new_bit_field3); |
6992 return result; | 6992 return result; |
6993 } | 6993 } |
6994 | 6994 |
6995 | 6995 |
6996 Handle<Map> Map::Normalize(Handle<Map> fast_map, | 6996 Handle<Map> Map::Normalize(Handle<Map> fast_map, |
6997 PropertyNormalizationMode mode) { | 6997 PropertyNormalizationMode mode) { |
6998 ASSERT(!fast_map->is_dictionary_map()); | 6998 DCHECK(!fast_map->is_dictionary_map()); |
6999 | 6999 |
7000 Isolate* isolate = fast_map->GetIsolate(); | 7000 Isolate* isolate = fast_map->GetIsolate(); |
7001 Handle<NormalizedMapCache> cache( | 7001 Handle<NormalizedMapCache> cache( |
7002 isolate->context()->native_context()->normalized_map_cache()); | 7002 isolate->context()->native_context()->normalized_map_cache()); |
7003 | 7003 |
7004 Handle<Map> new_map; | 7004 Handle<Map> new_map; |
7005 if (cache->Get(fast_map, mode).ToHandle(&new_map)) { | 7005 if (cache->Get(fast_map, mode).ToHandle(&new_map)) { |
7006 #ifdef VERIFY_HEAP | 7006 #ifdef VERIFY_HEAP |
7007 if (FLAG_verify_heap) { | 7007 if (FLAG_verify_heap) { |
7008 new_map->SharedMapVerify(); | 7008 new_map->SharedMapVerify(); |
7009 } | 7009 } |
7010 #endif | 7010 #endif |
7011 #ifdef ENABLE_SLOW_ASSERTS | 7011 #ifdef ENABLE_SLOW_DCHECKS |
7012 if (FLAG_enable_slow_asserts) { | 7012 if (FLAG_enable_slow_asserts) { |
7013 // The cached map should match newly created normalized map bit-by-bit, | 7013 // The cached map should match newly created normalized map bit-by-bit, |
7014 // except for the code cache, which can contain some ics which can be | 7014 // except for the code cache, which can contain some ics which can be |
7015 // applied to the shared map. | 7015 // applied to the shared map. |
7016 Handle<Map> fresh = Map::CopyNormalized( | 7016 Handle<Map> fresh = Map::CopyNormalized( |
7017 fast_map, mode, SHARED_NORMALIZED_MAP); | 7017 fast_map, mode, SHARED_NORMALIZED_MAP); |
7018 | 7018 |
7019 ASSERT(memcmp(fresh->address(), | 7019 DCHECK(memcmp(fresh->address(), |
7020 new_map->address(), | 7020 new_map->address(), |
7021 Map::kCodeCacheOffset) == 0); | 7021 Map::kCodeCacheOffset) == 0); |
7022 STATIC_ASSERT(Map::kDependentCodeOffset == | 7022 STATIC_ASSERT(Map::kDependentCodeOffset == |
7023 Map::kCodeCacheOffset + kPointerSize); | 7023 Map::kCodeCacheOffset + kPointerSize); |
7024 int offset = Map::kDependentCodeOffset + kPointerSize; | 7024 int offset = Map::kDependentCodeOffset + kPointerSize; |
7025 ASSERT(memcmp(fresh->address() + offset, | 7025 DCHECK(memcmp(fresh->address() + offset, |
7026 new_map->address() + offset, | 7026 new_map->address() + offset, |
7027 Map::kSize - offset) == 0); | 7027 Map::kSize - offset) == 0); |
7028 } | 7028 } |
7029 #endif | 7029 #endif |
7030 } else { | 7030 } else { |
7031 new_map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP); | 7031 new_map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP); |
7032 cache->Set(fast_map, new_map); | 7032 cache->Set(fast_map, new_map); |
7033 isolate->counters()->normalized_maps()->Increment(); | 7033 isolate->counters()->normalized_maps()->Increment(); |
7034 } | 7034 } |
7035 fast_map->NotifyLeafMapLayoutChange(); | 7035 fast_map->NotifyLeafMapLayoutChange(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7080 return result; | 7080 return result; |
7081 } | 7081 } |
7082 | 7082 |
7083 | 7083 |
7084 Handle<Map> Map::ShareDescriptor(Handle<Map> map, | 7084 Handle<Map> Map::ShareDescriptor(Handle<Map> map, |
7085 Handle<DescriptorArray> descriptors, | 7085 Handle<DescriptorArray> descriptors, |
7086 Descriptor* descriptor) { | 7086 Descriptor* descriptor) { |
7087 // Sanity check. This path is only to be taken if the map owns its descriptor | 7087 // Sanity check. This path is only to be taken if the map owns its descriptor |
7088 // array, implying that its NumberOfOwnDescriptors equals the number of | 7088 // array, implying that its NumberOfOwnDescriptors equals the number of |
7089 // descriptors in the descriptor array. | 7089 // descriptors in the descriptor array. |
7090 ASSERT(map->NumberOfOwnDescriptors() == | 7090 DCHECK(map->NumberOfOwnDescriptors() == |
7091 map->instance_descriptors()->number_of_descriptors()); | 7091 map->instance_descriptors()->number_of_descriptors()); |
7092 | 7092 |
7093 Handle<Map> result = CopyDropDescriptors(map); | 7093 Handle<Map> result = CopyDropDescriptors(map); |
7094 Handle<Name> name = descriptor->GetKey(); | 7094 Handle<Name> name = descriptor->GetKey(); |
7095 Handle<TransitionArray> transitions = | 7095 Handle<TransitionArray> transitions = |
7096 TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION); | 7096 TransitionArray::CopyInsert(map, name, result, SIMPLE_TRANSITION); |
7097 | 7097 |
7098 // Ensure there's space for the new descriptor in the shared descriptor array. | 7098 // Ensure there's space for the new descriptor in the shared descriptor array. |
7099 if (descriptors->NumberOfSlackDescriptors() == 0) { | 7099 if (descriptors->NumberOfSlackDescriptors() == 0) { |
7100 int old_size = descriptors->number_of_descriptors(); | 7100 int old_size = descriptors->number_of_descriptors(); |
7101 if (old_size == 0) { | 7101 if (old_size == 0) { |
7102 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); | 7102 descriptors = DescriptorArray::Allocate(map->GetIsolate(), 0, 1); |
7103 } else { | 7103 } else { |
7104 EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); | 7104 EnsureDescriptorSlack(map, old_size < 4 ? 1 : old_size / 2); |
7105 descriptors = handle(map->instance_descriptors()); | 7105 descriptors = handle(map->instance_descriptors()); |
7106 } | 7106 } |
7107 } | 7107 } |
7108 | 7108 |
7109 // Commit the state atomically. | 7109 // Commit the state atomically. |
7110 DisallowHeapAllocation no_gc; | 7110 DisallowHeapAllocation no_gc; |
7111 | 7111 |
7112 descriptors->Append(descriptor); | 7112 descriptors->Append(descriptor); |
7113 result->SetBackPointer(*map); | 7113 result->SetBackPointer(*map); |
7114 result->InitializeDescriptors(*descriptors); | 7114 result->InitializeDescriptors(*descriptors); |
7115 | 7115 |
7116 ASSERT(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); | 7116 DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1); |
7117 | 7117 |
7118 map->set_transitions(*transitions); | 7118 map->set_transitions(*transitions); |
7119 map->set_owns_descriptors(false); | 7119 map->set_owns_descriptors(false); |
7120 | 7120 |
7121 return result; | 7121 return result; |
7122 } | 7122 } |
7123 | 7123 |
7124 | 7124 |
7125 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, | 7125 Handle<Map> Map::CopyReplaceDescriptors(Handle<Map> map, |
7126 Handle<DescriptorArray> descriptors, | 7126 Handle<DescriptorArray> descriptors, |
7127 TransitionFlag flag, | 7127 TransitionFlag flag, |
7128 MaybeHandle<Name> maybe_name, | 7128 MaybeHandle<Name> maybe_name, |
7129 SimpleTransitionFlag simple_flag) { | 7129 SimpleTransitionFlag simple_flag) { |
7130 ASSERT(descriptors->IsSortedNoDuplicates()); | 7130 DCHECK(descriptors->IsSortedNoDuplicates()); |
7131 | 7131 |
7132 Handle<Map> result = CopyDropDescriptors(map); | 7132 Handle<Map> result = CopyDropDescriptors(map); |
7133 result->InitializeDescriptors(*descriptors); | 7133 result->InitializeDescriptors(*descriptors); |
7134 | 7134 |
7135 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { | 7135 if (flag == INSERT_TRANSITION && map->CanHaveMoreTransitions()) { |
7136 Handle<Name> name; | 7136 Handle<Name> name; |
7137 CHECK(maybe_name.ToHandle(&name)); | 7137 CHECK(maybe_name.ToHandle(&name)); |
7138 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( | 7138 Handle<TransitionArray> transitions = TransitionArray::CopyInsert( |
7139 map, name, result, simple_flag); | 7139 map, name, result, simple_flag); |
7140 map->set_transitions(*transitions); | 7140 map->set_transitions(*transitions); |
(...skipping 10 matching lines...) Expand all Loading... |
7151 | 7151 |
7152 return result; | 7152 return result; |
7153 } | 7153 } |
7154 | 7154 |
7155 | 7155 |
7156 // Since this method is used to rewrite an existing transition tree, it can | 7156 // Since this method is used to rewrite an existing transition tree, it can |
7157 // always insert transitions without checking. | 7157 // always insert transitions without checking. |
7158 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, | 7158 Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map, |
7159 int new_descriptor, | 7159 int new_descriptor, |
7160 Handle<DescriptorArray> descriptors) { | 7160 Handle<DescriptorArray> descriptors) { |
7161 ASSERT(descriptors->IsSortedNoDuplicates()); | 7161 DCHECK(descriptors->IsSortedNoDuplicates()); |
7162 | 7162 |
7163 Handle<Map> result = CopyDropDescriptors(map); | 7163 Handle<Map> result = CopyDropDescriptors(map); |
7164 | 7164 |
7165 result->InitializeDescriptors(*descriptors); | 7165 result->InitializeDescriptors(*descriptors); |
7166 result->SetNumberOfOwnDescriptors(new_descriptor + 1); | 7166 result->SetNumberOfOwnDescriptors(new_descriptor + 1); |
7167 | 7167 |
7168 int unused_property_fields = map->unused_property_fields(); | 7168 int unused_property_fields = map->unused_property_fields(); |
7169 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { | 7169 if (descriptors->GetDetails(new_descriptor).type() == FIELD) { |
7170 unused_property_fields = map->unused_property_fields() - 1; | 7170 unused_property_fields = map->unused_property_fields() - 1; |
7171 if (unused_property_fields < 0) { | 7171 if (unused_property_fields < 0) { |
(...skipping 11 matching lines...) Expand all Loading... |
7183 map->set_transitions(*transitions); | 7183 map->set_transitions(*transitions); |
7184 result->SetBackPointer(*map); | 7184 result->SetBackPointer(*map); |
7185 | 7185 |
7186 return result; | 7186 return result; |
7187 } | 7187 } |
7188 | 7188 |
7189 | 7189 |
7190 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, | 7190 Handle<Map> Map::CopyAsElementsKind(Handle<Map> map, ElementsKind kind, |
7191 TransitionFlag flag) { | 7191 TransitionFlag flag) { |
7192 if (flag == INSERT_TRANSITION) { | 7192 if (flag == INSERT_TRANSITION) { |
7193 ASSERT(!map->HasElementsTransition() || | 7193 DCHECK(!map->HasElementsTransition() || |
7194 ((map->elements_transition_map()->elements_kind() == | 7194 ((map->elements_transition_map()->elements_kind() == |
7195 DICTIONARY_ELEMENTS || | 7195 DICTIONARY_ELEMENTS || |
7196 IsExternalArrayElementsKind( | 7196 IsExternalArrayElementsKind( |
7197 map->elements_transition_map()->elements_kind())) && | 7197 map->elements_transition_map()->elements_kind())) && |
7198 (kind == DICTIONARY_ELEMENTS || | 7198 (kind == DICTIONARY_ELEMENTS || |
7199 IsExternalArrayElementsKind(kind)))); | 7199 IsExternalArrayElementsKind(kind)))); |
7200 ASSERT(!IsFastElementsKind(kind) || | 7200 DCHECK(!IsFastElementsKind(kind) || |
7201 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); | 7201 IsMoreGeneralElementsKindTransition(map->elements_kind(), kind)); |
7202 ASSERT(kind != map->elements_kind()); | 7202 DCHECK(kind != map->elements_kind()); |
7203 } | 7203 } |
7204 | 7204 |
7205 bool insert_transition = | 7205 bool insert_transition = |
7206 flag == INSERT_TRANSITION && !map->HasElementsTransition(); | 7206 flag == INSERT_TRANSITION && !map->HasElementsTransition(); |
7207 | 7207 |
7208 if (insert_transition && map->owns_descriptors()) { | 7208 if (insert_transition && map->owns_descriptors()) { |
7209 // In case the map owned its own descriptors, share the descriptors and | 7209 // In case the map owned its own descriptors, share the descriptors and |
7210 // transfer ownership to the new map. | 7210 // transfer ownership to the new map. |
7211 Handle<Map> new_map = CopyDropDescriptors(map); | 7211 Handle<Map> new_map = CopyDropDescriptors(map); |
7212 | 7212 |
(...skipping 16 matching lines...) Expand all Loading... |
7229 if (insert_transition) { | 7229 if (insert_transition) { |
7230 SetElementsTransitionMap(map, new_map); | 7230 SetElementsTransitionMap(map, new_map); |
7231 new_map->SetBackPointer(*map); | 7231 new_map->SetBackPointer(*map); |
7232 } | 7232 } |
7233 | 7233 |
7234 return new_map; | 7234 return new_map; |
7235 } | 7235 } |
7236 | 7236 |
7237 | 7237 |
7238 Handle<Map> Map::CopyForObserved(Handle<Map> map) { | 7238 Handle<Map> Map::CopyForObserved(Handle<Map> map) { |
7239 ASSERT(!map->is_observed()); | 7239 DCHECK(!map->is_observed()); |
7240 | 7240 |
7241 Isolate* isolate = map->GetIsolate(); | 7241 Isolate* isolate = map->GetIsolate(); |
7242 | 7242 |
7243 // In case the map owned its own descriptors, share the descriptors and | 7243 // In case the map owned its own descriptors, share the descriptors and |
7244 // transfer ownership to the new map. | 7244 // transfer ownership to the new map. |
7245 Handle<Map> new_map; | 7245 Handle<Map> new_map; |
7246 if (map->owns_descriptors()) { | 7246 if (map->owns_descriptors()) { |
7247 new_map = CopyDropDescriptors(map); | 7247 new_map = CopyDropDescriptors(map); |
7248 } else { | 7248 } else { |
7249 new_map = Copy(map); | 7249 new_map = Copy(map); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7320 | 7320 |
7321 | 7321 |
7322 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { | 7322 bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { |
7323 PropertyDetails details = GetDetails(descriptor); | 7323 PropertyDetails details = GetDetails(descriptor); |
7324 switch (details.type()) { | 7324 switch (details.type()) { |
7325 case FIELD: | 7325 case FIELD: |
7326 return value->FitsRepresentation(details.representation()) && | 7326 return value->FitsRepresentation(details.representation()) && |
7327 GetFieldType(descriptor)->NowContains(value); | 7327 GetFieldType(descriptor)->NowContains(value); |
7328 | 7328 |
7329 case CONSTANT: | 7329 case CONSTANT: |
7330 ASSERT(GetConstant(descriptor) != value || | 7330 DCHECK(GetConstant(descriptor) != value || |
7331 value->FitsRepresentation(details.representation())); | 7331 value->FitsRepresentation(details.representation())); |
7332 return GetConstant(descriptor) == value; | 7332 return GetConstant(descriptor) == value; |
7333 | 7333 |
7334 case CALLBACKS: | 7334 case CALLBACKS: |
7335 return false; | 7335 return false; |
7336 | 7336 |
7337 case NORMAL: | 7337 case NORMAL: |
7338 case INTERCEPTOR: | 7338 case INTERCEPTOR: |
7339 case HANDLER: | 7339 case HANDLER: |
7340 case NONEXISTENT: | 7340 case NONEXISTENT: |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7511 | 7511 |
7512 Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map, | 7512 Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map, |
7513 Handle<DescriptorArray> descriptors, | 7513 Handle<DescriptorArray> descriptors, |
7514 Descriptor* descriptor, | 7514 Descriptor* descriptor, |
7515 int insertion_index, | 7515 int insertion_index, |
7516 TransitionFlag flag) { | 7516 TransitionFlag flag) { |
7517 // Ensure the key is unique. | 7517 // Ensure the key is unique. |
7518 descriptor->KeyToUniqueName(); | 7518 descriptor->KeyToUniqueName(); |
7519 | 7519 |
7520 Handle<Name> key = descriptor->GetKey(); | 7520 Handle<Name> key = descriptor->GetKey(); |
7521 ASSERT(*key == descriptors->GetKey(insertion_index)); | 7521 DCHECK(*key == descriptors->GetKey(insertion_index)); |
7522 | 7522 |
7523 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( | 7523 Handle<DescriptorArray> new_descriptors = DescriptorArray::CopyUpTo( |
7524 descriptors, map->NumberOfOwnDescriptors()); | 7524 descriptors, map->NumberOfOwnDescriptors()); |
7525 | 7525 |
7526 new_descriptors->Replace(insertion_index, descriptor); | 7526 new_descriptors->Replace(insertion_index, descriptor); |
7527 | 7527 |
7528 SimpleTransitionFlag simple_flag = | 7528 SimpleTransitionFlag simple_flag = |
7529 (insertion_index == descriptors->number_of_descriptors() - 1) | 7529 (insertion_index == descriptors->number_of_descriptors() - 1) |
7530 ? SIMPLE_TRANSITION | 7530 ? SIMPLE_TRANSITION |
7531 : FULL_TRANSITION; | 7531 : FULL_TRANSITION; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7565 if (!code_cache()->IsFixedArray()) { | 7565 if (!code_cache()->IsFixedArray()) { |
7566 return CodeCache::cast(code_cache())->GetIndex(name, code); | 7566 return CodeCache::cast(code_cache())->GetIndex(name, code); |
7567 } | 7567 } |
7568 return -1; | 7568 return -1; |
7569 } | 7569 } |
7570 | 7570 |
7571 | 7571 |
7572 void Map::RemoveFromCodeCache(Name* name, Code* code, int index) { | 7572 void Map::RemoveFromCodeCache(Name* name, Code* code, int index) { |
7573 // No GC is supposed to happen between a call to IndexInCodeCache and | 7573 // No GC is supposed to happen between a call to IndexInCodeCache and |
7574 // RemoveFromCodeCache so the code cache must be there. | 7574 // RemoveFromCodeCache so the code cache must be there. |
7575 ASSERT(!code_cache()->IsFixedArray()); | 7575 DCHECK(!code_cache()->IsFixedArray()); |
7576 CodeCache::cast(code_cache())->RemoveByIndex(name, code, index); | 7576 CodeCache::cast(code_cache())->RemoveByIndex(name, code, index); |
7577 } | 7577 } |
7578 | 7578 |
7579 | 7579 |
7580 // An iterator over all map transitions in an descriptor array, reusing the | 7580 // An iterator over all map transitions in an descriptor array, reusing the |
7581 // constructor field of the map while it is running. Negative values in | 7581 // constructor field of the map while it is running. Negative values in |
7582 // the constructor field indicate an active map transition iteration. The | 7582 // the constructor field indicate an active map transition iteration. The |
7583 // original constructor is restored after iterating over all entries. | 7583 // original constructor is restored after iterating over all entries. |
7584 class IntrusiveMapTransitionIterator { | 7584 class IntrusiveMapTransitionIterator { |
7585 public: | 7585 public: |
7586 IntrusiveMapTransitionIterator( | 7586 IntrusiveMapTransitionIterator( |
7587 Map* map, TransitionArray* transition_array, Object* constructor) | 7587 Map* map, TransitionArray* transition_array, Object* constructor) |
7588 : map_(map), | 7588 : map_(map), |
7589 transition_array_(transition_array), | 7589 transition_array_(transition_array), |
7590 constructor_(constructor) { } | 7590 constructor_(constructor) { } |
7591 | 7591 |
7592 void StartIfNotStarted() { | 7592 void StartIfNotStarted() { |
7593 ASSERT(!(*IteratorField())->IsSmi() || IsIterating()); | 7593 DCHECK(!(*IteratorField())->IsSmi() || IsIterating()); |
7594 if (!(*IteratorField())->IsSmi()) { | 7594 if (!(*IteratorField())->IsSmi()) { |
7595 ASSERT(*IteratorField() == constructor_); | 7595 DCHECK(*IteratorField() == constructor_); |
7596 *IteratorField() = Smi::FromInt(-1); | 7596 *IteratorField() = Smi::FromInt(-1); |
7597 } | 7597 } |
7598 } | 7598 } |
7599 | 7599 |
7600 bool IsIterating() { | 7600 bool IsIterating() { |
7601 return (*IteratorField())->IsSmi() && | 7601 return (*IteratorField())->IsSmi() && |
7602 Smi::cast(*IteratorField())->value() < 0; | 7602 Smi::cast(*IteratorField())->value() < 0; |
7603 } | 7603 } |
7604 | 7604 |
7605 Map* Next() { | 7605 Map* Next() { |
7606 ASSERT(IsIterating()); | 7606 DCHECK(IsIterating()); |
7607 int value = Smi::cast(*IteratorField())->value(); | 7607 int value = Smi::cast(*IteratorField())->value(); |
7608 int index = -value - 1; | 7608 int index = -value - 1; |
7609 int number_of_transitions = transition_array_->number_of_transitions(); | 7609 int number_of_transitions = transition_array_->number_of_transitions(); |
7610 while (index < number_of_transitions) { | 7610 while (index < number_of_transitions) { |
7611 *IteratorField() = Smi::FromInt(value - 1); | 7611 *IteratorField() = Smi::FromInt(value - 1); |
7612 return transition_array_->GetTarget(index); | 7612 return transition_array_->GetTarget(index); |
7613 } | 7613 } |
7614 | 7614 |
7615 *IteratorField() = constructor_; | 7615 *IteratorField() = constructor_; |
7616 return NULL; | 7616 return NULL; |
(...skipping 15 matching lines...) Expand all Loading... |
7632 // indicate an active prototype transition iteration. The original constructor | 7632 // indicate an active prototype transition iteration. The original constructor |
7633 // is restored after iterating over all entries. | 7633 // is restored after iterating over all entries. |
7634 class IntrusivePrototypeTransitionIterator { | 7634 class IntrusivePrototypeTransitionIterator { |
7635 public: | 7635 public: |
7636 IntrusivePrototypeTransitionIterator( | 7636 IntrusivePrototypeTransitionIterator( |
7637 Map* map, HeapObject* proto_trans, Object* constructor) | 7637 Map* map, HeapObject* proto_trans, Object* constructor) |
7638 : map_(map), proto_trans_(proto_trans), constructor_(constructor) { } | 7638 : map_(map), proto_trans_(proto_trans), constructor_(constructor) { } |
7639 | 7639 |
7640 void StartIfNotStarted() { | 7640 void StartIfNotStarted() { |
7641 if (!(*IteratorField())->IsSmi()) { | 7641 if (!(*IteratorField())->IsSmi()) { |
7642 ASSERT(*IteratorField() == constructor_); | 7642 DCHECK(*IteratorField() == constructor_); |
7643 *IteratorField() = Smi::FromInt(0); | 7643 *IteratorField() = Smi::FromInt(0); |
7644 } | 7644 } |
7645 } | 7645 } |
7646 | 7646 |
7647 bool IsIterating() { | 7647 bool IsIterating() { |
7648 return (*IteratorField())->IsSmi() && | 7648 return (*IteratorField())->IsSmi() && |
7649 Smi::cast(*IteratorField())->value() >= 0; | 7649 Smi::cast(*IteratorField())->value() >= 0; |
7650 } | 7650 } |
7651 | 7651 |
7652 Map* Next() { | 7652 Map* Next() { |
7653 ASSERT(IsIterating()); | 7653 DCHECK(IsIterating()); |
7654 int transitionNumber = Smi::cast(*IteratorField())->value(); | 7654 int transitionNumber = Smi::cast(*IteratorField())->value(); |
7655 if (transitionNumber < NumberOfTransitions()) { | 7655 if (transitionNumber < NumberOfTransitions()) { |
7656 *IteratorField() = Smi::FromInt(transitionNumber + 1); | 7656 *IteratorField() = Smi::FromInt(transitionNumber + 1); |
7657 return GetTransition(transitionNumber); | 7657 return GetTransition(transitionNumber); |
7658 } | 7658 } |
7659 *IteratorField() = constructor_; | 7659 *IteratorField() = constructor_; |
7660 return NULL; | 7660 return NULL; |
7661 } | 7661 } |
7662 | 7662 |
7663 private: | 7663 private: |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7791 if (code->type() == Code::NORMAL) { | 7791 if (code->type() == Code::NORMAL) { |
7792 // Make sure that a hash table is allocated for the normal load code cache. | 7792 // Make sure that a hash table is allocated for the normal load code cache. |
7793 if (code_cache->normal_type_cache()->IsUndefined()) { | 7793 if (code_cache->normal_type_cache()->IsUndefined()) { |
7794 Handle<Object> result = | 7794 Handle<Object> result = |
7795 CodeCacheHashTable::New(code_cache->GetIsolate(), | 7795 CodeCacheHashTable::New(code_cache->GetIsolate(), |
7796 CodeCacheHashTable::kInitialSize); | 7796 CodeCacheHashTable::kInitialSize); |
7797 code_cache->set_normal_type_cache(*result); | 7797 code_cache->set_normal_type_cache(*result); |
7798 } | 7798 } |
7799 UpdateNormalTypeCache(code_cache, name, code); | 7799 UpdateNormalTypeCache(code_cache, name, code); |
7800 } else { | 7800 } else { |
7801 ASSERT(code_cache->default_cache()->IsFixedArray()); | 7801 DCHECK(code_cache->default_cache()->IsFixedArray()); |
7802 UpdateDefaultCache(code_cache, name, code); | 7802 UpdateDefaultCache(code_cache, name, code); |
7803 } | 7803 } |
7804 } | 7804 } |
7805 | 7805 |
7806 | 7806 |
7807 void CodeCache::UpdateDefaultCache( | 7807 void CodeCache::UpdateDefaultCache( |
7808 Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code) { | 7808 Handle<CodeCache> code_cache, Handle<Name> name, Handle<Code> code) { |
7809 // When updating the default code cache we disregard the type encoded in the | 7809 // When updating the default code cache we disregard the type encoded in the |
7810 // flags. This allows call constant stubs to overwrite call field | 7810 // flags. This allows call constant stubs to overwrite call field |
7811 // stubs, etc. | 7811 // stubs, etc. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7846 cache->set(deleted_index + kCodeCacheEntryNameOffset, *name); | 7846 cache->set(deleted_index + kCodeCacheEntryNameOffset, *name); |
7847 cache->set(deleted_index + kCodeCacheEntryCodeOffset, *code); | 7847 cache->set(deleted_index + kCodeCacheEntryCodeOffset, *code); |
7848 return; | 7848 return; |
7849 } | 7849 } |
7850 } | 7850 } |
7851 | 7851 |
7852 // Extend the code cache with some new entries (at least one). Must be a | 7852 // Extend the code cache with some new entries (at least one). Must be a |
7853 // multiple of the entry size. | 7853 // multiple of the entry size. |
7854 int new_length = length + ((length >> 1)) + kCodeCacheEntrySize; | 7854 int new_length = length + ((length >> 1)) + kCodeCacheEntrySize; |
7855 new_length = new_length - new_length % kCodeCacheEntrySize; | 7855 new_length = new_length - new_length % kCodeCacheEntrySize; |
7856 ASSERT((new_length % kCodeCacheEntrySize) == 0); | 7856 DCHECK((new_length % kCodeCacheEntrySize) == 0); |
7857 cache = FixedArray::CopySize(cache, new_length); | 7857 cache = FixedArray::CopySize(cache, new_length); |
7858 | 7858 |
7859 // Add the (name, code) pair to the new cache. | 7859 // Add the (name, code) pair to the new cache. |
7860 cache->set(length + kCodeCacheEntryNameOffset, *name); | 7860 cache->set(length + kCodeCacheEntryNameOffset, *name); |
7861 cache->set(length + kCodeCacheEntryCodeOffset, *code); | 7861 cache->set(length + kCodeCacheEntryCodeOffset, *code); |
7862 code_cache->set_default_cache(*cache); | 7862 code_cache->set_default_cache(*cache); |
7863 } | 7863 } |
7864 | 7864 |
7865 | 7865 |
7866 void CodeCache::UpdateNormalTypeCache( | 7866 void CodeCache::UpdateNormalTypeCache( |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7923 int len = array->length(); | 7923 int len = array->length(); |
7924 for (int i = 0; i < len; i += kCodeCacheEntrySize) { | 7924 for (int i = 0; i < len; i += kCodeCacheEntrySize) { |
7925 if (array->get(i + kCodeCacheEntryCodeOffset) == code) return i + 1; | 7925 if (array->get(i + kCodeCacheEntryCodeOffset) == code) return i + 1; |
7926 } | 7926 } |
7927 return -1; | 7927 return -1; |
7928 } | 7928 } |
7929 | 7929 |
7930 | 7930 |
7931 void CodeCache::RemoveByIndex(Object* name, Code* code, int index) { | 7931 void CodeCache::RemoveByIndex(Object* name, Code* code, int index) { |
7932 if (code->type() == Code::NORMAL) { | 7932 if (code->type() == Code::NORMAL) { |
7933 ASSERT(!normal_type_cache()->IsUndefined()); | 7933 DCHECK(!normal_type_cache()->IsUndefined()); |
7934 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 7934 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
7935 ASSERT(cache->GetIndex(Name::cast(name), code->flags()) == index); | 7935 DCHECK(cache->GetIndex(Name::cast(name), code->flags()) == index); |
7936 cache->RemoveByIndex(index); | 7936 cache->RemoveByIndex(index); |
7937 } else { | 7937 } else { |
7938 FixedArray* array = default_cache(); | 7938 FixedArray* array = default_cache(); |
7939 ASSERT(array->length() >= index && array->get(index)->IsCode()); | 7939 DCHECK(array->length() >= index && array->get(index)->IsCode()); |
7940 // Use null instead of undefined for deleted elements to distinguish | 7940 // Use null instead of undefined for deleted elements to distinguish |
7941 // deleted elements from unused elements. This distinction is used | 7941 // deleted elements from unused elements. This distinction is used |
7942 // when looking up in the cache and when updating the cache. | 7942 // when looking up in the cache and when updating the cache. |
7943 ASSERT_EQ(1, kCodeCacheEntryCodeOffset - kCodeCacheEntryNameOffset); | 7943 DCHECK_EQ(1, kCodeCacheEntryCodeOffset - kCodeCacheEntryNameOffset); |
7944 array->set_null(index - 1); // Name. | 7944 array->set_null(index - 1); // Name. |
7945 array->set_null(index); // Code. | 7945 array->set_null(index); // Code. |
7946 } | 7946 } |
7947 } | 7947 } |
7948 | 7948 |
7949 | 7949 |
7950 // The key in the code cache hash table consists of the property name and the | 7950 // The key in the code cache hash table consists of the property name and the |
7951 // code object. The actual match is on the name and the code flags. If a key | 7951 // code object. The actual match is on the name and the code flags. If a key |
7952 // is created using the flags and not a code object it can only be used for | 7952 // is created using the flags and not a code object it can only be used for |
7953 // lookup not to create a new entry. | 7953 // lookup not to create a new entry. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8026 | 8026 |
8027 int CodeCacheHashTable::GetIndex(Name* name, Code::Flags flags) { | 8027 int CodeCacheHashTable::GetIndex(Name* name, Code::Flags flags) { |
8028 DisallowHeapAllocation no_alloc; | 8028 DisallowHeapAllocation no_alloc; |
8029 CodeCacheHashTableKey key(handle(name), flags); | 8029 CodeCacheHashTableKey key(handle(name), flags); |
8030 int entry = FindEntry(&key); | 8030 int entry = FindEntry(&key); |
8031 return (entry == kNotFound) ? -1 : entry; | 8031 return (entry == kNotFound) ? -1 : entry; |
8032 } | 8032 } |
8033 | 8033 |
8034 | 8034 |
8035 void CodeCacheHashTable::RemoveByIndex(int index) { | 8035 void CodeCacheHashTable::RemoveByIndex(int index) { |
8036 ASSERT(index >= 0); | 8036 DCHECK(index >= 0); |
8037 Heap* heap = GetHeap(); | 8037 Heap* heap = GetHeap(); |
8038 set(EntryToIndex(index), heap->the_hole_value()); | 8038 set(EntryToIndex(index), heap->the_hole_value()); |
8039 set(EntryToIndex(index) + 1, heap->the_hole_value()); | 8039 set(EntryToIndex(index) + 1, heap->the_hole_value()); |
8040 ElementRemoved(); | 8040 ElementRemoved(); |
8041 } | 8041 } |
8042 | 8042 |
8043 | 8043 |
8044 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> code_cache, | 8044 void PolymorphicCodeCache::Update(Handle<PolymorphicCodeCache> code_cache, |
8045 MapHandleList* maps, | 8045 MapHandleList* maps, |
8046 Code::Flags flags, | 8046 Code::Flags flags, |
8047 Handle<Code> code) { | 8047 Handle<Code> code) { |
8048 Isolate* isolate = code_cache->GetIsolate(); | 8048 Isolate* isolate = code_cache->GetIsolate(); |
8049 if (code_cache->cache()->IsUndefined()) { | 8049 if (code_cache->cache()->IsUndefined()) { |
8050 Handle<PolymorphicCodeCacheHashTable> result = | 8050 Handle<PolymorphicCodeCacheHashTable> result = |
8051 PolymorphicCodeCacheHashTable::New( | 8051 PolymorphicCodeCacheHashTable::New( |
8052 isolate, | 8052 isolate, |
8053 PolymorphicCodeCacheHashTable::kInitialSize); | 8053 PolymorphicCodeCacheHashTable::kInitialSize); |
8054 code_cache->set_cache(*result); | 8054 code_cache->set_cache(*result); |
8055 } else { | 8055 } else { |
8056 // This entry shouldn't be contained in the cache yet. | 8056 // This entry shouldn't be contained in the cache yet. |
8057 ASSERT(PolymorphicCodeCacheHashTable::cast(code_cache->cache()) | 8057 DCHECK(PolymorphicCodeCacheHashTable::cast(code_cache->cache()) |
8058 ->Lookup(maps, flags)->IsUndefined()); | 8058 ->Lookup(maps, flags)->IsUndefined()); |
8059 } | 8059 } |
8060 Handle<PolymorphicCodeCacheHashTable> hash_table = | 8060 Handle<PolymorphicCodeCacheHashTable> hash_table = |
8061 handle(PolymorphicCodeCacheHashTable::cast(code_cache->cache())); | 8061 handle(PolymorphicCodeCacheHashTable::cast(code_cache->cache())); |
8062 Handle<PolymorphicCodeCacheHashTable> new_cache = | 8062 Handle<PolymorphicCodeCacheHashTable> new_cache = |
8063 PolymorphicCodeCacheHashTable::Put(hash_table, maps, flags, code); | 8063 PolymorphicCodeCacheHashTable::Put(hash_table, maps, flags, code); |
8064 code_cache->set_cache(*new_cache); | 8064 code_cache->set_cache(*new_cache); |
8065 } | 8065 } |
8066 | 8066 |
8067 | 8067 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8187 | 8187 |
8188 Handle<Object> obj = key.AsHandle(hash_table->GetIsolate()); | 8188 Handle<Object> obj = key.AsHandle(hash_table->GetIsolate()); |
8189 cache->set(EntryToIndex(entry), *obj); | 8189 cache->set(EntryToIndex(entry), *obj); |
8190 cache->set(EntryToIndex(entry) + 1, *code); | 8190 cache->set(EntryToIndex(entry) + 1, *code); |
8191 cache->ElementAdded(); | 8191 cache->ElementAdded(); |
8192 return cache; | 8192 return cache; |
8193 } | 8193 } |
8194 | 8194 |
8195 | 8195 |
8196 void FixedArray::Shrink(int new_length) { | 8196 void FixedArray::Shrink(int new_length) { |
8197 ASSERT(0 <= new_length && new_length <= length()); | 8197 DCHECK(0 <= new_length && new_length <= length()); |
8198 if (new_length < length()) { | 8198 if (new_length < length()) { |
8199 RightTrimFixedArray<Heap::FROM_MUTATOR>( | 8199 RightTrimFixedArray<Heap::FROM_MUTATOR>( |
8200 GetHeap(), this, length() - new_length); | 8200 GetHeap(), this, length() - new_length); |
8201 } | 8201 } |
8202 } | 8202 } |
8203 | 8203 |
8204 | 8204 |
8205 MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike( | 8205 MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike( |
8206 Handle<FixedArray> content, | 8206 Handle<FixedArray> content, |
8207 Handle<JSObject> array) { | 8207 Handle<JSObject> array) { |
8208 ASSERT(array->IsJSArray() || array->HasSloppyArgumentsElements()); | 8208 DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements()); |
8209 ElementsAccessor* accessor = array->GetElementsAccessor(); | 8209 ElementsAccessor* accessor = array->GetElementsAccessor(); |
8210 Handle<FixedArray> result; | 8210 Handle<FixedArray> result; |
8211 ASSIGN_RETURN_ON_EXCEPTION( | 8211 ASSIGN_RETURN_ON_EXCEPTION( |
8212 array->GetIsolate(), result, | 8212 array->GetIsolate(), result, |
8213 accessor->AddElementsToFixedArray(array, array, content), | 8213 accessor->AddElementsToFixedArray(array, array, content), |
8214 FixedArray); | 8214 FixedArray); |
8215 | 8215 |
8216 #ifdef ENABLE_SLOW_ASSERTS | 8216 #ifdef ENABLE_SLOW_DCHECKS |
8217 if (FLAG_enable_slow_asserts) { | 8217 if (FLAG_enable_slow_asserts) { |
8218 DisallowHeapAllocation no_allocation; | 8218 DisallowHeapAllocation no_allocation; |
8219 for (int i = 0; i < result->length(); i++) { | 8219 for (int i = 0; i < result->length(); i++) { |
8220 Object* current = result->get(i); | 8220 Object* current = result->get(i); |
8221 ASSERT(current->IsNumber() || current->IsName()); | 8221 DCHECK(current->IsNumber() || current->IsName()); |
8222 } | 8222 } |
8223 } | 8223 } |
8224 #endif | 8224 #endif |
8225 return result; | 8225 return result; |
8226 } | 8226 } |
8227 | 8227 |
8228 | 8228 |
8229 MaybeHandle<FixedArray> FixedArray::UnionOfKeys(Handle<FixedArray> first, | 8229 MaybeHandle<FixedArray> FixedArray::UnionOfKeys(Handle<FixedArray> first, |
8230 Handle<FixedArray> second) { | 8230 Handle<FixedArray> second) { |
8231 ElementsAccessor* accessor = ElementsAccessor::ForArray(second); | 8231 ElementsAccessor* accessor = ElementsAccessor::ForArray(second); |
8232 Handle<FixedArray> result; | 8232 Handle<FixedArray> result; |
8233 ASSIGN_RETURN_ON_EXCEPTION( | 8233 ASSIGN_RETURN_ON_EXCEPTION( |
8234 first->GetIsolate(), result, | 8234 first->GetIsolate(), result, |
8235 accessor->AddElementsToFixedArray( | 8235 accessor->AddElementsToFixedArray( |
8236 Handle<Object>::null(), // receiver | 8236 Handle<Object>::null(), // receiver |
8237 Handle<JSObject>::null(), // holder | 8237 Handle<JSObject>::null(), // holder |
8238 first, | 8238 first, |
8239 Handle<FixedArrayBase>::cast(second)), | 8239 Handle<FixedArrayBase>::cast(second)), |
8240 FixedArray); | 8240 FixedArray); |
8241 | 8241 |
8242 #ifdef ENABLE_SLOW_ASSERTS | 8242 #ifdef ENABLE_SLOW_DCHECKS |
8243 if (FLAG_enable_slow_asserts) { | 8243 if (FLAG_enable_slow_asserts) { |
8244 DisallowHeapAllocation no_allocation; | 8244 DisallowHeapAllocation no_allocation; |
8245 for (int i = 0; i < result->length(); i++) { | 8245 for (int i = 0; i < result->length(); i++) { |
8246 Object* current = result->get(i); | 8246 Object* current = result->get(i); |
8247 ASSERT(current->IsNumber() || current->IsName()); | 8247 DCHECK(current->IsNumber() || current->IsName()); |
8248 } | 8248 } |
8249 } | 8249 } |
8250 #endif | 8250 #endif |
8251 return result; | 8251 return result; |
8252 } | 8252 } |
8253 | 8253 |
8254 | 8254 |
8255 Handle<FixedArray> FixedArray::CopySize( | 8255 Handle<FixedArray> FixedArray::CopySize( |
8256 Handle<FixedArray> array, int new_length, PretenureFlag pretenure) { | 8256 Handle<FixedArray> array, int new_length, PretenureFlag pretenure) { |
8257 Isolate* isolate = array->GetIsolate(); | 8257 Isolate* isolate = array->GetIsolate(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8289 if (get(i) != other->get(i)) return false; | 8289 if (get(i) != other->get(i)) return false; |
8290 } | 8290 } |
8291 return true; | 8291 return true; |
8292 } | 8292 } |
8293 #endif | 8293 #endif |
8294 | 8294 |
8295 | 8295 |
8296 Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate, | 8296 Handle<DescriptorArray> DescriptorArray::Allocate(Isolate* isolate, |
8297 int number_of_descriptors, | 8297 int number_of_descriptors, |
8298 int slack) { | 8298 int slack) { |
8299 ASSERT(0 <= number_of_descriptors); | 8299 DCHECK(0 <= number_of_descriptors); |
8300 Factory* factory = isolate->factory(); | 8300 Factory* factory = isolate->factory(); |
8301 // Do not use DescriptorArray::cast on incomplete object. | 8301 // Do not use DescriptorArray::cast on incomplete object. |
8302 int size = number_of_descriptors + slack; | 8302 int size = number_of_descriptors + slack; |
8303 if (size == 0) return factory->empty_descriptor_array(); | 8303 if (size == 0) return factory->empty_descriptor_array(); |
8304 // Allocate the array of keys. | 8304 // Allocate the array of keys. |
8305 Handle<FixedArray> result = factory->NewFixedArray(LengthFor(size)); | 8305 Handle<FixedArray> result = factory->NewFixedArray(LengthFor(size)); |
8306 | 8306 |
8307 result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors)); | 8307 result->set(kDescriptorLengthIndex, Smi::FromInt(number_of_descriptors)); |
8308 result->set(kEnumCacheIndex, Smi::FromInt(0)); | 8308 result->set(kEnumCacheIndex, Smi::FromInt(0)); |
8309 return Handle<DescriptorArray>::cast(result); | 8309 return Handle<DescriptorArray>::cast(result); |
8310 } | 8310 } |
8311 | 8311 |
8312 | 8312 |
8313 void DescriptorArray::ClearEnumCache() { | 8313 void DescriptorArray::ClearEnumCache() { |
8314 set(kEnumCacheIndex, Smi::FromInt(0)); | 8314 set(kEnumCacheIndex, Smi::FromInt(0)); |
8315 } | 8315 } |
8316 | 8316 |
8317 | 8317 |
8318 void DescriptorArray::Replace(int index, Descriptor* descriptor) { | 8318 void DescriptorArray::Replace(int index, Descriptor* descriptor) { |
8319 descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index)); | 8319 descriptor->SetSortedKeyIndex(GetSortedKeyIndex(index)); |
8320 Set(index, descriptor); | 8320 Set(index, descriptor); |
8321 } | 8321 } |
8322 | 8322 |
8323 | 8323 |
8324 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, | 8324 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, |
8325 FixedArray* new_cache, | 8325 FixedArray* new_cache, |
8326 Object* new_index_cache) { | 8326 Object* new_index_cache) { |
8327 ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength); | 8327 DCHECK(bridge_storage->length() >= kEnumCacheBridgeLength); |
8328 ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray()); | 8328 DCHECK(new_index_cache->IsSmi() || new_index_cache->IsFixedArray()); |
8329 ASSERT(!IsEmpty()); | 8329 DCHECK(!IsEmpty()); |
8330 ASSERT(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); | 8330 DCHECK(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); |
8331 FixedArray::cast(bridge_storage)-> | 8331 FixedArray::cast(bridge_storage)-> |
8332 set(kEnumCacheBridgeCacheIndex, new_cache); | 8332 set(kEnumCacheBridgeCacheIndex, new_cache); |
8333 FixedArray::cast(bridge_storage)-> | 8333 FixedArray::cast(bridge_storage)-> |
8334 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); | 8334 set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); |
8335 set(kEnumCacheIndex, bridge_storage); | 8335 set(kEnumCacheIndex, bridge_storage); |
8336 } | 8336 } |
8337 | 8337 |
8338 | 8338 |
8339 void DescriptorArray::CopyFrom(int index, | 8339 void DescriptorArray::CopyFrom(int index, |
8340 DescriptorArray* src, | 8340 DescriptorArray* src, |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8396 if (right_child_hash > child_hash) { | 8396 if (right_child_hash > child_hash) { |
8397 child_index++; | 8397 child_index++; |
8398 child_hash = right_child_hash; | 8398 child_hash = right_child_hash; |
8399 } | 8399 } |
8400 } | 8400 } |
8401 if (child_hash <= parent_hash) break; | 8401 if (child_hash <= parent_hash) break; |
8402 SwapSortedKeys(parent_index, child_index); | 8402 SwapSortedKeys(parent_index, child_index); |
8403 parent_index = child_index; | 8403 parent_index = child_index; |
8404 } | 8404 } |
8405 } | 8405 } |
8406 ASSERT(IsSortedNoDuplicates()); | 8406 DCHECK(IsSortedNoDuplicates()); |
8407 } | 8407 } |
8408 | 8408 |
8409 | 8409 |
8410 Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) { | 8410 Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) { |
8411 Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair(); | 8411 Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair(); |
8412 copy->set_getter(pair->getter()); | 8412 copy->set_getter(pair->getter()); |
8413 copy->set_setter(pair->setter()); | 8413 copy->set_setter(pair->setter()); |
8414 return copy; | 8414 return copy; |
8415 } | 8415 } |
8416 | 8416 |
8417 | 8417 |
8418 Object* AccessorPair::GetComponent(AccessorComponent component) { | 8418 Object* AccessorPair::GetComponent(AccessorComponent component) { |
8419 Object* accessor = get(component); | 8419 Object* accessor = get(component); |
8420 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor; | 8420 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor; |
8421 } | 8421 } |
8422 | 8422 |
8423 | 8423 |
8424 Handle<DeoptimizationInputData> DeoptimizationInputData::New( | 8424 Handle<DeoptimizationInputData> DeoptimizationInputData::New( |
8425 Isolate* isolate, int deopt_entry_count, int return_patch_address_count, | 8425 Isolate* isolate, int deopt_entry_count, int return_patch_address_count, |
8426 PretenureFlag pretenure) { | 8426 PretenureFlag pretenure) { |
8427 ASSERT(deopt_entry_count + return_patch_address_count > 0); | 8427 DCHECK(deopt_entry_count + return_patch_address_count > 0); |
8428 Handle<FixedArray> deoptimization_data = | 8428 Handle<FixedArray> deoptimization_data = |
8429 Handle<FixedArray>::cast(isolate->factory()->NewFixedArray( | 8429 Handle<FixedArray>::cast(isolate->factory()->NewFixedArray( |
8430 LengthFor(deopt_entry_count, return_patch_address_count), pretenure)); | 8430 LengthFor(deopt_entry_count, return_patch_address_count), pretenure)); |
8431 deoptimization_data->set(kDeoptEntryCountIndex, | 8431 deoptimization_data->set(kDeoptEntryCountIndex, |
8432 Smi::FromInt(deopt_entry_count)); | 8432 Smi::FromInt(deopt_entry_count)); |
8433 deoptimization_data->set(kReturnAddressPatchEntryCountIndex, | 8433 deoptimization_data->set(kReturnAddressPatchEntryCountIndex, |
8434 Smi::FromInt(return_patch_address_count)); | 8434 Smi::FromInt(return_patch_address_count)); |
8435 return Handle<DeoptimizationInputData>::cast(deoptimization_data); | 8435 return Handle<DeoptimizationInputData>::cast(deoptimization_data); |
8436 } | 8436 } |
8437 | 8437 |
(...skipping 26 matching lines...) Expand all Loading... |
8464 #endif | 8464 #endif |
8465 | 8465 |
8466 | 8466 |
8467 bool String::LooksValid() { | 8467 bool String::LooksValid() { |
8468 if (!GetIsolate()->heap()->Contains(this)) return false; | 8468 if (!GetIsolate()->heap()->Contains(this)) return false; |
8469 return true; | 8469 return true; |
8470 } | 8470 } |
8471 | 8471 |
8472 | 8472 |
8473 String::FlatContent String::GetFlatContent() { | 8473 String::FlatContent String::GetFlatContent() { |
8474 ASSERT(!AllowHeapAllocation::IsAllowed()); | 8474 DCHECK(!AllowHeapAllocation::IsAllowed()); |
8475 int length = this->length(); | 8475 int length = this->length(); |
8476 StringShape shape(this); | 8476 StringShape shape(this); |
8477 String* string = this; | 8477 String* string = this; |
8478 int offset = 0; | 8478 int offset = 0; |
8479 if (shape.representation_tag() == kConsStringTag) { | 8479 if (shape.representation_tag() == kConsStringTag) { |
8480 ConsString* cons = ConsString::cast(string); | 8480 ConsString* cons = ConsString::cast(string); |
8481 if (cons->second()->length() != 0) { | 8481 if (cons->second()->length() != 0) { |
8482 return FlatContent(); | 8482 return FlatContent(); |
8483 } | 8483 } |
8484 string = cons->first(); | 8484 string = cons->first(); |
8485 shape = StringShape(string); | 8485 shape = StringShape(string); |
8486 } | 8486 } |
8487 if (shape.representation_tag() == kSlicedStringTag) { | 8487 if (shape.representation_tag() == kSlicedStringTag) { |
8488 SlicedString* slice = SlicedString::cast(string); | 8488 SlicedString* slice = SlicedString::cast(string); |
8489 offset = slice->offset(); | 8489 offset = slice->offset(); |
8490 string = slice->parent(); | 8490 string = slice->parent(); |
8491 shape = StringShape(string); | 8491 shape = StringShape(string); |
8492 ASSERT(shape.representation_tag() != kConsStringTag && | 8492 DCHECK(shape.representation_tag() != kConsStringTag && |
8493 shape.representation_tag() != kSlicedStringTag); | 8493 shape.representation_tag() != kSlicedStringTag); |
8494 } | 8494 } |
8495 if (shape.encoding_tag() == kOneByteStringTag) { | 8495 if (shape.encoding_tag() == kOneByteStringTag) { |
8496 const uint8_t* start; | 8496 const uint8_t* start; |
8497 if (shape.representation_tag() == kSeqStringTag) { | 8497 if (shape.representation_tag() == kSeqStringTag) { |
8498 start = SeqOneByteString::cast(string)->GetChars(); | 8498 start = SeqOneByteString::cast(string)->GetChars(); |
8499 } else { | 8499 } else { |
8500 start = ExternalAsciiString::cast(string)->GetChars(); | 8500 start = ExternalAsciiString::cast(string)->GetChars(); |
8501 } | 8501 } |
8502 return FlatContent(start + offset, length); | 8502 return FlatContent(start + offset, length); |
8503 } else { | 8503 } else { |
8504 ASSERT(shape.encoding_tag() == kTwoByteStringTag); | 8504 DCHECK(shape.encoding_tag() == kTwoByteStringTag); |
8505 const uc16* start; | 8505 const uc16* start; |
8506 if (shape.representation_tag() == kSeqStringTag) { | 8506 if (shape.representation_tag() == kSeqStringTag) { |
8507 start = SeqTwoByteString::cast(string)->GetChars(); | 8507 start = SeqTwoByteString::cast(string)->GetChars(); |
8508 } else { | 8508 } else { |
8509 start = ExternalTwoByteString::cast(string)->GetChars(); | 8509 start = ExternalTwoByteString::cast(string)->GetChars(); |
8510 } | 8510 } |
8511 return FlatContent(start + offset, length); | 8511 return FlatContent(start + offset, length); |
8512 } | 8512 } |
8513 } | 8513 } |
8514 | 8514 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8565 | 8565 |
8566 | 8566 |
8567 SmartArrayPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 8567 SmartArrayPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
8568 RobustnessFlag robust_flag, | 8568 RobustnessFlag robust_flag, |
8569 int* length_return) { | 8569 int* length_return) { |
8570 return ToCString(allow_nulls, robust_flag, 0, -1, length_return); | 8570 return ToCString(allow_nulls, robust_flag, 0, -1, length_return); |
8571 } | 8571 } |
8572 | 8572 |
8573 | 8573 |
8574 const uc16* String::GetTwoByteData(unsigned start) { | 8574 const uc16* String::GetTwoByteData(unsigned start) { |
8575 ASSERT(!IsOneByteRepresentationUnderneath()); | 8575 DCHECK(!IsOneByteRepresentationUnderneath()); |
8576 switch (StringShape(this).representation_tag()) { | 8576 switch (StringShape(this).representation_tag()) { |
8577 case kSeqStringTag: | 8577 case kSeqStringTag: |
8578 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); | 8578 return SeqTwoByteString::cast(this)->SeqTwoByteStringGetData(start); |
8579 case kExternalStringTag: | 8579 case kExternalStringTag: |
8580 return ExternalTwoByteString::cast(this)-> | 8580 return ExternalTwoByteString::cast(this)-> |
8581 ExternalTwoByteStringGetData(start); | 8581 ExternalTwoByteStringGetData(start); |
8582 case kSlicedStringTag: { | 8582 case kSlicedStringTag: { |
8583 SlicedString* slice = SlicedString::cast(this); | 8583 SlicedString* slice = SlicedString::cast(this); |
8584 return slice->parent()->GetTwoByteData(start + slice->offset()); | 8584 return slice->parent()->GetTwoByteData(start + slice->offset()); |
8585 } | 8585 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8683 : Relocatable(isolate), | 8683 : Relocatable(isolate), |
8684 str_(0), | 8684 str_(0), |
8685 is_ascii_(true), | 8685 is_ascii_(true), |
8686 length_(input.length()), | 8686 length_(input.length()), |
8687 start_(input.start()) { } | 8687 start_(input.start()) { } |
8688 | 8688 |
8689 | 8689 |
8690 void FlatStringReader::PostGarbageCollection() { | 8690 void FlatStringReader::PostGarbageCollection() { |
8691 if (str_ == NULL) return; | 8691 if (str_ == NULL) return; |
8692 Handle<String> str(str_); | 8692 Handle<String> str(str_); |
8693 ASSERT(str->IsFlat()); | 8693 DCHECK(str->IsFlat()); |
8694 DisallowHeapAllocation no_gc; | 8694 DisallowHeapAllocation no_gc; |
8695 // This does not actually prevent the vector from being relocated later. | 8695 // This does not actually prevent the vector from being relocated later. |
8696 String::FlatContent content = str->GetFlatContent(); | 8696 String::FlatContent content = str->GetFlatContent(); |
8697 ASSERT(content.IsFlat()); | 8697 DCHECK(content.IsFlat()); |
8698 is_ascii_ = content.IsAscii(); | 8698 is_ascii_ = content.IsAscii(); |
8699 if (is_ascii_) { | 8699 if (is_ascii_) { |
8700 start_ = content.ToOneByteVector().start(); | 8700 start_ = content.ToOneByteVector().start(); |
8701 } else { | 8701 } else { |
8702 start_ = content.ToUC16Vector().start(); | 8702 start_ = content.ToUC16Vector().start(); |
8703 } | 8703 } |
8704 } | 8704 } |
8705 | 8705 |
8706 | 8706 |
8707 void ConsStringIteratorOp::Initialize(ConsString* cons_string, int offset) { | 8707 void ConsStringIteratorOp::Initialize(ConsString* cons_string, int offset) { |
8708 ASSERT(cons_string != NULL); | 8708 DCHECK(cons_string != NULL); |
8709 root_ = cons_string; | 8709 root_ = cons_string; |
8710 consumed_ = offset; | 8710 consumed_ = offset; |
8711 // Force stack blown condition to trigger restart. | 8711 // Force stack blown condition to trigger restart. |
8712 depth_ = 1; | 8712 depth_ = 1; |
8713 maximum_depth_ = kStackSize + depth_; | 8713 maximum_depth_ = kStackSize + depth_; |
8714 ASSERT(StackBlown()); | 8714 DCHECK(StackBlown()); |
8715 } | 8715 } |
8716 | 8716 |
8717 | 8717 |
8718 String* ConsStringIteratorOp::Continue(int* offset_out) { | 8718 String* ConsStringIteratorOp::Continue(int* offset_out) { |
8719 ASSERT(depth_ != 0); | 8719 DCHECK(depth_ != 0); |
8720 ASSERT_EQ(0, *offset_out); | 8720 DCHECK_EQ(0, *offset_out); |
8721 bool blew_stack = StackBlown(); | 8721 bool blew_stack = StackBlown(); |
8722 String* string = NULL; | 8722 String* string = NULL; |
8723 // Get the next leaf if there is one. | 8723 // Get the next leaf if there is one. |
8724 if (!blew_stack) string = NextLeaf(&blew_stack); | 8724 if (!blew_stack) string = NextLeaf(&blew_stack); |
8725 // Restart search from root. | 8725 // Restart search from root. |
8726 if (blew_stack) { | 8726 if (blew_stack) { |
8727 ASSERT(string == NULL); | 8727 DCHECK(string == NULL); |
8728 string = Search(offset_out); | 8728 string = Search(offset_out); |
8729 } | 8729 } |
8730 // Ensure future calls return null immediately. | 8730 // Ensure future calls return null immediately. |
8731 if (string == NULL) Reset(NULL); | 8731 if (string == NULL) Reset(NULL); |
8732 return string; | 8732 return string; |
8733 } | 8733 } |
8734 | 8734 |
8735 | 8735 |
8736 String* ConsStringIteratorOp::Search(int* offset_out) { | 8736 String* ConsStringIteratorOp::Search(int* offset_out) { |
8737 ConsString* cons_string = root_; | 8737 ConsString* cons_string = root_; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8776 if (length == 0) { | 8776 if (length == 0) { |
8777 // Reset so future operations will return null immediately. | 8777 // Reset so future operations will return null immediately. |
8778 Reset(NULL); | 8778 Reset(NULL); |
8779 return NULL; | 8779 return NULL; |
8780 } | 8780 } |
8781 // Tell the stack we're done descending. | 8781 // Tell the stack we're done descending. |
8782 AdjustMaximumDepth(); | 8782 AdjustMaximumDepth(); |
8783 // Pop stack so next iteration is in correct place. | 8783 // Pop stack so next iteration is in correct place. |
8784 Pop(); | 8784 Pop(); |
8785 } | 8785 } |
8786 ASSERT(length != 0); | 8786 DCHECK(length != 0); |
8787 // Adjust return values and exit. | 8787 // Adjust return values and exit. |
8788 consumed_ = offset + length; | 8788 consumed_ = offset + length; |
8789 *offset_out = consumed - offset; | 8789 *offset_out = consumed - offset; |
8790 return string; | 8790 return string; |
8791 } | 8791 } |
8792 UNREACHABLE(); | 8792 UNREACHABLE(); |
8793 return NULL; | 8793 return NULL; |
8794 } | 8794 } |
8795 | 8795 |
8796 | 8796 |
(...skipping 25 matching lines...) Expand all Loading... |
8822 cons_string = ConsString::cast(string); | 8822 cons_string = ConsString::cast(string); |
8823 PushRight(cons_string); | 8823 PushRight(cons_string); |
8824 // Need to traverse all the way left. | 8824 // Need to traverse all the way left. |
8825 while (true) { | 8825 while (true) { |
8826 // Continue left. | 8826 // Continue left. |
8827 string = cons_string->first(); | 8827 string = cons_string->first(); |
8828 type = string->map()->instance_type(); | 8828 type = string->map()->instance_type(); |
8829 if ((type & kStringRepresentationMask) != kConsStringTag) { | 8829 if ((type & kStringRepresentationMask) != kConsStringTag) { |
8830 AdjustMaximumDepth(); | 8830 AdjustMaximumDepth(); |
8831 int length = string->length(); | 8831 int length = string->length(); |
8832 ASSERT(length != 0); | 8832 DCHECK(length != 0); |
8833 consumed_ += length; | 8833 consumed_ += length; |
8834 return string; | 8834 return string; |
8835 } | 8835 } |
8836 cons_string = ConsString::cast(string); | 8836 cons_string = ConsString::cast(string); |
8837 PushLeft(cons_string); | 8837 PushLeft(cons_string); |
8838 } | 8838 } |
8839 } | 8839 } |
8840 UNREACHABLE(); | 8840 UNREACHABLE(); |
8841 return NULL; | 8841 return NULL; |
8842 } | 8842 } |
8843 | 8843 |
8844 | 8844 |
8845 uint16_t ConsString::ConsStringGet(int index) { | 8845 uint16_t ConsString::ConsStringGet(int index) { |
8846 ASSERT(index >= 0 && index < this->length()); | 8846 DCHECK(index >= 0 && index < this->length()); |
8847 | 8847 |
8848 // Check for a flattened cons string | 8848 // Check for a flattened cons string |
8849 if (second()->length() == 0) { | 8849 if (second()->length() == 0) { |
8850 String* left = first(); | 8850 String* left = first(); |
8851 return left->Get(index); | 8851 return left->Get(index); |
8852 } | 8852 } |
8853 | 8853 |
8854 String* string = String::cast(this); | 8854 String* string = String::cast(this); |
8855 | 8855 |
8856 while (true) { | 8856 while (true) { |
(...skipping 23 matching lines...) Expand all Loading... |
8880 | 8880 |
8881 template <typename sinkchar> | 8881 template <typename sinkchar> |
8882 void String::WriteToFlat(String* src, | 8882 void String::WriteToFlat(String* src, |
8883 sinkchar* sink, | 8883 sinkchar* sink, |
8884 int f, | 8884 int f, |
8885 int t) { | 8885 int t) { |
8886 String* source = src; | 8886 String* source = src; |
8887 int from = f; | 8887 int from = f; |
8888 int to = t; | 8888 int to = t; |
8889 while (true) { | 8889 while (true) { |
8890 ASSERT(0 <= from && from <= to && to <= source->length()); | 8890 DCHECK(0 <= from && from <= to && to <= source->length()); |
8891 switch (StringShape(source).full_representation_tag()) { | 8891 switch (StringShape(source).full_representation_tag()) { |
8892 case kOneByteStringTag | kExternalStringTag: { | 8892 case kOneByteStringTag | kExternalStringTag: { |
8893 CopyChars(sink, | 8893 CopyChars(sink, |
8894 ExternalAsciiString::cast(source)->GetChars() + from, | 8894 ExternalAsciiString::cast(source)->GetChars() + from, |
8895 to - from); | 8895 to - from); |
8896 return; | 8896 return; |
8897 } | 8897 } |
8898 case kTwoByteStringTag | kExternalStringTag: { | 8898 case kTwoByteStringTag | kExternalStringTag: { |
8899 const uc16* data = | 8899 const uc16* data = |
8900 ExternalTwoByteString::cast(source)->GetChars(); | 8900 ExternalTwoByteString::cast(source)->GetChars(); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8997 bool include_ending_line) { | 8997 bool include_ending_line) { |
8998 src = Flatten(src); | 8998 src = Flatten(src); |
8999 // Rough estimate of line count based on a roughly estimated average | 8999 // Rough estimate of line count based on a roughly estimated average |
9000 // length of (unpacked) code. | 9000 // length of (unpacked) code. |
9001 int line_count_estimate = src->length() >> 4; | 9001 int line_count_estimate = src->length() >> 4; |
9002 List<int> line_ends(line_count_estimate); | 9002 List<int> line_ends(line_count_estimate); |
9003 Isolate* isolate = src->GetIsolate(); | 9003 Isolate* isolate = src->GetIsolate(); |
9004 { DisallowHeapAllocation no_allocation; // ensure vectors stay valid. | 9004 { DisallowHeapAllocation no_allocation; // ensure vectors stay valid. |
9005 // Dispatch on type of strings. | 9005 // Dispatch on type of strings. |
9006 String::FlatContent content = src->GetFlatContent(); | 9006 String::FlatContent content = src->GetFlatContent(); |
9007 ASSERT(content.IsFlat()); | 9007 DCHECK(content.IsFlat()); |
9008 if (content.IsAscii()) { | 9008 if (content.IsAscii()) { |
9009 CalculateLineEndsImpl(isolate, | 9009 CalculateLineEndsImpl(isolate, |
9010 &line_ends, | 9010 &line_ends, |
9011 content.ToOneByteVector(), | 9011 content.ToOneByteVector(), |
9012 include_ending_line); | 9012 include_ending_line); |
9013 } else { | 9013 } else { |
9014 CalculateLineEndsImpl(isolate, | 9014 CalculateLineEndsImpl(isolate, |
9015 &line_ends, | 9015 &line_ends, |
9016 content.ToUC16Vector(), | 9016 content.ToUC16Vector(), |
9017 include_ending_line); | 9017 include_ending_line); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9062 } | 9062 } |
9063 } | 9063 } |
9064 return true; | 9064 return true; |
9065 } | 9065 } |
9066 | 9066 |
9067 | 9067 |
9068 template<typename Chars1, typename Chars2> | 9068 template<typename Chars1, typename Chars2> |
9069 class RawStringComparator : public AllStatic { | 9069 class RawStringComparator : public AllStatic { |
9070 public: | 9070 public: |
9071 static inline bool compare(const Chars1* a, const Chars2* b, int len) { | 9071 static inline bool compare(const Chars1* a, const Chars2* b, int len) { |
9072 ASSERT(sizeof(Chars1) != sizeof(Chars2)); | 9072 DCHECK(sizeof(Chars1) != sizeof(Chars2)); |
9073 for (int i = 0; i < len; i++) { | 9073 for (int i = 0; i < len; i++) { |
9074 if (a[i] != b[i]) { | 9074 if (a[i] != b[i]) { |
9075 return false; | 9075 return false; |
9076 } | 9076 } |
9077 } | 9077 } |
9078 return true; | 9078 return true; |
9079 } | 9079 } |
9080 }; | 9080 }; |
9081 | 9081 |
9082 | 9082 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9120 length_ = length; | 9120 length_ = length; |
9121 } | 9121 } |
9122 | 9122 |
9123 inline void VisitTwoByteString(const uint16_t* chars, int length) { | 9123 inline void VisitTwoByteString(const uint16_t* chars, int length) { |
9124 is_one_byte_ = false; | 9124 is_one_byte_ = false; |
9125 buffer16_ = chars; | 9125 buffer16_ = chars; |
9126 length_ = length; | 9126 length_ = length; |
9127 } | 9127 } |
9128 | 9128 |
9129 void Advance(int consumed) { | 9129 void Advance(int consumed) { |
9130 ASSERT(consumed <= length_); | 9130 DCHECK(consumed <= length_); |
9131 // Still in buffer. | 9131 // Still in buffer. |
9132 if (length_ != consumed) { | 9132 if (length_ != consumed) { |
9133 if (is_one_byte_) { | 9133 if (is_one_byte_) { |
9134 buffer8_ += consumed; | 9134 buffer8_ += consumed; |
9135 } else { | 9135 } else { |
9136 buffer16_ += consumed; | 9136 buffer16_ += consumed; |
9137 } | 9137 } |
9138 length_ -= consumed; | 9138 length_ -= consumed; |
9139 return; | 9139 return; |
9140 } | 9140 } |
9141 // Advance state. | 9141 // Advance state. |
9142 int offset; | 9142 int offset; |
9143 String* next = op_->Next(&offset); | 9143 String* next = op_->Next(&offset); |
9144 ASSERT_EQ(0, offset); | 9144 DCHECK_EQ(0, offset); |
9145 ASSERT(next != NULL); | 9145 DCHECK(next != NULL); |
9146 String::VisitFlat(this, next); | 9146 String::VisitFlat(this, next); |
9147 } | 9147 } |
9148 | 9148 |
9149 ConsStringIteratorOp* const op_; | 9149 ConsStringIteratorOp* const op_; |
9150 bool is_one_byte_; | 9150 bool is_one_byte_; |
9151 int length_; | 9151 int length_; |
9152 union { | 9152 union { |
9153 const uint8_t* buffer8_; | 9153 const uint8_t* buffer8_; |
9154 const uint16_t* buffer16_; | 9154 const uint16_t* buffer16_; |
9155 }; | 9155 }; |
(...skipping 15 matching lines...) Expand all Loading... |
9171 const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_); | 9171 const Chars2* b = reinterpret_cast<const Chars2*>(state_2->buffer8_); |
9172 return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check); | 9172 return RawStringComparator<Chars1, Chars2>::compare(a, b, to_check); |
9173 } | 9173 } |
9174 | 9174 |
9175 bool Equals(String* string_1, String* string_2) { | 9175 bool Equals(String* string_1, String* string_2) { |
9176 int length = string_1->length(); | 9176 int length = string_1->length(); |
9177 state_1_.Init(string_1); | 9177 state_1_.Init(string_1); |
9178 state_2_.Init(string_2); | 9178 state_2_.Init(string_2); |
9179 while (true) { | 9179 while (true) { |
9180 int to_check = Min(state_1_.length_, state_2_.length_); | 9180 int to_check = Min(state_1_.length_, state_2_.length_); |
9181 ASSERT(to_check > 0 && to_check <= length); | 9181 DCHECK(to_check > 0 && to_check <= length); |
9182 bool is_equal; | 9182 bool is_equal; |
9183 if (state_1_.is_one_byte_) { | 9183 if (state_1_.is_one_byte_) { |
9184 if (state_2_.is_one_byte_) { | 9184 if (state_2_.is_one_byte_) { |
9185 is_equal = Equals<uint8_t, uint8_t>(&state_1_, &state_2_, to_check); | 9185 is_equal = Equals<uint8_t, uint8_t>(&state_1_, &state_2_, to_check); |
9186 } else { | 9186 } else { |
9187 is_equal = Equals<uint8_t, uint16_t>(&state_1_, &state_2_, to_check); | 9187 is_equal = Equals<uint8_t, uint16_t>(&state_1_, &state_2_, to_check); |
9188 } | 9188 } |
9189 } else { | 9189 } else { |
9190 if (state_2_.is_one_byte_) { | 9190 if (state_2_.is_one_byte_) { |
9191 is_equal = Equals<uint16_t, uint8_t>(&state_1_, &state_2_, to_check); | 9191 is_equal = Equals<uint16_t, uint8_t>(&state_1_, &state_2_, to_check); |
(...skipping 21 matching lines...) Expand all Loading... |
9213 bool String::SlowEquals(String* other) { | 9213 bool String::SlowEquals(String* other) { |
9214 DisallowHeapAllocation no_gc; | 9214 DisallowHeapAllocation no_gc; |
9215 // Fast check: negative check with lengths. | 9215 // Fast check: negative check with lengths. |
9216 int len = length(); | 9216 int len = length(); |
9217 if (len != other->length()) return false; | 9217 if (len != other->length()) return false; |
9218 if (len == 0) return true; | 9218 if (len == 0) return true; |
9219 | 9219 |
9220 // Fast check: if hash code is computed for both strings | 9220 // Fast check: if hash code is computed for both strings |
9221 // a fast negative check can be performed. | 9221 // a fast negative check can be performed. |
9222 if (HasHashCode() && other->HasHashCode()) { | 9222 if (HasHashCode() && other->HasHashCode()) { |
9223 #ifdef ENABLE_SLOW_ASSERTS | 9223 #ifdef ENABLE_SLOW_DCHECKS |
9224 if (FLAG_enable_slow_asserts) { | 9224 if (FLAG_enable_slow_asserts) { |
9225 if (Hash() != other->Hash()) { | 9225 if (Hash() != other->Hash()) { |
9226 bool found_difference = false; | 9226 bool found_difference = false; |
9227 for (int i = 0; i < len; i++) { | 9227 for (int i = 0; i < len; i++) { |
9228 if (Get(i) != other->Get(i)) { | 9228 if (Get(i) != other->Get(i)) { |
9229 found_difference = true; | 9229 found_difference = true; |
9230 break; | 9230 break; |
9231 } | 9231 } |
9232 } | 9232 } |
9233 ASSERT(found_difference); | 9233 DCHECK(found_difference); |
9234 } | 9234 } |
9235 } | 9235 } |
9236 #endif | 9236 #endif |
9237 if (Hash() != other->Hash()) return false; | 9237 if (Hash() != other->Hash()) return false; |
9238 } | 9238 } |
9239 | 9239 |
9240 // We know the strings are both non-empty. Compare the first chars | 9240 // We know the strings are both non-empty. Compare the first chars |
9241 // before we try to flatten the strings. | 9241 // before we try to flatten the strings. |
9242 if (this->Get(0) != other->Get(0)) return false; | 9242 if (this->Get(0) != other->Get(0)) return false; |
9243 | 9243 |
(...skipping 13 matching lines...) Expand all Loading... |
9257 | 9257 |
9258 bool String::SlowEquals(Handle<String> one, Handle<String> two) { | 9258 bool String::SlowEquals(Handle<String> one, Handle<String> two) { |
9259 // Fast check: negative check with lengths. | 9259 // Fast check: negative check with lengths. |
9260 int one_length = one->length(); | 9260 int one_length = one->length(); |
9261 if (one_length != two->length()) return false; | 9261 if (one_length != two->length()) return false; |
9262 if (one_length == 0) return true; | 9262 if (one_length == 0) return true; |
9263 | 9263 |
9264 // Fast check: if hash code is computed for both strings | 9264 // Fast check: if hash code is computed for both strings |
9265 // a fast negative check can be performed. | 9265 // a fast negative check can be performed. |
9266 if (one->HasHashCode() && two->HasHashCode()) { | 9266 if (one->HasHashCode() && two->HasHashCode()) { |
9267 #ifdef ENABLE_SLOW_ASSERTS | 9267 #ifdef ENABLE_SLOW_DCHECKS |
9268 if (FLAG_enable_slow_asserts) { | 9268 if (FLAG_enable_slow_asserts) { |
9269 if (one->Hash() != two->Hash()) { | 9269 if (one->Hash() != two->Hash()) { |
9270 bool found_difference = false; | 9270 bool found_difference = false; |
9271 for (int i = 0; i < one_length; i++) { | 9271 for (int i = 0; i < one_length; i++) { |
9272 if (one->Get(i) != two->Get(i)) { | 9272 if (one->Get(i) != two->Get(i)) { |
9273 found_difference = true; | 9273 found_difference = true; |
9274 break; | 9274 break; |
9275 } | 9275 } |
9276 } | 9276 } |
9277 ASSERT(found_difference); | 9277 DCHECK(found_difference); |
9278 } | 9278 } |
9279 } | 9279 } |
9280 #endif | 9280 #endif |
9281 if (one->Hash() != two->Hash()) return false; | 9281 if (one->Hash() != two->Hash()) return false; |
9282 } | 9282 } |
9283 | 9283 |
9284 // We know the strings are both non-empty. Compare the first chars | 9284 // We know the strings are both non-empty. Compare the first chars |
9285 // before we try to flatten the strings. | 9285 // before we try to flatten the strings. |
9286 if (one->Get(0) != two->Get(0)) return false; | 9286 if (one->Get(0) != two->Get(0)) return false; |
9287 | 9287 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9330 (str_len < slen || | 9330 (str_len < slen || |
9331 str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) { | 9331 str_len > slen*static_cast<int>(unibrow::Utf8::kMaxEncodedSize))) { |
9332 return false; | 9332 return false; |
9333 } | 9333 } |
9334 int i; | 9334 int i; |
9335 unsigned remaining_in_str = static_cast<unsigned>(str_len); | 9335 unsigned remaining_in_str = static_cast<unsigned>(str_len); |
9336 const uint8_t* utf8_data = reinterpret_cast<const uint8_t*>(str.start()); | 9336 const uint8_t* utf8_data = reinterpret_cast<const uint8_t*>(str.start()); |
9337 for (i = 0; i < slen && remaining_in_str > 0; i++) { | 9337 for (i = 0; i < slen && remaining_in_str > 0; i++) { |
9338 unsigned cursor = 0; | 9338 unsigned cursor = 0; |
9339 uint32_t r = unibrow::Utf8::ValueOf(utf8_data, remaining_in_str, &cursor); | 9339 uint32_t r = unibrow::Utf8::ValueOf(utf8_data, remaining_in_str, &cursor); |
9340 ASSERT(cursor > 0 && cursor <= remaining_in_str); | 9340 DCHECK(cursor > 0 && cursor <= remaining_in_str); |
9341 if (r > unibrow::Utf16::kMaxNonSurrogateCharCode) { | 9341 if (r > unibrow::Utf16::kMaxNonSurrogateCharCode) { |
9342 if (i > slen - 1) return false; | 9342 if (i > slen - 1) return false; |
9343 if (Get(i++) != unibrow::Utf16::LeadSurrogate(r)) return false; | 9343 if (Get(i++) != unibrow::Utf16::LeadSurrogate(r)) return false; |
9344 if (Get(i) != unibrow::Utf16::TrailSurrogate(r)) return false; | 9344 if (Get(i) != unibrow::Utf16::TrailSurrogate(r)) return false; |
9345 } else { | 9345 } else { |
9346 if (Get(i) != r) return false; | 9346 if (Get(i) != r) return false; |
9347 } | 9347 } |
9348 utf8_data += cursor; | 9348 utf8_data += cursor; |
9349 remaining_in_str -= cursor; | 9349 remaining_in_str -= cursor; |
9350 } | 9350 } |
(...skipping 27 matching lines...) Expand all Loading... |
9378 } | 9378 } |
9379 for (int i = 0; i < slen; i++) { | 9379 for (int i = 0; i < slen; i++) { |
9380 if (Get(i) != str[i]) return false; | 9380 if (Get(i) != str[i]) return false; |
9381 } | 9381 } |
9382 return true; | 9382 return true; |
9383 } | 9383 } |
9384 | 9384 |
9385 | 9385 |
9386 uint32_t String::ComputeAndSetHash() { | 9386 uint32_t String::ComputeAndSetHash() { |
9387 // Should only be called if hash code has not yet been computed. | 9387 // Should only be called if hash code has not yet been computed. |
9388 ASSERT(!HasHashCode()); | 9388 DCHECK(!HasHashCode()); |
9389 | 9389 |
9390 // Store the hash code in the object. | 9390 // Store the hash code in the object. |
9391 uint32_t field = IteratingStringHasher::Hash(this, GetHeap()->HashSeed()); | 9391 uint32_t field = IteratingStringHasher::Hash(this, GetHeap()->HashSeed()); |
9392 set_hash_field(field); | 9392 set_hash_field(field); |
9393 | 9393 |
9394 // Check the hash code is there. | 9394 // Check the hash code is there. |
9395 ASSERT(HasHashCode()); | 9395 DCHECK(HasHashCode()); |
9396 uint32_t result = field >> kHashShift; | 9396 uint32_t result = field >> kHashShift; |
9397 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 9397 DCHECK(result != 0); // Ensure that the hash value of 0 is never computed. |
9398 return result; | 9398 return result; |
9399 } | 9399 } |
9400 | 9400 |
9401 | 9401 |
9402 bool String::ComputeArrayIndex(uint32_t* index) { | 9402 bool String::ComputeArrayIndex(uint32_t* index) { |
9403 int length = this->length(); | 9403 int length = this->length(); |
9404 if (length == 0 || length > kMaxArrayIndexSize) return false; | 9404 if (length == 0 || length > kMaxArrayIndexSize) return false; |
9405 ConsStringIteratorOp op; | 9405 ConsStringIteratorOp op; |
9406 StringCharacterStream stream(this, &op); | 9406 StringCharacterStream stream(this, &op); |
9407 return StringToArrayIndex(&stream, index); | 9407 return StringToArrayIndex(&stream, index); |
(...skipping 16 matching lines...) Expand all Loading... |
9424 | 9424 |
9425 Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) { | 9425 Handle<String> SeqString::Truncate(Handle<SeqString> string, int new_length) { |
9426 int new_size, old_size; | 9426 int new_size, old_size; |
9427 int old_length = string->length(); | 9427 int old_length = string->length(); |
9428 if (old_length <= new_length) return string; | 9428 if (old_length <= new_length) return string; |
9429 | 9429 |
9430 if (string->IsSeqOneByteString()) { | 9430 if (string->IsSeqOneByteString()) { |
9431 old_size = SeqOneByteString::SizeFor(old_length); | 9431 old_size = SeqOneByteString::SizeFor(old_length); |
9432 new_size = SeqOneByteString::SizeFor(new_length); | 9432 new_size = SeqOneByteString::SizeFor(new_length); |
9433 } else { | 9433 } else { |
9434 ASSERT(string->IsSeqTwoByteString()); | 9434 DCHECK(string->IsSeqTwoByteString()); |
9435 old_size = SeqTwoByteString::SizeFor(old_length); | 9435 old_size = SeqTwoByteString::SizeFor(old_length); |
9436 new_size = SeqTwoByteString::SizeFor(new_length); | 9436 new_size = SeqTwoByteString::SizeFor(new_length); |
9437 } | 9437 } |
9438 | 9438 |
9439 int delta = old_size - new_size; | 9439 int delta = old_size - new_size; |
9440 | 9440 |
9441 Address start_of_string = string->address(); | 9441 Address start_of_string = string->address(); |
9442 ASSERT_OBJECT_ALIGNED(start_of_string); | 9442 DCHECK_OBJECT_ALIGNED(start_of_string); |
9443 ASSERT_OBJECT_ALIGNED(start_of_string + new_size); | 9443 DCHECK_OBJECT_ALIGNED(start_of_string + new_size); |
9444 | 9444 |
9445 Heap* heap = string->GetHeap(); | 9445 Heap* heap = string->GetHeap(); |
9446 NewSpace* newspace = heap->new_space(); | 9446 NewSpace* newspace = heap->new_space(); |
9447 if (newspace->Contains(start_of_string) && | 9447 if (newspace->Contains(start_of_string) && |
9448 newspace->top() == start_of_string + old_size) { | 9448 newspace->top() == start_of_string + old_size) { |
9449 // Last allocated object in new space. Simply lower allocation top. | 9449 // Last allocated object in new space. Simply lower allocation top. |
9450 newspace->set_top(start_of_string + new_size); | 9450 newspace->set_top(start_of_string + new_size); |
9451 } else { | 9451 } else { |
9452 // Sizes are pointer size aligned, so that we can use filler objects | 9452 // Sizes are pointer size aligned, so that we can use filler objects |
9453 // that are a multiple of pointer size. | 9453 // that are a multiple of pointer size. |
9454 heap->CreateFillerObjectAt(start_of_string + new_size, delta); | 9454 heap->CreateFillerObjectAt(start_of_string + new_size, delta); |
9455 } | 9455 } |
9456 heap->AdjustLiveBytes(start_of_string, -delta, Heap::FROM_MUTATOR); | 9456 heap->AdjustLiveBytes(start_of_string, -delta, Heap::FROM_MUTATOR); |
9457 | 9457 |
9458 // We are storing the new length using release store after creating a filler | 9458 // We are storing the new length using release store after creating a filler |
9459 // for the left-over space to avoid races with the sweeper thread. | 9459 // for the left-over space to avoid races with the sweeper thread. |
9460 string->synchronized_set_length(new_length); | 9460 string->synchronized_set_length(new_length); |
9461 | 9461 |
9462 if (new_length == 0) return heap->isolate()->factory()->empty_string(); | 9462 if (new_length == 0) return heap->isolate()->factory()->empty_string(); |
9463 return string; | 9463 return string; |
9464 } | 9464 } |
9465 | 9465 |
9466 | 9466 |
9467 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { | 9467 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { |
9468 // For array indexes mix the length into the hash as an array index could | 9468 // For array indexes mix the length into the hash as an array index could |
9469 // be zero. | 9469 // be zero. |
9470 ASSERT(length > 0); | 9470 DCHECK(length > 0); |
9471 ASSERT(length <= String::kMaxArrayIndexSize); | 9471 DCHECK(length <= String::kMaxArrayIndexSize); |
9472 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < | 9472 DCHECK(TenToThe(String::kMaxCachedArrayIndexLength) < |
9473 (1 << String::kArrayIndexValueBits)); | 9473 (1 << String::kArrayIndexValueBits)); |
9474 | 9474 |
9475 value <<= String::ArrayIndexValueBits::kShift; | 9475 value <<= String::ArrayIndexValueBits::kShift; |
9476 value |= length << String::ArrayIndexLengthBits::kShift; | 9476 value |= length << String::ArrayIndexLengthBits::kShift; |
9477 | 9477 |
9478 ASSERT((value & String::kIsNotArrayIndexMask) == 0); | 9478 DCHECK((value & String::kIsNotArrayIndexMask) == 0); |
9479 ASSERT((length > String::kMaxCachedArrayIndexLength) || | 9479 DCHECK((length > String::kMaxCachedArrayIndexLength) || |
9480 (value & String::kContainsCachedArrayIndexMask) == 0); | 9480 (value & String::kContainsCachedArrayIndexMask) == 0); |
9481 return value; | 9481 return value; |
9482 } | 9482 } |
9483 | 9483 |
9484 | 9484 |
9485 uint32_t StringHasher::GetHashField() { | 9485 uint32_t StringHasher::GetHashField() { |
9486 if (length_ <= String::kMaxHashCalcLength) { | 9486 if (length_ <= String::kMaxHashCalcLength) { |
9487 if (is_array_index_) { | 9487 if (is_array_index_) { |
9488 return MakeArrayIndexHash(array_index_, length_); | 9488 return MakeArrayIndexHash(array_index_, length_); |
9489 } | 9489 } |
9490 return (GetHashCore(raw_running_hash_) << String::kHashShift) | | 9490 return (GetHashCore(raw_running_hash_) << String::kHashShift) | |
9491 String::kIsNotArrayIndexMask; | 9491 String::kIsNotArrayIndexMask; |
9492 } else { | 9492 } else { |
9493 return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask; | 9493 return (length_ << String::kHashShift) | String::kIsNotArrayIndexMask; |
9494 } | 9494 } |
9495 } | 9495 } |
9496 | 9496 |
9497 | 9497 |
9498 uint32_t StringHasher::ComputeUtf8Hash(Vector<const char> chars, | 9498 uint32_t StringHasher::ComputeUtf8Hash(Vector<const char> chars, |
9499 uint32_t seed, | 9499 uint32_t seed, |
9500 int* utf16_length_out) { | 9500 int* utf16_length_out) { |
9501 int vector_length = chars.length(); | 9501 int vector_length = chars.length(); |
9502 // Handle some edge cases | 9502 // Handle some edge cases |
9503 if (vector_length <= 1) { | 9503 if (vector_length <= 1) { |
9504 ASSERT(vector_length == 0 || | 9504 DCHECK(vector_length == 0 || |
9505 static_cast<uint8_t>(chars.start()[0]) <= | 9505 static_cast<uint8_t>(chars.start()[0]) <= |
9506 unibrow::Utf8::kMaxOneByteChar); | 9506 unibrow::Utf8::kMaxOneByteChar); |
9507 *utf16_length_out = vector_length; | 9507 *utf16_length_out = vector_length; |
9508 return HashSequentialString(chars.start(), vector_length, seed); | 9508 return HashSequentialString(chars.start(), vector_length, seed); |
9509 } | 9509 } |
9510 // Start with a fake length which won't affect computation. | 9510 // Start with a fake length which won't affect computation. |
9511 // It will be updated later. | 9511 // It will be updated later. |
9512 StringHasher hasher(String::kMaxArrayIndexSize, seed); | 9512 StringHasher hasher(String::kMaxArrayIndexSize, seed); |
9513 unsigned remaining = static_cast<unsigned>(vector_length); | 9513 unsigned remaining = static_cast<unsigned>(vector_length); |
9514 const uint8_t* stream = reinterpret_cast<const uint8_t*>(chars.start()); | 9514 const uint8_t* stream = reinterpret_cast<const uint8_t*>(chars.start()); |
9515 int utf16_length = 0; | 9515 int utf16_length = 0; |
9516 bool is_index = true; | 9516 bool is_index = true; |
9517 ASSERT(hasher.is_array_index_); | 9517 DCHECK(hasher.is_array_index_); |
9518 while (remaining > 0) { | 9518 while (remaining > 0) { |
9519 unsigned consumed = 0; | 9519 unsigned consumed = 0; |
9520 uint32_t c = unibrow::Utf8::ValueOf(stream, remaining, &consumed); | 9520 uint32_t c = unibrow::Utf8::ValueOf(stream, remaining, &consumed); |
9521 ASSERT(consumed > 0 && consumed <= remaining); | 9521 DCHECK(consumed > 0 && consumed <= remaining); |
9522 stream += consumed; | 9522 stream += consumed; |
9523 remaining -= consumed; | 9523 remaining -= consumed; |
9524 bool is_two_characters = c > unibrow::Utf16::kMaxNonSurrogateCharCode; | 9524 bool is_two_characters = c > unibrow::Utf16::kMaxNonSurrogateCharCode; |
9525 utf16_length += is_two_characters ? 2 : 1; | 9525 utf16_length += is_two_characters ? 2 : 1; |
9526 // No need to keep hashing. But we do need to calculate utf16_length. | 9526 // No need to keep hashing. But we do need to calculate utf16_length. |
9527 if (utf16_length > String::kMaxHashCalcLength) continue; | 9527 if (utf16_length > String::kMaxHashCalcLength) continue; |
9528 if (is_two_characters) { | 9528 if (is_two_characters) { |
9529 uint16_t c1 = unibrow::Utf16::LeadSurrogate(c); | 9529 uint16_t c1 = unibrow::Utf16::LeadSurrogate(c); |
9530 uint16_t c2 = unibrow::Utf16::TrailSurrogate(c); | 9530 uint16_t c2 = unibrow::Utf16::TrailSurrogate(c); |
9531 hasher.AddCharacter(c1); | 9531 hasher.AddCharacter(c1); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9638 // If there are no transitions to be cleared, return. | 9638 // If there are no transitions to be cleared, return. |
9639 // TODO(verwaest) Should be an assert, otherwise back pointers are not | 9639 // TODO(verwaest) Should be an assert, otherwise back pointers are not |
9640 // properly cleared. | 9640 // properly cleared. |
9641 if (transition_index == t->number_of_transitions()) return; | 9641 if (transition_index == t->number_of_transitions()) return; |
9642 | 9642 |
9643 int number_of_own_descriptors = NumberOfOwnDescriptors(); | 9643 int number_of_own_descriptors = NumberOfOwnDescriptors(); |
9644 | 9644 |
9645 if (descriptors_owner_died) { | 9645 if (descriptors_owner_died) { |
9646 if (number_of_own_descriptors > 0) { | 9646 if (number_of_own_descriptors > 0) { |
9647 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); | 9647 TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); |
9648 ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); | 9648 DCHECK(descriptors->number_of_descriptors() == number_of_own_descriptors); |
9649 set_owns_descriptors(true); | 9649 set_owns_descriptors(true); |
9650 } else { | 9650 } else { |
9651 ASSERT(descriptors == GetHeap()->empty_descriptor_array()); | 9651 DCHECK(descriptors == GetHeap()->empty_descriptor_array()); |
9652 } | 9652 } |
9653 } | 9653 } |
9654 | 9654 |
9655 // Note that we never eliminate a transition array, though we might right-trim | 9655 // Note that we never eliminate a transition array, though we might right-trim |
9656 // such that number_of_transitions() == 0. If this assumption changes, | 9656 // such that number_of_transitions() == 0. If this assumption changes, |
9657 // TransitionArray::CopyInsert() will need to deal with the case that a | 9657 // TransitionArray::CopyInsert() will need to deal with the case that a |
9658 // transition array disappeared during GC. | 9658 // transition array disappeared during GC. |
9659 int trim = t->number_of_transitions() - transition_index; | 9659 int trim = t->number_of_transitions() - transition_index; |
9660 if (trim > 0) { | 9660 if (trim > 0) { |
9661 RightTrimFixedArray<Heap::FROM_GC>(heap, t, t->IsSimpleTransition() | 9661 RightTrimFixedArray<Heap::FROM_GC>(heap, t, t->IsSimpleTransition() |
9662 ? trim : trim * TransitionArray::kTransitionSize); | 9662 ? trim : trim * TransitionArray::kTransitionSize); |
9663 } | 9663 } |
9664 ASSERT(HasTransitionArray()); | 9664 DCHECK(HasTransitionArray()); |
9665 } | 9665 } |
9666 | 9666 |
9667 | 9667 |
9668 int Map::Hash() { | 9668 int Map::Hash() { |
9669 // For performance reasons we only hash the 3 most variable fields of a map: | 9669 // For performance reasons we only hash the 3 most variable fields of a map: |
9670 // constructor, prototype and bit_field2. | 9670 // constructor, prototype and bit_field2. |
9671 | 9671 |
9672 // Shift away the tag. | 9672 // Shift away the tag. |
9673 int hash = (static_cast<uint32_t>( | 9673 int hash = (static_cast<uint32_t>( |
9674 reinterpret_cast<uintptr_t>(constructor())) >> 2); | 9674 reinterpret_cast<uintptr_t>(constructor())) >> 2); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9754 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { | 9754 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { |
9755 // Iterate over all fields in the body but take care in dealing with | 9755 // Iterate over all fields in the body but take care in dealing with |
9756 // the code entry. | 9756 // the code entry. |
9757 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); | 9757 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); |
9758 v->VisitCodeEntry(this->address() + kCodeEntryOffset); | 9758 v->VisitCodeEntry(this->address() + kCodeEntryOffset); |
9759 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); | 9759 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); |
9760 } | 9760 } |
9761 | 9761 |
9762 | 9762 |
9763 void JSFunction::MarkForOptimization() { | 9763 void JSFunction::MarkForOptimization() { |
9764 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); | 9764 DCHECK(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); |
9765 ASSERT(!IsOptimized()); | 9765 DCHECK(!IsOptimized()); |
9766 ASSERT(shared()->allows_lazy_compilation() || | 9766 DCHECK(shared()->allows_lazy_compilation() || |
9767 code()->optimizable()); | 9767 code()->optimizable()); |
9768 ASSERT(!shared()->is_generator()); | 9768 DCHECK(!shared()->is_generator()); |
9769 set_code_no_write_barrier( | 9769 set_code_no_write_barrier( |
9770 GetIsolate()->builtins()->builtin(Builtins::kCompileOptimized)); | 9770 GetIsolate()->builtins()->builtin(Builtins::kCompileOptimized)); |
9771 // No write barrier required, since the builtin is part of the root set. | 9771 // No write barrier required, since the builtin is part of the root set. |
9772 } | 9772 } |
9773 | 9773 |
9774 | 9774 |
9775 void JSFunction::MarkForConcurrentOptimization() { | 9775 void JSFunction::MarkForConcurrentOptimization() { |
9776 ASSERT(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); | 9776 DCHECK(is_compiled() || GetIsolate()->DebuggerHasBreakPoints()); |
9777 ASSERT(!IsOptimized()); | 9777 DCHECK(!IsOptimized()); |
9778 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); | 9778 DCHECK(shared()->allows_lazy_compilation() || code()->optimizable()); |
9779 ASSERT(!shared()->is_generator()); | 9779 DCHECK(!shared()->is_generator()); |
9780 ASSERT(GetIsolate()->concurrent_recompilation_enabled()); | 9780 DCHECK(GetIsolate()->concurrent_recompilation_enabled()); |
9781 if (FLAG_trace_concurrent_recompilation) { | 9781 if (FLAG_trace_concurrent_recompilation) { |
9782 PrintF(" ** Marking "); | 9782 PrintF(" ** Marking "); |
9783 PrintName(); | 9783 PrintName(); |
9784 PrintF(" for concurrent recompilation.\n"); | 9784 PrintF(" for concurrent recompilation.\n"); |
9785 } | 9785 } |
9786 set_code_no_write_barrier( | 9786 set_code_no_write_barrier( |
9787 GetIsolate()->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); | 9787 GetIsolate()->builtins()->builtin(Builtins::kCompileOptimizedConcurrent)); |
9788 // No write barrier required, since the builtin is part of the root set. | 9788 // No write barrier required, since the builtin is part of the root set. |
9789 } | 9789 } |
9790 | 9790 |
9791 | 9791 |
9792 void JSFunction::MarkInOptimizationQueue() { | 9792 void JSFunction::MarkInOptimizationQueue() { |
9793 // We can only arrive here via the concurrent-recompilation builtin. If | 9793 // We can only arrive here via the concurrent-recompilation builtin. If |
9794 // break points were set, the code would point to the lazy-compile builtin. | 9794 // break points were set, the code would point to the lazy-compile builtin. |
9795 ASSERT(!GetIsolate()->DebuggerHasBreakPoints()); | 9795 DCHECK(!GetIsolate()->DebuggerHasBreakPoints()); |
9796 ASSERT(IsMarkedForConcurrentOptimization() && !IsOptimized()); | 9796 DCHECK(IsMarkedForConcurrentOptimization() && !IsOptimized()); |
9797 ASSERT(shared()->allows_lazy_compilation() || code()->optimizable()); | 9797 DCHECK(shared()->allows_lazy_compilation() || code()->optimizable()); |
9798 ASSERT(GetIsolate()->concurrent_recompilation_enabled()); | 9798 DCHECK(GetIsolate()->concurrent_recompilation_enabled()); |
9799 if (FLAG_trace_concurrent_recompilation) { | 9799 if (FLAG_trace_concurrent_recompilation) { |
9800 PrintF(" ** Queueing "); | 9800 PrintF(" ** Queueing "); |
9801 PrintName(); | 9801 PrintName(); |
9802 PrintF(" for concurrent recompilation.\n"); | 9802 PrintF(" for concurrent recompilation.\n"); |
9803 } | 9803 } |
9804 set_code_no_write_barrier( | 9804 set_code_no_write_barrier( |
9805 GetIsolate()->builtins()->builtin(Builtins::kInOptimizationQueue)); | 9805 GetIsolate()->builtins()->builtin(Builtins::kInOptimizationQueue)); |
9806 // No write barrier required, since the builtin is part of the root set. | 9806 // No write barrier required, since the builtin is part of the root set. |
9807 } | 9807 } |
9808 | 9808 |
9809 | 9809 |
9810 void SharedFunctionInfo::AddToOptimizedCodeMap( | 9810 void SharedFunctionInfo::AddToOptimizedCodeMap( |
9811 Handle<SharedFunctionInfo> shared, | 9811 Handle<SharedFunctionInfo> shared, |
9812 Handle<Context> native_context, | 9812 Handle<Context> native_context, |
9813 Handle<Code> code, | 9813 Handle<Code> code, |
9814 Handle<FixedArray> literals, | 9814 Handle<FixedArray> literals, |
9815 BailoutId osr_ast_id) { | 9815 BailoutId osr_ast_id) { |
9816 Isolate* isolate = shared->GetIsolate(); | 9816 Isolate* isolate = shared->GetIsolate(); |
9817 ASSERT(code->kind() == Code::OPTIMIZED_FUNCTION); | 9817 DCHECK(code->kind() == Code::OPTIMIZED_FUNCTION); |
9818 ASSERT(native_context->IsNativeContext()); | 9818 DCHECK(native_context->IsNativeContext()); |
9819 STATIC_ASSERT(kEntryLength == 4); | 9819 STATIC_ASSERT(kEntryLength == 4); |
9820 Handle<FixedArray> new_code_map; | 9820 Handle<FixedArray> new_code_map; |
9821 Handle<Object> value(shared->optimized_code_map(), isolate); | 9821 Handle<Object> value(shared->optimized_code_map(), isolate); |
9822 int old_length; | 9822 int old_length; |
9823 if (value->IsSmi()) { | 9823 if (value->IsSmi()) { |
9824 // No optimized code map. | 9824 // No optimized code map. |
9825 ASSERT_EQ(0, Smi::cast(*value)->value()); | 9825 DCHECK_EQ(0, Smi::cast(*value)->value()); |
9826 // Create 3 entries per context {context, code, literals}. | 9826 // Create 3 entries per context {context, code, literals}. |
9827 new_code_map = isolate->factory()->NewFixedArray(kInitialLength); | 9827 new_code_map = isolate->factory()->NewFixedArray(kInitialLength); |
9828 old_length = kEntriesStart; | 9828 old_length = kEntriesStart; |
9829 } else { | 9829 } else { |
9830 // Copy old map and append one new entry. | 9830 // Copy old map and append one new entry. |
9831 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value); | 9831 Handle<FixedArray> old_code_map = Handle<FixedArray>::cast(value); |
9832 ASSERT_EQ(-1, shared->SearchOptimizedCodeMap(*native_context, osr_ast_id)); | 9832 DCHECK_EQ(-1, shared->SearchOptimizedCodeMap(*native_context, osr_ast_id)); |
9833 old_length = old_code_map->length(); | 9833 old_length = old_code_map->length(); |
9834 new_code_map = FixedArray::CopySize( | 9834 new_code_map = FixedArray::CopySize( |
9835 old_code_map, old_length + kEntryLength); | 9835 old_code_map, old_length + kEntryLength); |
9836 // Zap the old map for the sake of the heap verifier. | 9836 // Zap the old map for the sake of the heap verifier. |
9837 if (Heap::ShouldZapGarbage()) { | 9837 if (Heap::ShouldZapGarbage()) { |
9838 Object** data = old_code_map->data_start(); | 9838 Object** data = old_code_map->data_start(); |
9839 MemsetPointer(data, isolate->heap()->the_hole_value(), old_length); | 9839 MemsetPointer(data, isolate->heap()->the_hole_value(), old_length); |
9840 } | 9840 } |
9841 } | 9841 } |
9842 new_code_map->set(old_length + kContextOffset, *native_context); | 9842 new_code_map->set(old_length + kContextOffset, *native_context); |
9843 new_code_map->set(old_length + kCachedCodeOffset, *code); | 9843 new_code_map->set(old_length + kCachedCodeOffset, *code); |
9844 new_code_map->set(old_length + kLiteralsOffset, *literals); | 9844 new_code_map->set(old_length + kLiteralsOffset, *literals); |
9845 new_code_map->set(old_length + kOsrAstIdOffset, | 9845 new_code_map->set(old_length + kOsrAstIdOffset, |
9846 Smi::FromInt(osr_ast_id.ToInt())); | 9846 Smi::FromInt(osr_ast_id.ToInt())); |
9847 | 9847 |
9848 #ifdef DEBUG | 9848 #ifdef DEBUG |
9849 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { | 9849 for (int i = kEntriesStart; i < new_code_map->length(); i += kEntryLength) { |
9850 ASSERT(new_code_map->get(i + kContextOffset)->IsNativeContext()); | 9850 DCHECK(new_code_map->get(i + kContextOffset)->IsNativeContext()); |
9851 ASSERT(new_code_map->get(i + kCachedCodeOffset)->IsCode()); | 9851 DCHECK(new_code_map->get(i + kCachedCodeOffset)->IsCode()); |
9852 ASSERT(Code::cast(new_code_map->get(i + kCachedCodeOffset))->kind() == | 9852 DCHECK(Code::cast(new_code_map->get(i + kCachedCodeOffset))->kind() == |
9853 Code::OPTIMIZED_FUNCTION); | 9853 Code::OPTIMIZED_FUNCTION); |
9854 ASSERT(new_code_map->get(i + kLiteralsOffset)->IsFixedArray()); | 9854 DCHECK(new_code_map->get(i + kLiteralsOffset)->IsFixedArray()); |
9855 ASSERT(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); | 9855 DCHECK(new_code_map->get(i + kOsrAstIdOffset)->IsSmi()); |
9856 } | 9856 } |
9857 #endif | 9857 #endif |
9858 shared->set_optimized_code_map(*new_code_map); | 9858 shared->set_optimized_code_map(*new_code_map); |
9859 } | 9859 } |
9860 | 9860 |
9861 | 9861 |
9862 FixedArray* SharedFunctionInfo::GetLiteralsFromOptimizedCodeMap(int index) { | 9862 FixedArray* SharedFunctionInfo::GetLiteralsFromOptimizedCodeMap(int index) { |
9863 ASSERT(index > kEntriesStart); | 9863 DCHECK(index > kEntriesStart); |
9864 FixedArray* code_map = FixedArray::cast(optimized_code_map()); | 9864 FixedArray* code_map = FixedArray::cast(optimized_code_map()); |
9865 if (!bound()) { | 9865 if (!bound()) { |
9866 FixedArray* cached_literals = FixedArray::cast(code_map->get(index + 1)); | 9866 FixedArray* cached_literals = FixedArray::cast(code_map->get(index + 1)); |
9867 ASSERT_NE(NULL, cached_literals); | 9867 DCHECK_NE(NULL, cached_literals); |
9868 return cached_literals; | 9868 return cached_literals; |
9869 } | 9869 } |
9870 return NULL; | 9870 return NULL; |
9871 } | 9871 } |
9872 | 9872 |
9873 | 9873 |
9874 Code* SharedFunctionInfo::GetCodeFromOptimizedCodeMap(int index) { | 9874 Code* SharedFunctionInfo::GetCodeFromOptimizedCodeMap(int index) { |
9875 ASSERT(index > kEntriesStart); | 9875 DCHECK(index > kEntriesStart); |
9876 FixedArray* code_map = FixedArray::cast(optimized_code_map()); | 9876 FixedArray* code_map = FixedArray::cast(optimized_code_map()); |
9877 Code* code = Code::cast(code_map->get(index)); | 9877 Code* code = Code::cast(code_map->get(index)); |
9878 ASSERT_NE(NULL, code); | 9878 DCHECK_NE(NULL, code); |
9879 return code; | 9879 return code; |
9880 } | 9880 } |
9881 | 9881 |
9882 | 9882 |
9883 void SharedFunctionInfo::ClearOptimizedCodeMap() { | 9883 void SharedFunctionInfo::ClearOptimizedCodeMap() { |
9884 FixedArray* code_map = FixedArray::cast(optimized_code_map()); | 9884 FixedArray* code_map = FixedArray::cast(optimized_code_map()); |
9885 | 9885 |
9886 // If the next map link slot is already used then the function was | 9886 // If the next map link slot is already used then the function was |
9887 // enqueued with code flushing and we remove it now. | 9887 // enqueued with code flushing and we remove it now. |
9888 if (!code_map->get(kNextMapIndex)->IsUndefined()) { | 9888 if (!code_map->get(kNextMapIndex)->IsUndefined()) { |
9889 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher(); | 9889 CodeFlusher* flusher = GetHeap()->mark_compact_collector()->code_flusher(); |
9890 flusher->EvictOptimizedCodeMap(this); | 9890 flusher->EvictOptimizedCodeMap(this); |
9891 } | 9891 } |
9892 | 9892 |
9893 ASSERT(code_map->get(kNextMapIndex)->IsUndefined()); | 9893 DCHECK(code_map->get(kNextMapIndex)->IsUndefined()); |
9894 set_optimized_code_map(Smi::FromInt(0)); | 9894 set_optimized_code_map(Smi::FromInt(0)); |
9895 } | 9895 } |
9896 | 9896 |
9897 | 9897 |
9898 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, | 9898 void SharedFunctionInfo::EvictFromOptimizedCodeMap(Code* optimized_code, |
9899 const char* reason) { | 9899 const char* reason) { |
9900 DisallowHeapAllocation no_gc; | 9900 DisallowHeapAllocation no_gc; |
9901 if (optimized_code_map()->IsSmi()) return; | 9901 if (optimized_code_map()->IsSmi()) return; |
9902 | 9902 |
9903 FixedArray* code_map = FixedArray::cast(optimized_code_map()); | 9903 FixedArray* code_map = FixedArray::cast(optimized_code_map()); |
9904 int dst = kEntriesStart; | 9904 int dst = kEntriesStart; |
9905 int length = code_map->length(); | 9905 int length = code_map->length(); |
9906 for (int src = kEntriesStart; src < length; src += kEntryLength) { | 9906 for (int src = kEntriesStart; src < length; src += kEntryLength) { |
9907 ASSERT(code_map->get(src)->IsNativeContext()); | 9907 DCHECK(code_map->get(src)->IsNativeContext()); |
9908 if (Code::cast(code_map->get(src + kCachedCodeOffset)) == optimized_code) { | 9908 if (Code::cast(code_map->get(src + kCachedCodeOffset)) == optimized_code) { |
9909 // Evict the src entry by not copying it to the dst entry. | 9909 // Evict the src entry by not copying it to the dst entry. |
9910 if (FLAG_trace_opt) { | 9910 if (FLAG_trace_opt) { |
9911 PrintF("[evicting entry from optimizing code map (%s) for ", reason); | 9911 PrintF("[evicting entry from optimizing code map (%s) for ", reason); |
9912 ShortPrint(); | 9912 ShortPrint(); |
9913 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value()); | 9913 BailoutId osr(Smi::cast(code_map->get(src + kOsrAstIdOffset))->value()); |
9914 if (osr.IsNone()) { | 9914 if (osr.IsNone()) { |
9915 PrintF("]\n"); | 9915 PrintF("]\n"); |
9916 } else { | 9916 } else { |
9917 PrintF(" (osr ast id %d)]\n", osr.ToInt()); | 9917 PrintF(" (osr ast id %d)]\n", osr.ToInt()); |
(...skipping 17 matching lines...) Expand all Loading... |
9935 if (dst != length) { | 9935 if (dst != length) { |
9936 // Always trim even when array is cleared because of heap verifier. | 9936 // Always trim even when array is cleared because of heap verifier. |
9937 RightTrimFixedArray<Heap::FROM_MUTATOR>(GetHeap(), code_map, length - dst); | 9937 RightTrimFixedArray<Heap::FROM_MUTATOR>(GetHeap(), code_map, length - dst); |
9938 if (code_map->length() == kEntriesStart) ClearOptimizedCodeMap(); | 9938 if (code_map->length() == kEntriesStart) ClearOptimizedCodeMap(); |
9939 } | 9939 } |
9940 } | 9940 } |
9941 | 9941 |
9942 | 9942 |
9943 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { | 9943 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { |
9944 FixedArray* code_map = FixedArray::cast(optimized_code_map()); | 9944 FixedArray* code_map = FixedArray::cast(optimized_code_map()); |
9945 ASSERT(shrink_by % kEntryLength == 0); | 9945 DCHECK(shrink_by % kEntryLength == 0); |
9946 ASSERT(shrink_by <= code_map->length() - kEntriesStart); | 9946 DCHECK(shrink_by <= code_map->length() - kEntriesStart); |
9947 // Always trim even when array is cleared because of heap verifier. | 9947 // Always trim even when array is cleared because of heap verifier. |
9948 RightTrimFixedArray<Heap::FROM_GC>(GetHeap(), code_map, shrink_by); | 9948 RightTrimFixedArray<Heap::FROM_GC>(GetHeap(), code_map, shrink_by); |
9949 if (code_map->length() == kEntriesStart) { | 9949 if (code_map->length() == kEntriesStart) { |
9950 ClearOptimizedCodeMap(); | 9950 ClearOptimizedCodeMap(); |
9951 } | 9951 } |
9952 } | 9952 } |
9953 | 9953 |
9954 | 9954 |
9955 void JSObject::OptimizeAsPrototype(Handle<JSObject> object) { | 9955 void JSObject::OptimizeAsPrototype(Handle<JSObject> object) { |
9956 if (object->IsGlobalObject()) return; | 9956 if (object->IsGlobalObject()) return; |
9957 | 9957 |
9958 // Make sure prototypes are fast objects and their maps have the bit set | 9958 // Make sure prototypes are fast objects and their maps have the bit set |
9959 // so they remain fast. | 9959 // so they remain fast. |
9960 if (!object->HasFastProperties()) { | 9960 if (!object->HasFastProperties()) { |
9961 MigrateSlowToFast(object, 0); | 9961 MigrateSlowToFast(object, 0); |
9962 } | 9962 } |
9963 } | 9963 } |
9964 | 9964 |
9965 | 9965 |
9966 Handle<Object> CacheInitialJSArrayMaps( | 9966 Handle<Object> CacheInitialJSArrayMaps( |
9967 Handle<Context> native_context, Handle<Map> initial_map) { | 9967 Handle<Context> native_context, Handle<Map> initial_map) { |
9968 // Replace all of the cached initial array maps in the native context with | 9968 // Replace all of the cached initial array maps in the native context with |
9969 // the appropriate transitioned elements kind maps. | 9969 // the appropriate transitioned elements kind maps. |
9970 Factory* factory = native_context->GetIsolate()->factory(); | 9970 Factory* factory = native_context->GetIsolate()->factory(); |
9971 Handle<FixedArray> maps = factory->NewFixedArrayWithHoles( | 9971 Handle<FixedArray> maps = factory->NewFixedArrayWithHoles( |
9972 kElementsKindCount, TENURED); | 9972 kElementsKindCount, TENURED); |
9973 | 9973 |
9974 Handle<Map> current_map = initial_map; | 9974 Handle<Map> current_map = initial_map; |
9975 ElementsKind kind = current_map->elements_kind(); | 9975 ElementsKind kind = current_map->elements_kind(); |
9976 ASSERT(kind == GetInitialFastElementsKind()); | 9976 DCHECK(kind == GetInitialFastElementsKind()); |
9977 maps->set(kind, *current_map); | 9977 maps->set(kind, *current_map); |
9978 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; | 9978 for (int i = GetSequenceIndexFromFastElementsKind(kind) + 1; |
9979 i < kFastElementsKindCount; ++i) { | 9979 i < kFastElementsKindCount; ++i) { |
9980 Handle<Map> new_map; | 9980 Handle<Map> new_map; |
9981 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); | 9981 ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(i); |
9982 if (current_map->HasElementsTransition()) { | 9982 if (current_map->HasElementsTransition()) { |
9983 new_map = handle(current_map->elements_transition_map()); | 9983 new_map = handle(current_map->elements_transition_map()); |
9984 ASSERT(new_map->elements_kind() == next_kind); | 9984 DCHECK(new_map->elements_kind() == next_kind); |
9985 } else { | 9985 } else { |
9986 new_map = Map::CopyAsElementsKind( | 9986 new_map = Map::CopyAsElementsKind( |
9987 current_map, next_kind, INSERT_TRANSITION); | 9987 current_map, next_kind, INSERT_TRANSITION); |
9988 } | 9988 } |
9989 maps->set(next_kind, *new_map); | 9989 maps->set(next_kind, *new_map); |
9990 current_map = new_map; | 9990 current_map = new_map; |
9991 } | 9991 } |
9992 native_context->set_js_array_maps(*maps); | 9992 native_context->set_js_array_maps(*maps); |
9993 return initial_map; | 9993 return initial_map; |
9994 } | 9994 } |
9995 | 9995 |
9996 | 9996 |
9997 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, | 9997 void JSFunction::SetInstancePrototype(Handle<JSFunction> function, |
9998 Handle<Object> value) { | 9998 Handle<Object> value) { |
9999 Isolate* isolate = function->GetIsolate(); | 9999 Isolate* isolate = function->GetIsolate(); |
10000 | 10000 |
10001 ASSERT(value->IsJSReceiver()); | 10001 DCHECK(value->IsJSReceiver()); |
10002 | 10002 |
10003 // First some logic for the map of the prototype to make sure it is in fast | 10003 // First some logic for the map of the prototype to make sure it is in fast |
10004 // mode. | 10004 // mode. |
10005 if (value->IsJSObject()) { | 10005 if (value->IsJSObject()) { |
10006 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); | 10006 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); |
10007 } | 10007 } |
10008 | 10008 |
10009 // Now some logic for the maps of the objects that are created by using this | 10009 // Now some logic for the maps of the objects that are created by using this |
10010 // function as a constructor. | 10010 // function as a constructor. |
10011 if (function->has_initial_map()) { | 10011 if (function->has_initial_map()) { |
(...skipping 27 matching lines...) Expand all Loading... |
10039 // needed. At that point, a new initial map is created and the | 10039 // needed. At that point, a new initial map is created and the |
10040 // prototype is put into the initial map where it belongs. | 10040 // prototype is put into the initial map where it belongs. |
10041 function->set_prototype_or_initial_map(*value); | 10041 function->set_prototype_or_initial_map(*value); |
10042 } | 10042 } |
10043 isolate->heap()->ClearInstanceofCache(); | 10043 isolate->heap()->ClearInstanceofCache(); |
10044 } | 10044 } |
10045 | 10045 |
10046 | 10046 |
10047 void JSFunction::SetPrototype(Handle<JSFunction> function, | 10047 void JSFunction::SetPrototype(Handle<JSFunction> function, |
10048 Handle<Object> value) { | 10048 Handle<Object> value) { |
10049 ASSERT(function->should_have_prototype()); | 10049 DCHECK(function->should_have_prototype()); |
10050 Handle<Object> construct_prototype = value; | 10050 Handle<Object> construct_prototype = value; |
10051 | 10051 |
10052 // If the value is not a JSReceiver, store the value in the map's | 10052 // If the value is not a JSReceiver, store the value in the map's |
10053 // constructor field so it can be accessed. Also, set the prototype | 10053 // constructor field so it can be accessed. Also, set the prototype |
10054 // used for constructing objects to the original object prototype. | 10054 // used for constructing objects to the original object prototype. |
10055 // See ECMA-262 13.2.2. | 10055 // See ECMA-262 13.2.2. |
10056 if (!value->IsJSReceiver()) { | 10056 if (!value->IsJSReceiver()) { |
10057 // Copy the map so this does not affect unrelated functions. | 10057 // Copy the map so this does not affect unrelated functions. |
10058 // Remove map transitions because they point to maps with a | 10058 // Remove map transitions because they point to maps with a |
10059 // different prototype. | 10059 // different prototype. |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10128 } | 10128 } |
10129 JSObject::OptimizeAsPrototype( | 10129 JSObject::OptimizeAsPrototype( |
10130 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); | 10130 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter))); |
10131 } | 10131 } |
10132 } else { | 10132 } else { |
10133 prototype = isolate->factory()->NewFunctionPrototype(function); | 10133 prototype = isolate->factory()->NewFunctionPrototype(function); |
10134 } | 10134 } |
10135 map->set_inobject_properties(in_object_properties); | 10135 map->set_inobject_properties(in_object_properties); |
10136 map->set_unused_property_fields(in_object_properties); | 10136 map->set_unused_property_fields(in_object_properties); |
10137 map->set_prototype(*prototype); | 10137 map->set_prototype(*prototype); |
10138 ASSERT(map->has_fast_object_elements()); | 10138 DCHECK(map->has_fast_object_elements()); |
10139 | 10139 |
10140 // Finally link initial map and constructor function. | 10140 // Finally link initial map and constructor function. |
10141 function->set_initial_map(*map); | 10141 function->set_initial_map(*map); |
10142 map->set_constructor(*function); | 10142 map->set_constructor(*function); |
10143 | 10143 |
10144 if (!function->shared()->is_generator()) { | 10144 if (!function->shared()->is_generator()) { |
10145 function->StartInobjectSlackTracking(); | 10145 function->StartInobjectSlackTracking(); |
10146 } | 10146 } |
10147 } | 10147 } |
10148 | 10148 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10212 oddball->set_kind(kind); | 10212 oddball->set_kind(kind); |
10213 } | 10213 } |
10214 | 10214 |
10215 | 10215 |
10216 void Script::InitLineEnds(Handle<Script> script) { | 10216 void Script::InitLineEnds(Handle<Script> script) { |
10217 if (!script->line_ends()->IsUndefined()) return; | 10217 if (!script->line_ends()->IsUndefined()) return; |
10218 | 10218 |
10219 Isolate* isolate = script->GetIsolate(); | 10219 Isolate* isolate = script->GetIsolate(); |
10220 | 10220 |
10221 if (!script->source()->IsString()) { | 10221 if (!script->source()->IsString()) { |
10222 ASSERT(script->source()->IsUndefined()); | 10222 DCHECK(script->source()->IsUndefined()); |
10223 Handle<FixedArray> empty = isolate->factory()->NewFixedArray(0); | 10223 Handle<FixedArray> empty = isolate->factory()->NewFixedArray(0); |
10224 script->set_line_ends(*empty); | 10224 script->set_line_ends(*empty); |
10225 ASSERT(script->line_ends()->IsFixedArray()); | 10225 DCHECK(script->line_ends()->IsFixedArray()); |
10226 return; | 10226 return; |
10227 } | 10227 } |
10228 | 10228 |
10229 Handle<String> src(String::cast(script->source()), isolate); | 10229 Handle<String> src(String::cast(script->source()), isolate); |
10230 | 10230 |
10231 Handle<FixedArray> array = String::CalculateLineEnds(src, true); | 10231 Handle<FixedArray> array = String::CalculateLineEnds(src, true); |
10232 | 10232 |
10233 if (*array != isolate->heap()->empty_fixed_array()) { | 10233 if (*array != isolate->heap()->empty_fixed_array()) { |
10234 array->set_map(isolate->heap()->fixed_cow_array_map()); | 10234 array->set_map(isolate->heap()->fixed_cow_array_map()); |
10235 } | 10235 } |
10236 | 10236 |
10237 script->set_line_ends(*array); | 10237 script->set_line_ends(*array); |
10238 ASSERT(script->line_ends()->IsFixedArray()); | 10238 DCHECK(script->line_ends()->IsFixedArray()); |
10239 } | 10239 } |
10240 | 10240 |
10241 | 10241 |
10242 int Script::GetColumnNumber(Handle<Script> script, int code_pos) { | 10242 int Script::GetColumnNumber(Handle<Script> script, int code_pos) { |
10243 int line_number = GetLineNumber(script, code_pos); | 10243 int line_number = GetLineNumber(script, code_pos); |
10244 if (line_number == -1) return -1; | 10244 if (line_number == -1) return -1; |
10245 | 10245 |
10246 DisallowHeapAllocation no_allocation; | 10246 DisallowHeapAllocation no_allocation; |
10247 FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); | 10247 FixedArray* line_ends_array = FixedArray::cast(script->line_ends()); |
10248 line_number = line_number - script->line_offset()->value(); | 10248 line_number = line_number - script->line_offset()->value(); |
10249 if (line_number == 0) return code_pos + script->column_offset()->value(); | 10249 if (line_number == 0) return code_pos + script->column_offset()->value(); |
10250 int prev_line_end_pos = | 10250 int prev_line_end_pos = |
10251 Smi::cast(line_ends_array->get(line_number - 1))->value(); | 10251 Smi::cast(line_ends_array->get(line_number - 1))->value(); |
10252 return code_pos - (prev_line_end_pos + 1); | 10252 return code_pos - (prev_line_end_pos + 1); |
10253 } | 10253 } |
10254 | 10254 |
10255 | 10255 |
10256 int Script::GetLineNumberWithArray(int code_pos) { | 10256 int Script::GetLineNumberWithArray(int code_pos) { |
10257 DisallowHeapAllocation no_allocation; | 10257 DisallowHeapAllocation no_allocation; |
10258 ASSERT(line_ends()->IsFixedArray()); | 10258 DCHECK(line_ends()->IsFixedArray()); |
10259 FixedArray* line_ends_array = FixedArray::cast(line_ends()); | 10259 FixedArray* line_ends_array = FixedArray::cast(line_ends()); |
10260 int line_ends_len = line_ends_array->length(); | 10260 int line_ends_len = line_ends_array->length(); |
10261 if (line_ends_len == 0) return -1; | 10261 if (line_ends_len == 0) return -1; |
10262 | 10262 |
10263 if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) { | 10263 if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) { |
10264 return line_offset()->value(); | 10264 return line_offset()->value(); |
10265 } | 10265 } |
10266 | 10266 |
10267 int left = 0; | 10267 int left = 0; |
10268 int right = line_ends_len; | 10268 int right = line_ends_len; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10302 | 10302 |
10303 | 10303 |
10304 Handle<Object> Script::GetNameOrSourceURL(Handle<Script> script) { | 10304 Handle<Object> Script::GetNameOrSourceURL(Handle<Script> script) { |
10305 Isolate* isolate = script->GetIsolate(); | 10305 Isolate* isolate = script->GetIsolate(); |
10306 Handle<String> name_or_source_url_key = | 10306 Handle<String> name_or_source_url_key = |
10307 isolate->factory()->InternalizeOneByteString( | 10307 isolate->factory()->InternalizeOneByteString( |
10308 STATIC_ASCII_VECTOR("nameOrSourceURL")); | 10308 STATIC_ASCII_VECTOR("nameOrSourceURL")); |
10309 Handle<JSObject> script_wrapper = Script::GetWrapper(script); | 10309 Handle<JSObject> script_wrapper = Script::GetWrapper(script); |
10310 Handle<Object> property = Object::GetProperty( | 10310 Handle<Object> property = Object::GetProperty( |
10311 script_wrapper, name_or_source_url_key).ToHandleChecked(); | 10311 script_wrapper, name_or_source_url_key).ToHandleChecked(); |
10312 ASSERT(property->IsJSFunction()); | 10312 DCHECK(property->IsJSFunction()); |
10313 Handle<JSFunction> method = Handle<JSFunction>::cast(property); | 10313 Handle<JSFunction> method = Handle<JSFunction>::cast(property); |
10314 Handle<Object> result; | 10314 Handle<Object> result; |
10315 // Do not check against pending exception, since this function may be called | 10315 // Do not check against pending exception, since this function may be called |
10316 // when an exception has already been pending. | 10316 // when an exception has already been pending. |
10317 if (!Execution::TryCall(method, script_wrapper, 0, NULL).ToHandle(&result)) { | 10317 if (!Execution::TryCall(method, script_wrapper, 0, NULL).ToHandle(&result)) { |
10318 return isolate->factory()->undefined_value(); | 10318 return isolate->factory()->undefined_value(); |
10319 } | 10319 } |
10320 return result; | 10320 return result; |
10321 } | 10321 } |
10322 | 10322 |
10323 | 10323 |
10324 // Wrappers for scripts are kept alive and cached in weak global | 10324 // Wrappers for scripts are kept alive and cached in weak global |
10325 // handles referred from foreign objects held by the scripts as long as | 10325 // handles referred from foreign objects held by the scripts as long as |
10326 // they are used. When they are not used anymore, the garbage | 10326 // they are used. When they are not used anymore, the garbage |
10327 // collector will call the weak callback on the global handle | 10327 // collector will call the weak callback on the global handle |
10328 // associated with the wrapper and get rid of both the wrapper and the | 10328 // associated with the wrapper and get rid of both the wrapper and the |
10329 // handle. | 10329 // handle. |
10330 static void ClearWrapperCacheWeakCallback( | 10330 static void ClearWrapperCacheWeakCallback( |
10331 const v8::WeakCallbackData<v8::Value, void>& data) { | 10331 const v8::WeakCallbackData<v8::Value, void>& data) { |
10332 Object** location = reinterpret_cast<Object**>(data.GetParameter()); | 10332 Object** location = reinterpret_cast<Object**>(data.GetParameter()); |
10333 JSValue* wrapper = JSValue::cast(*location); | 10333 JSValue* wrapper = JSValue::cast(*location); |
10334 Script::cast(wrapper->value())->ClearWrapperCache(); | 10334 Script::cast(wrapper->value())->ClearWrapperCache(); |
10335 } | 10335 } |
10336 | 10336 |
10337 | 10337 |
10338 void Script::ClearWrapperCache() { | 10338 void Script::ClearWrapperCache() { |
10339 Foreign* foreign = wrapper(); | 10339 Foreign* foreign = wrapper(); |
10340 Object** location = reinterpret_cast<Object**>(foreign->foreign_address()); | 10340 Object** location = reinterpret_cast<Object**>(foreign->foreign_address()); |
10341 ASSERT_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location)); | 10341 DCHECK_EQ(foreign->foreign_address(), reinterpret_cast<Address>(location)); |
10342 foreign->set_foreign_address(0); | 10342 foreign->set_foreign_address(0); |
10343 GlobalHandles::Destroy(location); | 10343 GlobalHandles::Destroy(location); |
10344 GetIsolate()->counters()->script_wrappers()->Decrement(); | 10344 GetIsolate()->counters()->script_wrappers()->Decrement(); |
10345 } | 10345 } |
10346 | 10346 |
10347 | 10347 |
10348 Handle<JSObject> Script::GetWrapper(Handle<Script> script) { | 10348 Handle<JSObject> Script::GetWrapper(Handle<Script> script) { |
10349 if (script->wrapper()->foreign_address() != NULL) { | 10349 if (script->wrapper()->foreign_address() != NULL) { |
10350 // Return a handle for the existing script wrapper from the cache. | 10350 // Return a handle for the existing script wrapper from the cache. |
10351 return Handle<JSValue>( | 10351 return Handle<JSValue>( |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10466 int length = code_relocation->length(); | 10466 int length = code_relocation->length(); |
10467 if (length != recompiled_relocation->length()) return false; | 10467 if (length != recompiled_relocation->length()) return false; |
10468 int compare = memcmp(code_relocation->GetDataStartAddress(), | 10468 int compare = memcmp(code_relocation->GetDataStartAddress(), |
10469 recompiled_relocation->GetDataStartAddress(), | 10469 recompiled_relocation->GetDataStartAddress(), |
10470 length); | 10470 length); |
10471 return compare == 0; | 10471 return compare == 0; |
10472 } | 10472 } |
10473 | 10473 |
10474 | 10474 |
10475 void SharedFunctionInfo::EnableDeoptimizationSupport(Code* recompiled) { | 10475 void SharedFunctionInfo::EnableDeoptimizationSupport(Code* recompiled) { |
10476 ASSERT(!has_deoptimization_support()); | 10476 DCHECK(!has_deoptimization_support()); |
10477 DisallowHeapAllocation no_allocation; | 10477 DisallowHeapAllocation no_allocation; |
10478 Code* code = this->code(); | 10478 Code* code = this->code(); |
10479 if (IsCodeEquivalent(code, recompiled)) { | 10479 if (IsCodeEquivalent(code, recompiled)) { |
10480 // Copy the deoptimization data from the recompiled code. | 10480 // Copy the deoptimization data from the recompiled code. |
10481 code->set_deoptimization_data(recompiled->deoptimization_data()); | 10481 code->set_deoptimization_data(recompiled->deoptimization_data()); |
10482 code->set_has_deoptimization_support(true); | 10482 code->set_has_deoptimization_support(true); |
10483 } else { | 10483 } else { |
10484 // TODO(3025757): In case the recompiled isn't equivalent to the | 10484 // TODO(3025757): In case the recompiled isn't equivalent to the |
10485 // old code, we have to replace it. We should try to avoid this | 10485 // old code, we have to replace it. We should try to avoid this |
10486 // altogether because it flushes valuable type feedback by | 10486 // altogether because it flushes valuable type feedback by |
10487 // effectively resetting all IC state. | 10487 // effectively resetting all IC state. |
10488 ReplaceCode(recompiled); | 10488 ReplaceCode(recompiled); |
10489 } | 10489 } |
10490 ASSERT(has_deoptimization_support()); | 10490 DCHECK(has_deoptimization_support()); |
10491 } | 10491 } |
10492 | 10492 |
10493 | 10493 |
10494 void SharedFunctionInfo::DisableOptimization(BailoutReason reason) { | 10494 void SharedFunctionInfo::DisableOptimization(BailoutReason reason) { |
10495 // Disable optimization for the shared function info and mark the | 10495 // Disable optimization for the shared function info and mark the |
10496 // code as non-optimizable. The marker on the shared function info | 10496 // code as non-optimizable. The marker on the shared function info |
10497 // is there because we flush non-optimized code thereby loosing the | 10497 // is there because we flush non-optimized code thereby loosing the |
10498 // non-optimizable information for the code. When the code is | 10498 // non-optimizable information for the code. When the code is |
10499 // regenerated and set on the shared function info it is marked as | 10499 // regenerated and set on the shared function info it is marked as |
10500 // non-optimizable if optimization is disabled for the shared | 10500 // non-optimizable if optimization is disabled for the shared |
10501 // function info. | 10501 // function info. |
10502 set_optimization_disabled(true); | 10502 set_optimization_disabled(true); |
10503 set_bailout_reason(reason); | 10503 set_bailout_reason(reason); |
10504 // Code should be the lazy compilation stub or else unoptimized. If the | 10504 // Code should be the lazy compilation stub or else unoptimized. If the |
10505 // latter, disable optimization for the code too. | 10505 // latter, disable optimization for the code too. |
10506 ASSERT(code()->kind() == Code::FUNCTION || code()->kind() == Code::BUILTIN); | 10506 DCHECK(code()->kind() == Code::FUNCTION || code()->kind() == Code::BUILTIN); |
10507 if (code()->kind() == Code::FUNCTION) { | 10507 if (code()->kind() == Code::FUNCTION) { |
10508 code()->set_optimizable(false); | 10508 code()->set_optimizable(false); |
10509 } | 10509 } |
10510 PROFILE(GetIsolate(), CodeDisableOptEvent(code(), this)); | 10510 PROFILE(GetIsolate(), CodeDisableOptEvent(code(), this)); |
10511 if (FLAG_trace_opt) { | 10511 if (FLAG_trace_opt) { |
10512 PrintF("[disabled optimization for "); | 10512 PrintF("[disabled optimization for "); |
10513 ShortPrint(); | 10513 ShortPrint(); |
10514 PrintF(", reason: %s]\n", GetBailoutReason(reason)); | 10514 PrintF(", reason: %s]\n", GetBailoutReason(reason)); |
10515 } | 10515 } |
10516 } | 10516 } |
10517 | 10517 |
10518 | 10518 |
10519 bool SharedFunctionInfo::VerifyBailoutId(BailoutId id) { | 10519 bool SharedFunctionInfo::VerifyBailoutId(BailoutId id) { |
10520 ASSERT(!id.IsNone()); | 10520 DCHECK(!id.IsNone()); |
10521 Code* unoptimized = code(); | 10521 Code* unoptimized = code(); |
10522 DeoptimizationOutputData* data = | 10522 DeoptimizationOutputData* data = |
10523 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); | 10523 DeoptimizationOutputData::cast(unoptimized->deoptimization_data()); |
10524 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); | 10524 unsigned ignore = Deoptimizer::GetOutputInfo(data, id, this); |
10525 USE(ignore); | 10525 USE(ignore); |
10526 return true; // Return true if there was no ASSERT. | 10526 return true; // Return true if there was no DCHECK. |
10527 } | 10527 } |
10528 | 10528 |
10529 | 10529 |
10530 void JSFunction::StartInobjectSlackTracking() { | 10530 void JSFunction::StartInobjectSlackTracking() { |
10531 ASSERT(has_initial_map() && !IsInobjectSlackTrackingInProgress()); | 10531 DCHECK(has_initial_map() && !IsInobjectSlackTrackingInProgress()); |
10532 | 10532 |
10533 if (!FLAG_clever_optimizations) return; | 10533 if (!FLAG_clever_optimizations) return; |
10534 Map* map = initial_map(); | 10534 Map* map = initial_map(); |
10535 | 10535 |
10536 // Only initiate the tracking the first time. | 10536 // Only initiate the tracking the first time. |
10537 if (map->done_inobject_slack_tracking()) return; | 10537 if (map->done_inobject_slack_tracking()) return; |
10538 map->set_done_inobject_slack_tracking(true); | 10538 map->set_done_inobject_slack_tracking(true); |
10539 | 10539 |
10540 // No tracking during the snapshot construction phase. | 10540 // No tracking during the snapshot construction phase. |
10541 Isolate* isolate = GetIsolate(); | 10541 Isolate* isolate = GetIsolate(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10580 map->set_inobject_properties(map->inobject_properties() - slack); | 10580 map->set_inobject_properties(map->inobject_properties() - slack); |
10581 map->set_unused_property_fields(map->unused_property_fields() - slack); | 10581 map->set_unused_property_fields(map->unused_property_fields() - slack); |
10582 map->set_instance_size(map->instance_size() - slack * kPointerSize); | 10582 map->set_instance_size(map->instance_size() - slack * kPointerSize); |
10583 | 10583 |
10584 // Visitor id might depend on the instance size, recalculate it. | 10584 // Visitor id might depend on the instance size, recalculate it. |
10585 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); | 10585 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); |
10586 } | 10586 } |
10587 | 10587 |
10588 | 10588 |
10589 void JSFunction::CompleteInobjectSlackTracking() { | 10589 void JSFunction::CompleteInobjectSlackTracking() { |
10590 ASSERT(has_initial_map()); | 10590 DCHECK(has_initial_map()); |
10591 Map* map = initial_map(); | 10591 Map* map = initial_map(); |
10592 | 10592 |
10593 ASSERT(map->done_inobject_slack_tracking()); | 10593 DCHECK(map->done_inobject_slack_tracking()); |
10594 map->set_construction_count(kNoSlackTracking); | 10594 map->set_construction_count(kNoSlackTracking); |
10595 | 10595 |
10596 int slack = map->unused_property_fields(); | 10596 int slack = map->unused_property_fields(); |
10597 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); | 10597 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); |
10598 if (slack != 0) { | 10598 if (slack != 0) { |
10599 // Resize the initial map and all maps in its transition tree. | 10599 // Resize the initial map and all maps in its transition tree. |
10600 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); | 10600 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); |
10601 } | 10601 } |
10602 } | 10602 } |
10603 | 10603 |
10604 | 10604 |
10605 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context, | 10605 int SharedFunctionInfo::SearchOptimizedCodeMap(Context* native_context, |
10606 BailoutId osr_ast_id) { | 10606 BailoutId osr_ast_id) { |
10607 DisallowHeapAllocation no_gc; | 10607 DisallowHeapAllocation no_gc; |
10608 ASSERT(native_context->IsNativeContext()); | 10608 DCHECK(native_context->IsNativeContext()); |
10609 if (!FLAG_cache_optimized_code) return -1; | 10609 if (!FLAG_cache_optimized_code) return -1; |
10610 Object* value = optimized_code_map(); | 10610 Object* value = optimized_code_map(); |
10611 if (!value->IsSmi()) { | 10611 if (!value->IsSmi()) { |
10612 FixedArray* optimized_code_map = FixedArray::cast(value); | 10612 FixedArray* optimized_code_map = FixedArray::cast(value); |
10613 int length = optimized_code_map->length(); | 10613 int length = optimized_code_map->length(); |
10614 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); | 10614 Smi* osr_ast_id_smi = Smi::FromInt(osr_ast_id.ToInt()); |
10615 for (int i = kEntriesStart; i < length; i += kEntryLength) { | 10615 for (int i = kEntriesStart; i < length; i += kEntryLength) { |
10616 if (optimized_code_map->get(i + kContextOffset) == native_context && | 10616 if (optimized_code_map->get(i + kContextOffset) == native_context && |
10617 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { | 10617 optimized_code_map->get(i + kOsrAstIdOffset) == osr_ast_id_smi) { |
10618 return i + kCachedCodeOffset; | 10618 return i + kCachedCodeOffset; |
(...skipping 19 matching lines...) Expand all Loading... |
10638 | 10638 |
10639 #define DECLARE_TAG(ignore1, ignore2, name) name, | 10639 #define DECLARE_TAG(ignore1, ignore2, name) name, |
10640 const char* const VisitorSynchronization::kTagNames[ | 10640 const char* const VisitorSynchronization::kTagNames[ |
10641 VisitorSynchronization::kNumberOfSyncTags] = { | 10641 VisitorSynchronization::kNumberOfSyncTags] = { |
10642 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) | 10642 VISITOR_SYNCHRONIZATION_TAGS_LIST(DECLARE_TAG) |
10643 }; | 10643 }; |
10644 #undef DECLARE_TAG | 10644 #undef DECLARE_TAG |
10645 | 10645 |
10646 | 10646 |
10647 void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) { | 10647 void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) { |
10648 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 10648 DCHECK(RelocInfo::IsCodeTarget(rinfo->rmode())); |
10649 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 10649 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
10650 Object* old_target = target; | 10650 Object* old_target = target; |
10651 VisitPointer(&target); | 10651 VisitPointer(&target); |
10652 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. | 10652 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
10653 } | 10653 } |
10654 | 10654 |
10655 | 10655 |
10656 void ObjectVisitor::VisitCodeAgeSequence(RelocInfo* rinfo) { | 10656 void ObjectVisitor::VisitCodeAgeSequence(RelocInfo* rinfo) { |
10657 ASSERT(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); | 10657 DCHECK(RelocInfo::IsCodeAgeSequence(rinfo->rmode())); |
10658 Object* stub = rinfo->code_age_stub(); | 10658 Object* stub = rinfo->code_age_stub(); |
10659 if (stub) { | 10659 if (stub) { |
10660 VisitPointer(&stub); | 10660 VisitPointer(&stub); |
10661 } | 10661 } |
10662 } | 10662 } |
10663 | 10663 |
10664 | 10664 |
10665 void ObjectVisitor::VisitCodeEntry(Address entry_address) { | 10665 void ObjectVisitor::VisitCodeEntry(Address entry_address) { |
10666 Object* code = Code::GetObjectFromEntryAddress(entry_address); | 10666 Object* code = Code::GetObjectFromEntryAddress(entry_address); |
10667 Object* old_code = code; | 10667 Object* old_code = code; |
10668 VisitPointer(&code); | 10668 VisitPointer(&code); |
10669 if (code != old_code) { | 10669 if (code != old_code) { |
10670 Memory::Address_at(entry_address) = reinterpret_cast<Code*>(code)->entry(); | 10670 Memory::Address_at(entry_address) = reinterpret_cast<Code*>(code)->entry(); |
10671 } | 10671 } |
10672 } | 10672 } |
10673 | 10673 |
10674 | 10674 |
10675 void ObjectVisitor::VisitCell(RelocInfo* rinfo) { | 10675 void ObjectVisitor::VisitCell(RelocInfo* rinfo) { |
10676 ASSERT(rinfo->rmode() == RelocInfo::CELL); | 10676 DCHECK(rinfo->rmode() == RelocInfo::CELL); |
10677 Object* cell = rinfo->target_cell(); | 10677 Object* cell = rinfo->target_cell(); |
10678 Object* old_cell = cell; | 10678 Object* old_cell = cell; |
10679 VisitPointer(&cell); | 10679 VisitPointer(&cell); |
10680 if (cell != old_cell) { | 10680 if (cell != old_cell) { |
10681 rinfo->set_target_cell(reinterpret_cast<Cell*>(cell)); | 10681 rinfo->set_target_cell(reinterpret_cast<Cell*>(cell)); |
10682 } | 10682 } |
10683 } | 10683 } |
10684 | 10684 |
10685 | 10685 |
10686 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { | 10686 void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { |
10687 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 10687 DCHECK((RelocInfo::IsJSReturn(rinfo->rmode()) && |
10688 rinfo->IsPatchedReturnSequence()) || | 10688 rinfo->IsPatchedReturnSequence()) || |
10689 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 10689 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
10690 rinfo->IsPatchedDebugBreakSlotSequence())); | 10690 rinfo->IsPatchedDebugBreakSlotSequence())); |
10691 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 10691 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
10692 Object* old_target = target; | 10692 Object* old_target = target; |
10693 VisitPointer(&target); | 10693 VisitPointer(&target); |
10694 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. | 10694 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
10695 } | 10695 } |
10696 | 10696 |
10697 | 10697 |
10698 void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) { | 10698 void ObjectVisitor::VisitEmbeddedPointer(RelocInfo* rinfo) { |
10699 ASSERT(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 10699 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
10700 Object* p = rinfo->target_object(); | 10700 Object* p = rinfo->target_object(); |
10701 VisitPointer(&p); | 10701 VisitPointer(&p); |
10702 } | 10702 } |
10703 | 10703 |
10704 | 10704 |
10705 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) { | 10705 void ObjectVisitor::VisitExternalReference(RelocInfo* rinfo) { |
10706 Address p = rinfo->target_reference(); | 10706 Address p = rinfo->target_reference(); |
10707 VisitExternalReference(&p); | 10707 VisitExternalReference(&p); |
10708 } | 10708 } |
10709 | 10709 |
(...skipping 22 matching lines...) Expand all Loading... |
10732 | 10732 |
10733 void Code::Relocate(intptr_t delta) { | 10733 void Code::Relocate(intptr_t delta) { |
10734 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { | 10734 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { |
10735 it.rinfo()->apply(delta, SKIP_ICACHE_FLUSH); | 10735 it.rinfo()->apply(delta, SKIP_ICACHE_FLUSH); |
10736 } | 10736 } |
10737 CpuFeatures::FlushICache(instruction_start(), instruction_size()); | 10737 CpuFeatures::FlushICache(instruction_start(), instruction_size()); |
10738 } | 10738 } |
10739 | 10739 |
10740 | 10740 |
10741 void Code::CopyFrom(const CodeDesc& desc) { | 10741 void Code::CopyFrom(const CodeDesc& desc) { |
10742 ASSERT(Marking::Color(this) == Marking::WHITE_OBJECT); | 10742 DCHECK(Marking::Color(this) == Marking::WHITE_OBJECT); |
10743 | 10743 |
10744 // copy code | 10744 // copy code |
10745 CopyBytes(instruction_start(), desc.buffer, | 10745 CopyBytes(instruction_start(), desc.buffer, |
10746 static_cast<size_t>(desc.instr_size)); | 10746 static_cast<size_t>(desc.instr_size)); |
10747 | 10747 |
10748 // copy reloc info | 10748 // copy reloc info |
10749 CopyBytes(relocation_start(), | 10749 CopyBytes(relocation_start(), |
10750 desc.buffer + desc.buffer_size - desc.reloc_size, | 10750 desc.buffer + desc.buffer_size - desc.reloc_size, |
10751 static_cast<size_t>(desc.reloc_size)); | 10751 static_cast<size_t>(desc.reloc_size)); |
10752 | 10752 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10848 } | 10848 } |
10849 | 10849 |
10850 | 10850 |
10851 SafepointEntry Code::GetSafepointEntry(Address pc) { | 10851 SafepointEntry Code::GetSafepointEntry(Address pc) { |
10852 SafepointTable table(this); | 10852 SafepointTable table(this); |
10853 return table.FindEntry(pc); | 10853 return table.FindEntry(pc); |
10854 } | 10854 } |
10855 | 10855 |
10856 | 10856 |
10857 Object* Code::FindNthObject(int n, Map* match_map) { | 10857 Object* Code::FindNthObject(int n, Map* match_map) { |
10858 ASSERT(is_inline_cache_stub()); | 10858 DCHECK(is_inline_cache_stub()); |
10859 DisallowHeapAllocation no_allocation; | 10859 DisallowHeapAllocation no_allocation; |
10860 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10860 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
10861 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10861 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10862 RelocInfo* info = it.rinfo(); | 10862 RelocInfo* info = it.rinfo(); |
10863 Object* object = info->target_object(); | 10863 Object* object = info->target_object(); |
10864 if (object->IsHeapObject()) { | 10864 if (object->IsHeapObject()) { |
10865 if (HeapObject::cast(object)->map() == match_map) { | 10865 if (HeapObject::cast(object)->map() == match_map) { |
10866 if (--n == 0) return object; | 10866 if (--n == 0) return object; |
10867 } | 10867 } |
10868 } | 10868 } |
10869 } | 10869 } |
10870 return NULL; | 10870 return NULL; |
10871 } | 10871 } |
10872 | 10872 |
10873 | 10873 |
10874 AllocationSite* Code::FindFirstAllocationSite() { | 10874 AllocationSite* Code::FindFirstAllocationSite() { |
10875 Object* result = FindNthObject(1, GetHeap()->allocation_site_map()); | 10875 Object* result = FindNthObject(1, GetHeap()->allocation_site_map()); |
10876 return (result != NULL) ? AllocationSite::cast(result) : NULL; | 10876 return (result != NULL) ? AllocationSite::cast(result) : NULL; |
10877 } | 10877 } |
10878 | 10878 |
10879 | 10879 |
10880 Map* Code::FindFirstMap() { | 10880 Map* Code::FindFirstMap() { |
10881 Object* result = FindNthObject(1, GetHeap()->meta_map()); | 10881 Object* result = FindNthObject(1, GetHeap()->meta_map()); |
10882 return (result != NULL) ? Map::cast(result) : NULL; | 10882 return (result != NULL) ? Map::cast(result) : NULL; |
10883 } | 10883 } |
10884 | 10884 |
10885 | 10885 |
10886 void Code::FindAndReplace(const FindAndReplacePattern& pattern) { | 10886 void Code::FindAndReplace(const FindAndReplacePattern& pattern) { |
10887 ASSERT(is_inline_cache_stub() || is_handler()); | 10887 DCHECK(is_inline_cache_stub() || is_handler()); |
10888 DisallowHeapAllocation no_allocation; | 10888 DisallowHeapAllocation no_allocation; |
10889 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10889 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
10890 STATIC_ASSERT(FindAndReplacePattern::kMaxCount < 32); | 10890 STATIC_ASSERT(FindAndReplacePattern::kMaxCount < 32); |
10891 int current_pattern = 0; | 10891 int current_pattern = 0; |
10892 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10892 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10893 RelocInfo* info = it.rinfo(); | 10893 RelocInfo* info = it.rinfo(); |
10894 Object* object = info->target_object(); | 10894 Object* object = info->target_object(); |
10895 if (object->IsHeapObject()) { | 10895 if (object->IsHeapObject()) { |
10896 Map* map = HeapObject::cast(object)->map(); | 10896 Map* map = HeapObject::cast(object)->map(); |
10897 if (map == *pattern.find_[current_pattern]) { | 10897 if (map == *pattern.find_[current_pattern]) { |
10898 info->set_target_object(*pattern.replace_[current_pattern]); | 10898 info->set_target_object(*pattern.replace_[current_pattern]); |
10899 if (++current_pattern == pattern.count_) return; | 10899 if (++current_pattern == pattern.count_) return; |
10900 } | 10900 } |
10901 } | 10901 } |
10902 } | 10902 } |
10903 UNREACHABLE(); | 10903 UNREACHABLE(); |
10904 } | 10904 } |
10905 | 10905 |
10906 | 10906 |
10907 void Code::FindAllMaps(MapHandleList* maps) { | 10907 void Code::FindAllMaps(MapHandleList* maps) { |
10908 ASSERT(is_inline_cache_stub()); | 10908 DCHECK(is_inline_cache_stub()); |
10909 DisallowHeapAllocation no_allocation; | 10909 DisallowHeapAllocation no_allocation; |
10910 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10910 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
10911 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10911 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10912 RelocInfo* info = it.rinfo(); | 10912 RelocInfo* info = it.rinfo(); |
10913 Object* object = info->target_object(); | 10913 Object* object = info->target_object(); |
10914 if (object->IsMap()) maps->Add(handle(Map::cast(object))); | 10914 if (object->IsMap()) maps->Add(handle(Map::cast(object))); |
10915 } | 10915 } |
10916 } | 10916 } |
10917 | 10917 |
10918 | 10918 |
10919 Code* Code::FindFirstHandler() { | 10919 Code* Code::FindFirstHandler() { |
10920 ASSERT(is_inline_cache_stub()); | 10920 DCHECK(is_inline_cache_stub()); |
10921 DisallowHeapAllocation no_allocation; | 10921 DisallowHeapAllocation no_allocation; |
10922 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); | 10922 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
10923 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10923 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10924 RelocInfo* info = it.rinfo(); | 10924 RelocInfo* info = it.rinfo(); |
10925 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); | 10925 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); |
10926 if (code->kind() == Code::HANDLER) return code; | 10926 if (code->kind() == Code::HANDLER) return code; |
10927 } | 10927 } |
10928 return NULL; | 10928 return NULL; |
10929 } | 10929 } |
10930 | 10930 |
10931 | 10931 |
10932 bool Code::FindHandlers(CodeHandleList* code_list, int length) { | 10932 bool Code::FindHandlers(CodeHandleList* code_list, int length) { |
10933 ASSERT(is_inline_cache_stub()); | 10933 DCHECK(is_inline_cache_stub()); |
10934 DisallowHeapAllocation no_allocation; | 10934 DisallowHeapAllocation no_allocation; |
10935 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); | 10935 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET); |
10936 int i = 0; | 10936 int i = 0; |
10937 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10937 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10938 if (i == length) return true; | 10938 if (i == length) return true; |
10939 RelocInfo* info = it.rinfo(); | 10939 RelocInfo* info = it.rinfo(); |
10940 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); | 10940 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); |
10941 // IC stubs with handlers never contain non-handler code objects before | 10941 // IC stubs with handlers never contain non-handler code objects before |
10942 // handler targets. | 10942 // handler targets. |
10943 if (code->kind() != Code::HANDLER) break; | 10943 if (code->kind() != Code::HANDLER) break; |
10944 code_list->Add(Handle<Code>(code)); | 10944 code_list->Add(Handle<Code>(code)); |
10945 i++; | 10945 i++; |
10946 } | 10946 } |
10947 return i == length; | 10947 return i == length; |
10948 } | 10948 } |
10949 | 10949 |
10950 | 10950 |
10951 MaybeHandle<Code> Code::FindHandlerForMap(Map* map) { | 10951 MaybeHandle<Code> Code::FindHandlerForMap(Map* map) { |
10952 ASSERT(is_inline_cache_stub()); | 10952 DCHECK(is_inline_cache_stub()); |
10953 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | | 10953 int mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) | |
10954 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10954 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
10955 bool return_next = false; | 10955 bool return_next = false; |
10956 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10956 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10957 RelocInfo* info = it.rinfo(); | 10957 RelocInfo* info = it.rinfo(); |
10958 if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) { | 10958 if (info->rmode() == RelocInfo::EMBEDDED_OBJECT) { |
10959 Object* object = info->target_object(); | 10959 Object* object = info->target_object(); |
10960 if (object == map) return_next = true; | 10960 if (object == map) return_next = true; |
10961 } else if (return_next) { | 10961 } else if (return_next) { |
10962 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); | 10962 Code* code = Code::GetCodeFromTargetAddress(info->target_address()); |
10963 ASSERT(code->kind() == Code::HANDLER); | 10963 DCHECK(code->kind() == Code::HANDLER); |
10964 return handle(code); | 10964 return handle(code); |
10965 } | 10965 } |
10966 } | 10966 } |
10967 return MaybeHandle<Code>(); | 10967 return MaybeHandle<Code>(); |
10968 } | 10968 } |
10969 | 10969 |
10970 | 10970 |
10971 Name* Code::FindFirstName() { | 10971 Name* Code::FindFirstName() { |
10972 ASSERT(is_inline_cache_stub()); | 10972 DCHECK(is_inline_cache_stub()); |
10973 DisallowHeapAllocation no_allocation; | 10973 DisallowHeapAllocation no_allocation; |
10974 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); | 10974 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); |
10975 for (RelocIterator it(this, mask); !it.done(); it.next()) { | 10975 for (RelocIterator it(this, mask); !it.done(); it.next()) { |
10976 RelocInfo* info = it.rinfo(); | 10976 RelocInfo* info = it.rinfo(); |
10977 Object* object = info->target_object(); | 10977 Object* object = info->target_object(); |
10978 if (object->IsName()) return Name::cast(object); | 10978 if (object->IsName()) return Name::cast(object); |
10979 } | 10979 } |
10980 return NULL; | 10980 return NULL; |
10981 } | 10981 } |
10982 | 10982 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11028 vector->set(i, TypeFeedbackInfo::RawUninitializedSentinel(heap), | 11028 vector->set(i, TypeFeedbackInfo::RawUninitializedSentinel(heap), |
11029 SKIP_WRITE_BARRIER); | 11029 SKIP_WRITE_BARRIER); |
11030 } | 11030 } |
11031 } | 11031 } |
11032 } | 11032 } |
11033 } | 11033 } |
11034 | 11034 |
11035 | 11035 |
11036 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { | 11036 BailoutId Code::TranslatePcOffsetToAstId(uint32_t pc_offset) { |
11037 DisallowHeapAllocation no_gc; | 11037 DisallowHeapAllocation no_gc; |
11038 ASSERT(kind() == FUNCTION); | 11038 DCHECK(kind() == FUNCTION); |
11039 BackEdgeTable back_edges(this, &no_gc); | 11039 BackEdgeTable back_edges(this, &no_gc); |
11040 for (uint32_t i = 0; i < back_edges.length(); i++) { | 11040 for (uint32_t i = 0; i < back_edges.length(); i++) { |
11041 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); | 11041 if (back_edges.pc_offset(i) == pc_offset) return back_edges.ast_id(i); |
11042 } | 11042 } |
11043 return BailoutId::None(); | 11043 return BailoutId::None(); |
11044 } | 11044 } |
11045 | 11045 |
11046 | 11046 |
11047 uint32_t Code::TranslateAstIdToPcOffset(BailoutId ast_id) { | 11047 uint32_t Code::TranslateAstIdToPcOffset(BailoutId ast_id) { |
11048 DisallowHeapAllocation no_gc; | 11048 DisallowHeapAllocation no_gc; |
11049 ASSERT(kind() == FUNCTION); | 11049 DCHECK(kind() == FUNCTION); |
11050 BackEdgeTable back_edges(this, &no_gc); | 11050 BackEdgeTable back_edges(this, &no_gc); |
11051 for (uint32_t i = 0; i < back_edges.length(); i++) { | 11051 for (uint32_t i = 0; i < back_edges.length(); i++) { |
11052 if (back_edges.ast_id(i) == ast_id) return back_edges.pc_offset(i); | 11052 if (back_edges.ast_id(i) == ast_id) return back_edges.pc_offset(i); |
11053 } | 11053 } |
11054 UNREACHABLE(); // We expect to find the back edge. | 11054 UNREACHABLE(); // We expect to find the back edge. |
11055 return 0; | 11055 return 0; |
11056 } | 11056 } |
11057 | 11057 |
11058 | 11058 |
11059 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { | 11059 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11171 #define HANDLE_CODE_AGE(AGE) \ | 11171 #define HANDLE_CODE_AGE(AGE) \ |
11172 case k##AGE##CodeAge: { \ | 11172 case k##AGE##CodeAge: { \ |
11173 Code* stub = parity == EVEN_MARKING_PARITY \ | 11173 Code* stub = parity == EVEN_MARKING_PARITY \ |
11174 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ | 11174 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ |
11175 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ | 11175 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ |
11176 return stub; \ | 11176 return stub; \ |
11177 } | 11177 } |
11178 CODE_AGE_LIST(HANDLE_CODE_AGE) | 11178 CODE_AGE_LIST(HANDLE_CODE_AGE) |
11179 #undef HANDLE_CODE_AGE | 11179 #undef HANDLE_CODE_AGE |
11180 case kNotExecutedCodeAge: { | 11180 case kNotExecutedCodeAge: { |
11181 ASSERT(parity == NO_MARKING_PARITY); | 11181 DCHECK(parity == NO_MARKING_PARITY); |
11182 return *builtins->MarkCodeAsExecutedOnce(); | 11182 return *builtins->MarkCodeAsExecutedOnce(); |
11183 } | 11183 } |
11184 case kExecutedOnceCodeAge: { | 11184 case kExecutedOnceCodeAge: { |
11185 ASSERT(parity == NO_MARKING_PARITY); | 11185 DCHECK(parity == NO_MARKING_PARITY); |
11186 return *builtins->MarkCodeAsExecutedTwice(); | 11186 return *builtins->MarkCodeAsExecutedTwice(); |
11187 } | 11187 } |
11188 default: | 11188 default: |
11189 UNREACHABLE(); | 11189 UNREACHABLE(); |
11190 break; | 11190 break; |
11191 } | 11191 } |
11192 return NULL; | 11192 return NULL; |
11193 } | 11193 } |
11194 | 11194 |
11195 | 11195 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11264 | 11264 |
11265 if (!FLAG_print_code_verbose) { | 11265 if (!FLAG_print_code_verbose) { |
11266 os << "\n"; | 11266 os << "\n"; |
11267 continue; | 11267 continue; |
11268 } | 11268 } |
11269 // Print details of the frame translation. | 11269 // Print details of the frame translation. |
11270 int translation_index = TranslationIndex(i)->value(); | 11270 int translation_index = TranslationIndex(i)->value(); |
11271 TranslationIterator iterator(TranslationByteArray(), translation_index); | 11271 TranslationIterator iterator(TranslationByteArray(), translation_index); |
11272 Translation::Opcode opcode = | 11272 Translation::Opcode opcode = |
11273 static_cast<Translation::Opcode>(iterator.Next()); | 11273 static_cast<Translation::Opcode>(iterator.Next()); |
11274 ASSERT(Translation::BEGIN == opcode); | 11274 DCHECK(Translation::BEGIN == opcode); |
11275 int frame_count = iterator.Next(); | 11275 int frame_count = iterator.Next(); |
11276 int jsframe_count = iterator.Next(); | 11276 int jsframe_count = iterator.Next(); |
11277 os << " " << Translation::StringFor(opcode) | 11277 os << " " << Translation::StringFor(opcode) |
11278 << " {frame count=" << frame_count | 11278 << " {frame count=" << frame_count |
11279 << ", js frame count=" << jsframe_count << "}\n"; | 11279 << ", js frame count=" << jsframe_count << "}\n"; |
11280 | 11280 |
11281 while (iterator.HasNext() && | 11281 while (iterator.HasNext() && |
11282 Translation::BEGIN != | 11282 Translation::BEGIN != |
11283 (opcode = static_cast<Translation::Opcode>(iterator.Next()))) { | 11283 (opcode = static_cast<Translation::Opcode>(iterator.Next()))) { |
11284 Vector<char> buf2 = Vector<char>::New(128); | 11284 Vector<char> buf2 = Vector<char>::New(128); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11483 const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this), true); | 11483 const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this), true); |
11484 os << "major_key = " << (n == NULL ? "null" : n) << "\n"; | 11484 os << "major_key = " << (n == NULL ? "null" : n) << "\n"; |
11485 } | 11485 } |
11486 if (is_inline_cache_stub()) { | 11486 if (is_inline_cache_stub()) { |
11487 os << "ic_state = " << ICState2String(ic_state()) << "\n"; | 11487 os << "ic_state = " << ICState2String(ic_state()) << "\n"; |
11488 PrintExtraICState(os, kind(), extra_ic_state()); | 11488 PrintExtraICState(os, kind(), extra_ic_state()); |
11489 if (ic_state() == MONOMORPHIC) { | 11489 if (ic_state() == MONOMORPHIC) { |
11490 os << "type = " << StubType2String(type()) << "\n"; | 11490 os << "type = " << StubType2String(type()) << "\n"; |
11491 } | 11491 } |
11492 if (is_compare_ic_stub()) { | 11492 if (is_compare_ic_stub()) { |
11493 ASSERT(CodeStub::GetMajorKey(this) == CodeStub::CompareIC); | 11493 DCHECK(CodeStub::GetMajorKey(this) == CodeStub::CompareIC); |
11494 CompareIC::State left_state, right_state, handler_state; | 11494 CompareIC::State left_state, right_state, handler_state; |
11495 Token::Value op; | 11495 Token::Value op; |
11496 ICCompareStub::DecodeKey(stub_key(), &left_state, &right_state, | 11496 ICCompareStub::DecodeKey(stub_key(), &left_state, &right_state, |
11497 &handler_state, &op); | 11497 &handler_state, &op); |
11498 os << "compare_state = " << CompareIC::GetStateName(left_state) << "*" | 11498 os << "compare_state = " << CompareIC::GetStateName(left_state) << "*" |
11499 << CompareIC::GetStateName(right_state) << " -> " | 11499 << CompareIC::GetStateName(right_state) << " -> " |
11500 << CompareIC::GetStateName(handler_state) << "\n"; | 11500 << CompareIC::GetStateName(handler_state) << "\n"; |
11501 os << "compare_operation = " << Token::Name(op) << "\n"; | 11501 os << "compare_operation = " << Token::Name(op) << "\n"; |
11502 } | 11502 } |
11503 } | 11503 } |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11587 } | 11587 } |
11588 #endif // ENABLE_DISASSEMBLER | 11588 #endif // ENABLE_DISASSEMBLER |
11589 | 11589 |
11590 | 11590 |
11591 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength( | 11591 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength( |
11592 Handle<JSObject> object, | 11592 Handle<JSObject> object, |
11593 int capacity, | 11593 int capacity, |
11594 int length, | 11594 int length, |
11595 SetFastElementsCapacitySmiMode smi_mode) { | 11595 SetFastElementsCapacitySmiMode smi_mode) { |
11596 // We should never end in here with a pixel or external array. | 11596 // We should never end in here with a pixel or external array. |
11597 ASSERT(!object->HasExternalArrayElements()); | 11597 DCHECK(!object->HasExternalArrayElements()); |
11598 | 11598 |
11599 // Allocate a new fast elements backing store. | 11599 // Allocate a new fast elements backing store. |
11600 Handle<FixedArray> new_elements = | 11600 Handle<FixedArray> new_elements = |
11601 object->GetIsolate()->factory()->NewUninitializedFixedArray(capacity); | 11601 object->GetIsolate()->factory()->NewUninitializedFixedArray(capacity); |
11602 | 11602 |
11603 ElementsKind elements_kind = object->GetElementsKind(); | 11603 ElementsKind elements_kind = object->GetElementsKind(); |
11604 ElementsKind new_elements_kind; | 11604 ElementsKind new_elements_kind; |
11605 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, | 11605 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, |
11606 // or if it's allowed and the old elements array contained only SMIs. | 11606 // or if it's allowed and the old elements array contained only SMIs. |
11607 bool has_fast_smi_elements = | 11607 bool has_fast_smi_elements = |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11647 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length)); | 11647 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length)); |
11648 } | 11648 } |
11649 return new_elements; | 11649 return new_elements; |
11650 } | 11650 } |
11651 | 11651 |
11652 | 11652 |
11653 void JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object, | 11653 void JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object, |
11654 int capacity, | 11654 int capacity, |
11655 int length) { | 11655 int length) { |
11656 // We should never end in here with a pixel or external array. | 11656 // We should never end in here with a pixel or external array. |
11657 ASSERT(!object->HasExternalArrayElements()); | 11657 DCHECK(!object->HasExternalArrayElements()); |
11658 | 11658 |
11659 Handle<FixedArrayBase> elems = | 11659 Handle<FixedArrayBase> elems = |
11660 object->GetIsolate()->factory()->NewFixedDoubleArray(capacity); | 11660 object->GetIsolate()->factory()->NewFixedDoubleArray(capacity); |
11661 | 11661 |
11662 ElementsKind elements_kind = object->GetElementsKind(); | 11662 ElementsKind elements_kind = object->GetElementsKind(); |
11663 CHECK(elements_kind != SLOPPY_ARGUMENTS_ELEMENTS); | 11663 CHECK(elements_kind != SLOPPY_ARGUMENTS_ELEMENTS); |
11664 ElementsKind new_elements_kind = elements_kind; | 11664 ElementsKind new_elements_kind = elements_kind; |
11665 if (IsHoleyElementsKind(elements_kind)) { | 11665 if (IsHoleyElementsKind(elements_kind)) { |
11666 new_elements_kind = FAST_HOLEY_DOUBLE_ELEMENTS; | 11666 new_elements_kind = FAST_HOLEY_DOUBLE_ELEMENTS; |
11667 } else { | 11667 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
11683 } | 11683 } |
11684 | 11684 |
11685 if (object->IsJSArray()) { | 11685 if (object->IsJSArray()) { |
11686 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length)); | 11686 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length)); |
11687 } | 11687 } |
11688 } | 11688 } |
11689 | 11689 |
11690 | 11690 |
11691 // static | 11691 // static |
11692 void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) { | 11692 void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) { |
11693 ASSERT(capacity >= 0); | 11693 DCHECK(capacity >= 0); |
11694 array->GetIsolate()->factory()->NewJSArrayStorage( | 11694 array->GetIsolate()->factory()->NewJSArrayStorage( |
11695 array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); | 11695 array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); |
11696 } | 11696 } |
11697 | 11697 |
11698 | 11698 |
11699 void JSArray::Expand(Handle<JSArray> array, int required_size) { | 11699 void JSArray::Expand(Handle<JSArray> array, int required_size) { |
11700 ElementsAccessor* accessor = array->GetElementsAccessor(); | 11700 ElementsAccessor* accessor = array->GetElementsAccessor(); |
11701 accessor->SetCapacityAndLength(array, required_size, required_size); | 11701 accessor->SetCapacityAndLength(array, required_size, required_size); |
11702 } | 11702 } |
11703 | 11703 |
11704 | 11704 |
11705 // Returns false if the passed-in index is marked non-configurable, | 11705 // Returns false if the passed-in index is marked non-configurable, |
11706 // which will cause the ES5 truncation operation to halt, and thus | 11706 // which will cause the ES5 truncation operation to halt, and thus |
11707 // no further old values need be collected. | 11707 // no further old values need be collected. |
11708 static bool GetOldValue(Isolate* isolate, | 11708 static bool GetOldValue(Isolate* isolate, |
11709 Handle<JSObject> object, | 11709 Handle<JSObject> object, |
11710 uint32_t index, | 11710 uint32_t index, |
11711 List<Handle<Object> >* old_values, | 11711 List<Handle<Object> >* old_values, |
11712 List<uint32_t>* indices) { | 11712 List<uint32_t>* indices) { |
11713 Maybe<PropertyAttributes> maybe = | 11713 Maybe<PropertyAttributes> maybe = |
11714 JSReceiver::GetOwnElementAttribute(object, index); | 11714 JSReceiver::GetOwnElementAttribute(object, index); |
11715 ASSERT(maybe.has_value); | 11715 DCHECK(maybe.has_value); |
11716 ASSERT(maybe.value != ABSENT); | 11716 DCHECK(maybe.value != ABSENT); |
11717 if (maybe.value == DONT_DELETE) return false; | 11717 if (maybe.value == DONT_DELETE) return false; |
11718 Handle<Object> value; | 11718 Handle<Object> value; |
11719 if (!JSObject::GetOwnElementAccessorPair(object, index).is_null()) { | 11719 if (!JSObject::GetOwnElementAccessorPair(object, index).is_null()) { |
11720 value = Handle<Object>::cast(isolate->factory()->the_hole_value()); | 11720 value = Handle<Object>::cast(isolate->factory()->the_hole_value()); |
11721 } else { | 11721 } else { |
11722 value = Object::GetElement(isolate, object, index).ToHandleChecked(); | 11722 value = Object::GetElement(isolate, object, index).ToHandleChecked(); |
11723 } | 11723 } |
11724 old_values->Add(value); | 11724 old_values->Add(value); |
11725 indices->Add(index); | 11725 indices->Add(index); |
11726 return true; | 11726 return true; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11781 // space size, then force it to go dictionary mode. | 11781 // space size, then force it to go dictionary mode. |
11782 int max_fast_array_size = static_cast<int>( | 11782 int max_fast_array_size = static_cast<int>( |
11783 (array->GetHeap()->MaxOldGenerationSize() / kDoubleSize) / 4); | 11783 (array->GetHeap()->MaxOldGenerationSize() / kDoubleSize) / 4); |
11784 if (new_length_handle->IsNumber() && | 11784 if (new_length_handle->IsNumber() && |
11785 NumberToInt32(*new_length_handle) >= max_fast_array_size) { | 11785 NumberToInt32(*new_length_handle) >= max_fast_array_size) { |
11786 NormalizeElements(array); | 11786 NormalizeElements(array); |
11787 } | 11787 } |
11788 } | 11788 } |
11789 | 11789 |
11790 // We should never end in here with a pixel or external array. | 11790 // We should never end in here with a pixel or external array. |
11791 ASSERT(array->AllowsSetElementsLength()); | 11791 DCHECK(array->AllowsSetElementsLength()); |
11792 if (!array->map()->is_observed()) { | 11792 if (!array->map()->is_observed()) { |
11793 return array->GetElementsAccessor()->SetLength(array, new_length_handle); | 11793 return array->GetElementsAccessor()->SetLength(array, new_length_handle); |
11794 } | 11794 } |
11795 | 11795 |
11796 Isolate* isolate = array->GetIsolate(); | 11796 Isolate* isolate = array->GetIsolate(); |
11797 List<uint32_t> indices; | 11797 List<uint32_t> indices; |
11798 List<Handle<Object> > old_values; | 11798 List<Handle<Object> > old_values; |
11799 Handle<Object> old_length_handle(array->length(), isolate); | 11799 Handle<Object> old_length_handle(array->length(), isolate); |
11800 uint32_t old_length = 0; | 11800 uint32_t old_length = 0; |
11801 CHECK(old_length_handle->ToArrayIndex(&old_length)); | 11801 CHECK(old_length_handle->ToArrayIndex(&old_length)); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11887 return Handle<Map>(Map::cast(result)); | 11887 return Handle<Map>(Map::cast(result)); |
11888 } | 11888 } |
11889 } | 11889 } |
11890 return Handle<Map>(); | 11890 return Handle<Map>(); |
11891 } | 11891 } |
11892 | 11892 |
11893 | 11893 |
11894 Handle<Map> Map::PutPrototypeTransition(Handle<Map> map, | 11894 Handle<Map> Map::PutPrototypeTransition(Handle<Map> map, |
11895 Handle<Object> prototype, | 11895 Handle<Object> prototype, |
11896 Handle<Map> target_map) { | 11896 Handle<Map> target_map) { |
11897 ASSERT(target_map->IsMap()); | 11897 DCHECK(target_map->IsMap()); |
11898 ASSERT(HeapObject::cast(*prototype)->map()->IsMap()); | 11898 DCHECK(HeapObject::cast(*prototype)->map()->IsMap()); |
11899 // Don't cache prototype transition if this map is shared. | 11899 // Don't cache prototype transition if this map is shared. |
11900 if (map->is_shared() || !FLAG_cache_prototype_transitions) return map; | 11900 if (map->is_shared() || !FLAG_cache_prototype_transitions) return map; |
11901 | 11901 |
11902 const int step = kProtoTransitionElementsPerEntry; | 11902 const int step = kProtoTransitionElementsPerEntry; |
11903 const int header = kProtoTransitionHeaderSize; | 11903 const int header = kProtoTransitionHeaderSize; |
11904 | 11904 |
11905 Handle<FixedArray> cache(map->GetPrototypeTransitions()); | 11905 Handle<FixedArray> cache(map->GetPrototypeTransitions()); |
11906 int capacity = (cache->length() - header) / step; | 11906 int capacity = (cache->length() - header) / step; |
11907 int transitions = map->NumberOfProtoTransitions() + 1; | 11907 int transitions = map->NumberOfProtoTransitions() + 1; |
11908 | 11908 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11966 Handle<Code> code) { | 11966 Handle<Code> code) { |
11967 Handle<DependentCode> codes = DependentCode::Insert( | 11967 Handle<DependentCode> codes = DependentCode::Insert( |
11968 Handle<DependentCode>(map->dependent_code()), group, code); | 11968 Handle<DependentCode>(map->dependent_code()), group, code); |
11969 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); | 11969 if (*codes != map->dependent_code()) map->set_dependent_code(*codes); |
11970 } | 11970 } |
11971 | 11971 |
11972 | 11972 |
11973 // static | 11973 // static |
11974 void Map::AddDependentIC(Handle<Map> map, | 11974 void Map::AddDependentIC(Handle<Map> map, |
11975 Handle<Code> stub) { | 11975 Handle<Code> stub) { |
11976 ASSERT(stub->next_code_link()->IsUndefined()); | 11976 DCHECK(stub->next_code_link()->IsUndefined()); |
11977 int n = map->dependent_code()->number_of_entries(DependentCode::kWeakICGroup); | 11977 int n = map->dependent_code()->number_of_entries(DependentCode::kWeakICGroup); |
11978 if (n == 0) { | 11978 if (n == 0) { |
11979 // Slow path: insert the head of the list with possible heap allocation. | 11979 // Slow path: insert the head of the list with possible heap allocation. |
11980 Map::AddDependentCode(map, DependentCode::kWeakICGroup, stub); | 11980 Map::AddDependentCode(map, DependentCode::kWeakICGroup, stub); |
11981 } else { | 11981 } else { |
11982 // Fast path: link the stub to the existing head of the list without any | 11982 // Fast path: link the stub to the existing head of the list without any |
11983 // heap allocation. | 11983 // heap allocation. |
11984 ASSERT(n == 1); | 11984 DCHECK(n == 1); |
11985 map->dependent_code()->AddToDependentICList(stub); | 11985 map->dependent_code()->AddToDependentICList(stub); |
11986 } | 11986 } |
11987 } | 11987 } |
11988 | 11988 |
11989 | 11989 |
11990 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) { | 11990 DependentCode::GroupStartIndexes::GroupStartIndexes(DependentCode* entries) { |
11991 Recompute(entries); | 11991 Recompute(entries); |
11992 } | 11992 } |
11993 | 11993 |
11994 | 11994 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12065 int end = starts.at(group + 1); | 12065 int end = starts.at(group + 1); |
12066 for (int i = start; i < end; i++) { | 12066 for (int i = start; i < end; i++) { |
12067 if (object_at(i) == info_wrapper) { | 12067 if (object_at(i) == info_wrapper) { |
12068 set_object_at(i, code); | 12068 set_object_at(i, code); |
12069 break; | 12069 break; |
12070 } | 12070 } |
12071 } | 12071 } |
12072 | 12072 |
12073 #ifdef DEBUG | 12073 #ifdef DEBUG |
12074 for (int i = start; i < end; i++) { | 12074 for (int i = start; i < end; i++) { |
12075 ASSERT(is_code_at(i) || compilation_info_at(i) != info); | 12075 DCHECK(is_code_at(i) || compilation_info_at(i) != info); |
12076 } | 12076 } |
12077 #endif | 12077 #endif |
12078 } | 12078 } |
12079 | 12079 |
12080 | 12080 |
12081 void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group, | 12081 void DependentCode::RemoveCompilationInfo(DependentCode::DependencyGroup group, |
12082 CompilationInfo* info) { | 12082 CompilationInfo* info) { |
12083 DisallowHeapAllocation no_allocation; | 12083 DisallowHeapAllocation no_allocation; |
12084 AllowDeferredHandleDereference get_object_wrapper; | 12084 AllowDeferredHandleDereference get_object_wrapper; |
12085 Foreign* info_wrapper = *info->object_wrapper(); | 12085 Foreign* info_wrapper = *info->object_wrapper(); |
12086 GroupStartIndexes starts(this); | 12086 GroupStartIndexes starts(this); |
12087 int start = starts.at(group); | 12087 int start = starts.at(group); |
12088 int end = starts.at(group + 1); | 12088 int end = starts.at(group + 1); |
12089 // Find compilation info wrapper. | 12089 // Find compilation info wrapper. |
12090 int info_pos = -1; | 12090 int info_pos = -1; |
12091 for (int i = start; i < end; i++) { | 12091 for (int i = start; i < end; i++) { |
12092 if (object_at(i) == info_wrapper) { | 12092 if (object_at(i) == info_wrapper) { |
12093 info_pos = i; | 12093 info_pos = i; |
12094 break; | 12094 break; |
12095 } | 12095 } |
12096 } | 12096 } |
12097 if (info_pos == -1) return; // Not found. | 12097 if (info_pos == -1) return; // Not found. |
12098 int gap = info_pos; | 12098 int gap = info_pos; |
12099 // Use the last of each group to fill the gap in the previous group. | 12099 // Use the last of each group to fill the gap in the previous group. |
12100 for (int i = group; i < kGroupCount; i++) { | 12100 for (int i = group; i < kGroupCount; i++) { |
12101 int last_of_group = starts.at(i + 1) - 1; | 12101 int last_of_group = starts.at(i + 1) - 1; |
12102 ASSERT(last_of_group >= gap); | 12102 DCHECK(last_of_group >= gap); |
12103 if (last_of_group == gap) continue; | 12103 if (last_of_group == gap) continue; |
12104 copy(last_of_group, gap); | 12104 copy(last_of_group, gap); |
12105 gap = last_of_group; | 12105 gap = last_of_group; |
12106 } | 12106 } |
12107 ASSERT(gap == starts.number_of_entries() - 1); | 12107 DCHECK(gap == starts.number_of_entries() - 1); |
12108 clear_at(gap); // Clear last gap. | 12108 clear_at(gap); // Clear last gap. |
12109 set_number_of_entries(group, end - start - 1); | 12109 set_number_of_entries(group, end - start - 1); |
12110 | 12110 |
12111 #ifdef DEBUG | 12111 #ifdef DEBUG |
12112 for (int i = start; i < end - 1; i++) { | 12112 for (int i = start; i < end - 1; i++) { |
12113 ASSERT(is_code_at(i) || compilation_info_at(i) != info); | 12113 DCHECK(is_code_at(i) || compilation_info_at(i) != info); |
12114 } | 12114 } |
12115 #endif | 12115 #endif |
12116 } | 12116 } |
12117 | 12117 |
12118 | 12118 |
12119 static bool CodeListContains(Object* head, Code* code) { | 12119 static bool CodeListContains(Object* head, Code* code) { |
12120 while (!head->IsUndefined()) { | 12120 while (!head->IsUndefined()) { |
12121 if (head == code) return true; | 12121 if (head == code) return true; |
12122 head = Code::cast(head)->next_code_link(); | 12122 head = Code::cast(head)->next_code_link(); |
12123 } | 12123 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12173 clear_at(i); | 12173 clear_at(i); |
12174 } | 12174 } |
12175 set_number_of_entries(group, 0); | 12175 set_number_of_entries(group, 0); |
12176 return marked; | 12176 return marked; |
12177 } | 12177 } |
12178 | 12178 |
12179 | 12179 |
12180 void DependentCode::DeoptimizeDependentCodeGroup( | 12180 void DependentCode::DeoptimizeDependentCodeGroup( |
12181 Isolate* isolate, | 12181 Isolate* isolate, |
12182 DependentCode::DependencyGroup group) { | 12182 DependentCode::DependencyGroup group) { |
12183 ASSERT(AllowCodeDependencyChange::IsAllowed()); | 12183 DCHECK(AllowCodeDependencyChange::IsAllowed()); |
12184 DisallowHeapAllocation no_allocation_scope; | 12184 DisallowHeapAllocation no_allocation_scope; |
12185 bool marked = MarkCodeForDeoptimization(isolate, group); | 12185 bool marked = MarkCodeForDeoptimization(isolate, group); |
12186 | 12186 |
12187 if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate); | 12187 if (marked) Deoptimizer::DeoptimizeMarkedCode(isolate); |
12188 } | 12188 } |
12189 | 12189 |
12190 | 12190 |
12191 void DependentCode::AddToDependentICList(Handle<Code> stub) { | 12191 void DependentCode::AddToDependentICList(Handle<Code> stub) { |
12192 DisallowHeapAllocation no_heap_allocation; | 12192 DisallowHeapAllocation no_heap_allocation; |
12193 GroupStartIndexes starts(this); | 12193 GroupStartIndexes starts(this); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12280 Handle<Map> map(real_receiver->map()); | 12280 Handle<Map> map(real_receiver->map()); |
12281 | 12281 |
12282 // Nothing to do if prototype is already set. | 12282 // Nothing to do if prototype is already set. |
12283 if (map->prototype() == *value) return value; | 12283 if (map->prototype() == *value) return value; |
12284 | 12284 |
12285 if (value->IsJSObject()) { | 12285 if (value->IsJSObject()) { |
12286 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); | 12286 JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value)); |
12287 } | 12287 } |
12288 | 12288 |
12289 Handle<Map> new_map = Map::TransitionToPrototype(map, value); | 12289 Handle<Map> new_map = Map::TransitionToPrototype(map, value); |
12290 ASSERT(new_map->prototype() == *value); | 12290 DCHECK(new_map->prototype() == *value); |
12291 JSObject::MigrateToMap(real_receiver, new_map); | 12291 JSObject::MigrateToMap(real_receiver, new_map); |
12292 | 12292 |
12293 if (!dictionary_elements_in_chain && | 12293 if (!dictionary_elements_in_chain && |
12294 new_map->DictionaryElementsInPrototypeChainOnly()) { | 12294 new_map->DictionaryElementsInPrototypeChainOnly()) { |
12295 // If the prototype chain didn't previously have element callbacks, then | 12295 // If the prototype chain didn't previously have element callbacks, then |
12296 // KeyedStoreICs need to be cleared to ensure any that involve this | 12296 // KeyedStoreICs need to be cleared to ensure any that involve this |
12297 // map go generic. | 12297 // map go generic. |
12298 object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); | 12298 object->GetHeap()->ClearAllICsByKind(Code::KEYED_STORE_IC); |
12299 } | 12299 } |
12300 | 12300 |
12301 heap->ClearInstanceofCache(); | 12301 heap->ClearInstanceofCache(); |
12302 ASSERT(size == object->Size()); | 12302 DCHECK(size == object->Size()); |
12303 return value; | 12303 return value; |
12304 } | 12304 } |
12305 | 12305 |
12306 | 12306 |
12307 void JSObject::EnsureCanContainElements(Handle<JSObject> object, | 12307 void JSObject::EnsureCanContainElements(Handle<JSObject> object, |
12308 Arguments* args, | 12308 Arguments* args, |
12309 uint32_t first_arg, | 12309 uint32_t first_arg, |
12310 uint32_t arg_count, | 12310 uint32_t arg_count, |
12311 EnsureElementsMode mode) { | 12311 EnsureElementsMode mode) { |
12312 // Elements in |Arguments| are ordered backwards (because they're on the | 12312 // Elements in |Arguments| are ordered backwards (because they're on the |
12313 // stack), but the method that's called here iterates over them in forward | 12313 // stack), but the method that's called here iterates over them in forward |
12314 // direction. | 12314 // direction. |
12315 return EnsureCanContainElements( | 12315 return EnsureCanContainElements( |
12316 object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode); | 12316 object, args->arguments() - first_arg - (arg_count - 1), arg_count, mode); |
12317 } | 12317 } |
12318 | 12318 |
12319 | 12319 |
12320 MaybeHandle<AccessorPair> JSObject::GetOwnElementAccessorPair( | 12320 MaybeHandle<AccessorPair> JSObject::GetOwnElementAccessorPair( |
12321 Handle<JSObject> object, | 12321 Handle<JSObject> object, |
12322 uint32_t index) { | 12322 uint32_t index) { |
12323 if (object->IsJSGlobalProxy()) { | 12323 if (object->IsJSGlobalProxy()) { |
12324 PrototypeIterator iter(object->GetIsolate(), object); | 12324 PrototypeIterator iter(object->GetIsolate(), object); |
12325 if (iter.IsAtEnd()) return MaybeHandle<AccessorPair>(); | 12325 if (iter.IsAtEnd()) return MaybeHandle<AccessorPair>(); |
12326 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 12326 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
12327 return GetOwnElementAccessorPair( | 12327 return GetOwnElementAccessorPair( |
12328 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index); | 12328 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index); |
12329 } | 12329 } |
12330 | 12330 |
12331 // Check for lookup interceptor. | 12331 // Check for lookup interceptor. |
12332 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); | 12332 if (object->HasIndexedInterceptor()) return MaybeHandle<AccessorPair>(); |
12333 | 12333 |
12334 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); | 12334 return object->GetElementsAccessor()->GetAccessorPair(object, object, index); |
12335 } | 12335 } |
12336 | 12336 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12370 } | 12370 } |
12371 | 12371 |
12372 | 12372 |
12373 MaybeHandle<Object> JSObject::GetElementWithCallback( | 12373 MaybeHandle<Object> JSObject::GetElementWithCallback( |
12374 Handle<JSObject> object, | 12374 Handle<JSObject> object, |
12375 Handle<Object> receiver, | 12375 Handle<Object> receiver, |
12376 Handle<Object> structure, | 12376 Handle<Object> structure, |
12377 uint32_t index, | 12377 uint32_t index, |
12378 Handle<Object> holder) { | 12378 Handle<Object> holder) { |
12379 Isolate* isolate = object->GetIsolate(); | 12379 Isolate* isolate = object->GetIsolate(); |
12380 ASSERT(!structure->IsForeign()); | 12380 DCHECK(!structure->IsForeign()); |
12381 // api style callbacks. | 12381 // api style callbacks. |
12382 if (structure->IsExecutableAccessorInfo()) { | 12382 if (structure->IsExecutableAccessorInfo()) { |
12383 Handle<ExecutableAccessorInfo> data = | 12383 Handle<ExecutableAccessorInfo> data = |
12384 Handle<ExecutableAccessorInfo>::cast(structure); | 12384 Handle<ExecutableAccessorInfo>::cast(structure); |
12385 Object* fun_obj = data->getter(); | 12385 Object* fun_obj = data->getter(); |
12386 v8::AccessorGetterCallback call_fun = | 12386 v8::AccessorGetterCallback call_fun = |
12387 v8::ToCData<v8::AccessorGetterCallback>(fun_obj); | 12387 v8::ToCData<v8::AccessorGetterCallback>(fun_obj); |
12388 if (call_fun == NULL) return isolate->factory()->undefined_value(); | 12388 if (call_fun == NULL) return isolate->factory()->undefined_value(); |
12389 Handle<JSObject> holder_handle = Handle<JSObject>::cast(holder); | 12389 Handle<JSObject> holder_handle = Handle<JSObject>::cast(holder); |
12390 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12390 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12427 MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object, | 12427 MaybeHandle<Object> JSObject::SetElementWithCallback(Handle<JSObject> object, |
12428 Handle<Object> structure, | 12428 Handle<Object> structure, |
12429 uint32_t index, | 12429 uint32_t index, |
12430 Handle<Object> value, | 12430 Handle<Object> value, |
12431 Handle<JSObject> holder, | 12431 Handle<JSObject> holder, |
12432 StrictMode strict_mode) { | 12432 StrictMode strict_mode) { |
12433 Isolate* isolate = object->GetIsolate(); | 12433 Isolate* isolate = object->GetIsolate(); |
12434 | 12434 |
12435 // We should never get here to initialize a const with the hole | 12435 // We should never get here to initialize a const with the hole |
12436 // value since a const declaration would conflict with the setter. | 12436 // value since a const declaration would conflict with the setter. |
12437 ASSERT(!value->IsTheHole()); | 12437 DCHECK(!value->IsTheHole()); |
12438 ASSERT(!structure->IsForeign()); | 12438 DCHECK(!structure->IsForeign()); |
12439 if (structure->IsExecutableAccessorInfo()) { | 12439 if (structure->IsExecutableAccessorInfo()) { |
12440 // api style callbacks | 12440 // api style callbacks |
12441 Handle<ExecutableAccessorInfo> data = | 12441 Handle<ExecutableAccessorInfo> data = |
12442 Handle<ExecutableAccessorInfo>::cast(structure); | 12442 Handle<ExecutableAccessorInfo>::cast(structure); |
12443 Object* call_obj = data->setter(); | 12443 Object* call_obj = data->setter(); |
12444 v8::AccessorSetterCallback call_fun = | 12444 v8::AccessorSetterCallback call_fun = |
12445 v8::ToCData<v8::AccessorSetterCallback>(call_obj); | 12445 v8::ToCData<v8::AccessorSetterCallback>(call_obj); |
12446 if (call_fun == NULL) return value; | 12446 if (call_fun == NULL) return value; |
12447 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12447 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
12448 Handle<String> key(isolate->factory()->NumberToString(number)); | 12448 Handle<String> key(isolate->factory()->NumberToString(number)); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12505 | 12505 |
12506 | 12506 |
12507 // Adding n elements in fast case is O(n*n). | 12507 // Adding n elements in fast case is O(n*n). |
12508 // Note: revisit design to have dual undefined values to capture absent | 12508 // Note: revisit design to have dual undefined values to capture absent |
12509 // elements. | 12509 // elements. |
12510 MaybeHandle<Object> JSObject::SetFastElement(Handle<JSObject> object, | 12510 MaybeHandle<Object> JSObject::SetFastElement(Handle<JSObject> object, |
12511 uint32_t index, | 12511 uint32_t index, |
12512 Handle<Object> value, | 12512 Handle<Object> value, |
12513 StrictMode strict_mode, | 12513 StrictMode strict_mode, |
12514 bool check_prototype) { | 12514 bool check_prototype) { |
12515 ASSERT(object->HasFastSmiOrObjectElements() || | 12515 DCHECK(object->HasFastSmiOrObjectElements() || |
12516 object->HasFastArgumentsElements()); | 12516 object->HasFastArgumentsElements()); |
12517 | 12517 |
12518 Isolate* isolate = object->GetIsolate(); | 12518 Isolate* isolate = object->GetIsolate(); |
12519 | 12519 |
12520 // Array optimizations rely on the prototype lookups of Array objects always | 12520 // Array optimizations rely on the prototype lookups of Array objects always |
12521 // returning undefined. If there is a store to the initial prototype object, | 12521 // returning undefined. If there is a store to the initial prototype object, |
12522 // make sure all of these optimizations are invalidated. | 12522 // make sure all of these optimizations are invalidated. |
12523 if (isolate->is_initial_object_prototype(*object) || | 12523 if (isolate->is_initial_object_prototype(*object) || |
12524 isolate->is_initial_array_prototype(*object)) { | 12524 isolate->is_initial_array_prototype(*object)) { |
12525 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, | 12525 object->map()->dependent_code()->DeoptimizeDependentCodeGroup(isolate, |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12568 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); | 12568 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind); |
12569 TransitionElementsKind(object, transitioned_kind); | 12569 TransitionElementsKind(object, transitioned_kind); |
12570 } | 12570 } |
12571 | 12571 |
12572 // Check if the capacity of the backing store needs to be increased, or if | 12572 // Check if the capacity of the backing store needs to be increased, or if |
12573 // a transition to slow elements is necessary. | 12573 // a transition to slow elements is necessary. |
12574 if (index >= capacity) { | 12574 if (index >= capacity) { |
12575 bool convert_to_slow = true; | 12575 bool convert_to_slow = true; |
12576 if ((index - capacity) < kMaxGap) { | 12576 if ((index - capacity) < kMaxGap) { |
12577 new_capacity = NewElementsCapacity(index + 1); | 12577 new_capacity = NewElementsCapacity(index + 1); |
12578 ASSERT(new_capacity > index); | 12578 DCHECK(new_capacity > index); |
12579 if (!object->ShouldConvertToSlowElements(new_capacity)) { | 12579 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
12580 convert_to_slow = false; | 12580 convert_to_slow = false; |
12581 } | 12581 } |
12582 } | 12582 } |
12583 if (convert_to_slow) { | 12583 if (convert_to_slow) { |
12584 NormalizeElements(object); | 12584 NormalizeElements(object); |
12585 return SetDictionaryElement(object, index, value, NONE, strict_mode, | 12585 return SetDictionaryElement(object, index, value, NONE, strict_mode, |
12586 check_prototype); | 12586 check_prototype); |
12587 } | 12587 } |
12588 } | 12588 } |
(...skipping 13 matching lines...) Expand all Loading... |
12602 } | 12602 } |
12603 // Change elements kind from Smi-only to generic FAST if necessary. | 12603 // Change elements kind from Smi-only to generic FAST if necessary. |
12604 if (object->HasFastSmiElements() && !value->IsSmi()) { | 12604 if (object->HasFastSmiElements() && !value->IsSmi()) { |
12605 ElementsKind kind = object->HasFastHoleyElements() | 12605 ElementsKind kind = object->HasFastHoleyElements() |
12606 ? FAST_HOLEY_ELEMENTS | 12606 ? FAST_HOLEY_ELEMENTS |
12607 : FAST_ELEMENTS; | 12607 : FAST_ELEMENTS; |
12608 | 12608 |
12609 UpdateAllocationSite(object, kind); | 12609 UpdateAllocationSite(object, kind); |
12610 Handle<Map> new_map = GetElementsTransitionMap(object, kind); | 12610 Handle<Map> new_map = GetElementsTransitionMap(object, kind); |
12611 JSObject::MigrateToMap(object, new_map); | 12611 JSObject::MigrateToMap(object, new_map); |
12612 ASSERT(IsFastObjectElementsKind(object->GetElementsKind())); | 12612 DCHECK(IsFastObjectElementsKind(object->GetElementsKind())); |
12613 } | 12613 } |
12614 // Increase backing store capacity if that's been decided previously. | 12614 // Increase backing store capacity if that's been decided previously. |
12615 if (new_capacity != capacity) { | 12615 if (new_capacity != capacity) { |
12616 SetFastElementsCapacitySmiMode smi_mode = | 12616 SetFastElementsCapacitySmiMode smi_mode = |
12617 value->IsSmi() && object->HasFastSmiElements() | 12617 value->IsSmi() && object->HasFastSmiElements() |
12618 ? kAllowSmiElements | 12618 ? kAllowSmiElements |
12619 : kDontAllowSmiElements; | 12619 : kDontAllowSmiElements; |
12620 Handle<FixedArray> new_elements = | 12620 Handle<FixedArray> new_elements = |
12621 SetFastElementsCapacityAndLength(object, new_capacity, array_length, | 12621 SetFastElementsCapacityAndLength(object, new_capacity, array_length, |
12622 smi_mode); | 12622 smi_mode); |
12623 new_elements->set(index, *value); | 12623 new_elements->set(index, *value); |
12624 JSObject::ValidateElements(object); | 12624 JSObject::ValidateElements(object); |
12625 return value; | 12625 return value; |
12626 } | 12626 } |
12627 | 12627 |
12628 // Finally, set the new element and length. | 12628 // Finally, set the new element and length. |
12629 ASSERT(object->elements()->IsFixedArray()); | 12629 DCHECK(object->elements()->IsFixedArray()); |
12630 backing_store->set(index, *value); | 12630 backing_store->set(index, *value); |
12631 if (must_update_array_length) { | 12631 if (must_update_array_length) { |
12632 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); | 12632 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); |
12633 } | 12633 } |
12634 return value; | 12634 return value; |
12635 } | 12635 } |
12636 | 12636 |
12637 | 12637 |
12638 MaybeHandle<Object> JSObject::SetDictionaryElement( | 12638 MaybeHandle<Object> JSObject::SetDictionaryElement( |
12639 Handle<JSObject> object, | 12639 Handle<JSObject> object, |
12640 uint32_t index, | 12640 uint32_t index, |
12641 Handle<Object> value, | 12641 Handle<Object> value, |
12642 PropertyAttributes attributes, | 12642 PropertyAttributes attributes, |
12643 StrictMode strict_mode, | 12643 StrictMode strict_mode, |
12644 bool check_prototype, | 12644 bool check_prototype, |
12645 SetPropertyMode set_mode) { | 12645 SetPropertyMode set_mode) { |
12646 ASSERT(object->HasDictionaryElements() || | 12646 DCHECK(object->HasDictionaryElements() || |
12647 object->HasDictionaryArgumentsElements()); | 12647 object->HasDictionaryArgumentsElements()); |
12648 Isolate* isolate = object->GetIsolate(); | 12648 Isolate* isolate = object->GetIsolate(); |
12649 | 12649 |
12650 // Insert element in the dictionary. | 12650 // Insert element in the dictionary. |
12651 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 12651 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
12652 bool is_arguments = | 12652 bool is_arguments = |
12653 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); | 12653 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); |
12654 Handle<SeededNumberDictionary> dictionary(is_arguments | 12654 Handle<SeededNumberDictionary> dictionary(is_arguments |
12655 ? SeededNumberDictionary::cast(elements->get(1)) | 12655 ? SeededNumberDictionary::cast(elements->get(1)) |
12656 : SeededNumberDictionary::cast(*elements)); | 12656 : SeededNumberDictionary::cast(*elements)); |
(...skipping 25 matching lines...) Expand all Loading... |
12682 HandleVector(args, 2)); | 12682 HandleVector(args, 2)); |
12683 return isolate->Throw<Object>(error); | 12683 return isolate->Throw<Object>(error); |
12684 } | 12684 } |
12685 } | 12685 } |
12686 // Elements of the arguments object in slow mode might be slow aliases. | 12686 // Elements of the arguments object in slow mode might be slow aliases. |
12687 if (is_arguments && element->IsAliasedArgumentsEntry()) { | 12687 if (is_arguments && element->IsAliasedArgumentsEntry()) { |
12688 Handle<AliasedArgumentsEntry> entry = | 12688 Handle<AliasedArgumentsEntry> entry = |
12689 Handle<AliasedArgumentsEntry>::cast(element); | 12689 Handle<AliasedArgumentsEntry>::cast(element); |
12690 Handle<Context> context(Context::cast(elements->get(0))); | 12690 Handle<Context> context(Context::cast(elements->get(0))); |
12691 int context_index = entry->aliased_context_slot(); | 12691 int context_index = entry->aliased_context_slot(); |
12692 ASSERT(!context->get(context_index)->IsTheHole()); | 12692 DCHECK(!context->get(context_index)->IsTheHole()); |
12693 context->set(context_index, *value); | 12693 context->set(context_index, *value); |
12694 // For elements that are still writable we keep slow aliasing. | 12694 // For elements that are still writable we keep slow aliasing. |
12695 if (!details.IsReadOnly()) value = element; | 12695 if (!details.IsReadOnly()) value = element; |
12696 } | 12696 } |
12697 dictionary->ValueAtPut(entry, *value); | 12697 dictionary->ValueAtPut(entry, *value); |
12698 } | 12698 } |
12699 } else { | 12699 } else { |
12700 // Index not already used. Look for an accessor in the prototype chain. | 12700 // Index not already used. Look for an accessor in the prototype chain. |
12701 // Can cause GC! | 12701 // Can cause GC! |
12702 if (check_prototype) { | 12702 if (check_prototype) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12773 } | 12773 } |
12774 return value; | 12774 return value; |
12775 } | 12775 } |
12776 | 12776 |
12777 MaybeHandle<Object> JSObject::SetFastDoubleElement( | 12777 MaybeHandle<Object> JSObject::SetFastDoubleElement( |
12778 Handle<JSObject> object, | 12778 Handle<JSObject> object, |
12779 uint32_t index, | 12779 uint32_t index, |
12780 Handle<Object> value, | 12780 Handle<Object> value, |
12781 StrictMode strict_mode, | 12781 StrictMode strict_mode, |
12782 bool check_prototype) { | 12782 bool check_prototype) { |
12783 ASSERT(object->HasFastDoubleElements()); | 12783 DCHECK(object->HasFastDoubleElements()); |
12784 | 12784 |
12785 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); | 12785 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); |
12786 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); | 12786 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); |
12787 | 12787 |
12788 // If storing to an element that isn't in the array, pass the store request | 12788 // If storing to an element that isn't in the array, pass the store request |
12789 // up the prototype chain before storing in the receiver's elements. | 12789 // up the prototype chain before storing in the receiver's elements. |
12790 if (check_prototype && | 12790 if (check_prototype && |
12791 (index >= elms_length || | 12791 (index >= elms_length || |
12792 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) { | 12792 Handle<FixedDoubleArray>::cast(base_elms)->is_the_hole(index))) { |
12793 bool found; | 12793 bool found; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12846 } | 12846 } |
12847 } | 12847 } |
12848 return value; | 12848 return value; |
12849 } | 12849 } |
12850 | 12850 |
12851 // Allow gap in fast case. | 12851 // Allow gap in fast case. |
12852 if ((index - elms_length) < kMaxGap) { | 12852 if ((index - elms_length) < kMaxGap) { |
12853 // Try allocating extra space. | 12853 // Try allocating extra space. |
12854 int new_capacity = NewElementsCapacity(index+1); | 12854 int new_capacity = NewElementsCapacity(index+1); |
12855 if (!object->ShouldConvertToSlowElements(new_capacity)) { | 12855 if (!object->ShouldConvertToSlowElements(new_capacity)) { |
12856 ASSERT(static_cast<uint32_t>(new_capacity) > index); | 12856 DCHECK(static_cast<uint32_t>(new_capacity) > index); |
12857 SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1); | 12857 SetFastDoubleElementsCapacityAndLength(object, new_capacity, index + 1); |
12858 FixedDoubleArray::cast(object->elements())->set(index, double_value); | 12858 FixedDoubleArray::cast(object->elements())->set(index, double_value); |
12859 JSObject::ValidateElements(object); | 12859 JSObject::ValidateElements(object); |
12860 return value; | 12860 return value; |
12861 } | 12861 } |
12862 } | 12862 } |
12863 | 12863 |
12864 // Otherwise default to slow case. | 12864 // Otherwise default to slow case. |
12865 ASSERT(object->HasFastDoubleElements()); | 12865 DCHECK(object->HasFastDoubleElements()); |
12866 ASSERT(object->map()->has_fast_double_elements()); | 12866 DCHECK(object->map()->has_fast_double_elements()); |
12867 ASSERT(object->elements()->IsFixedDoubleArray() || | 12867 DCHECK(object->elements()->IsFixedDoubleArray() || |
12868 object->elements()->length() == 0); | 12868 object->elements()->length() == 0); |
12869 | 12869 |
12870 NormalizeElements(object); | 12870 NormalizeElements(object); |
12871 ASSERT(object->HasDictionaryElements()); | 12871 DCHECK(object->HasDictionaryElements()); |
12872 return SetElement(object, index, value, NONE, strict_mode, check_prototype); | 12872 return SetElement(object, index, value, NONE, strict_mode, check_prototype); |
12873 } | 12873 } |
12874 | 12874 |
12875 | 12875 |
12876 MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, | 12876 MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, |
12877 uint32_t index, | 12877 uint32_t index, |
12878 Handle<Object> value, | 12878 Handle<Object> value, |
12879 PropertyAttributes attributes, | 12879 PropertyAttributes attributes, |
12880 StrictMode strict_mode) { | 12880 StrictMode strict_mode) { |
12881 if (object->IsJSProxy()) { | 12881 if (object->IsJSProxy()) { |
12882 return JSProxy::SetElementWithHandler( | 12882 return JSProxy::SetElementWithHandler( |
12883 Handle<JSProxy>::cast(object), object, index, value, strict_mode); | 12883 Handle<JSProxy>::cast(object), object, index, value, strict_mode); |
12884 } | 12884 } |
12885 return JSObject::SetElement( | 12885 return JSObject::SetElement( |
12886 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); | 12886 Handle<JSObject>::cast(object), index, value, attributes, strict_mode); |
12887 } | 12887 } |
12888 | 12888 |
12889 | 12889 |
12890 MaybeHandle<Object> JSObject::SetOwnElement(Handle<JSObject> object, | 12890 MaybeHandle<Object> JSObject::SetOwnElement(Handle<JSObject> object, |
12891 uint32_t index, | 12891 uint32_t index, |
12892 Handle<Object> value, | 12892 Handle<Object> value, |
12893 StrictMode strict_mode) { | 12893 StrictMode strict_mode) { |
12894 ASSERT(!object->HasExternalArrayElements()); | 12894 DCHECK(!object->HasExternalArrayElements()); |
12895 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); | 12895 return JSObject::SetElement(object, index, value, NONE, strict_mode, false); |
12896 } | 12896 } |
12897 | 12897 |
12898 | 12898 |
12899 MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object, | 12899 MaybeHandle<Object> JSObject::SetElement(Handle<JSObject> object, |
12900 uint32_t index, | 12900 uint32_t index, |
12901 Handle<Object> value, | 12901 Handle<Object> value, |
12902 PropertyAttributes attributes, | 12902 PropertyAttributes attributes, |
12903 StrictMode strict_mode, | 12903 StrictMode strict_mode, |
12904 bool check_prototype, | 12904 bool check_prototype, |
(...skipping 14 matching lines...) Expand all Loading... |
12919 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) { | 12919 if (!isolate->MayIndexedAccess(object, index, v8::ACCESS_SET)) { |
12920 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); | 12920 isolate->ReportFailedAccessCheck(object, v8::ACCESS_SET); |
12921 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 12921 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
12922 return value; | 12922 return value; |
12923 } | 12923 } |
12924 } | 12924 } |
12925 | 12925 |
12926 if (object->IsJSGlobalProxy()) { | 12926 if (object->IsJSGlobalProxy()) { |
12927 PrototypeIterator iter(isolate, object); | 12927 PrototypeIterator iter(isolate, object); |
12928 if (iter.IsAtEnd()) return value; | 12928 if (iter.IsAtEnd()) return value; |
12929 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 12929 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
12930 return SetElement( | 12930 return SetElement( |
12931 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, | 12931 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index, |
12932 value, attributes, strict_mode, check_prototype, set_mode); | 12932 value, attributes, strict_mode, check_prototype, set_mode); |
12933 } | 12933 } |
12934 | 12934 |
12935 // Don't allow element properties to be redefined for external arrays. | 12935 // Don't allow element properties to be redefined for external arrays. |
12936 if ((object->HasExternalArrayElements() || | 12936 if ((object->HasExternalArrayElements() || |
12937 object->HasFixedTypedArrayElements()) && | 12937 object->HasFixedTypedArrayElements()) && |
12938 set_mode == DEFINE_PROPERTY) { | 12938 set_mode == DEFINE_PROPERTY) { |
12939 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); | 12939 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13036 | 13036 |
13037 | 13037 |
13038 MaybeHandle<Object> JSObject::SetElementWithoutInterceptor( | 13038 MaybeHandle<Object> JSObject::SetElementWithoutInterceptor( |
13039 Handle<JSObject> object, | 13039 Handle<JSObject> object, |
13040 uint32_t index, | 13040 uint32_t index, |
13041 Handle<Object> value, | 13041 Handle<Object> value, |
13042 PropertyAttributes attributes, | 13042 PropertyAttributes attributes, |
13043 StrictMode strict_mode, | 13043 StrictMode strict_mode, |
13044 bool check_prototype, | 13044 bool check_prototype, |
13045 SetPropertyMode set_mode) { | 13045 SetPropertyMode set_mode) { |
13046 ASSERT(object->HasDictionaryElements() || | 13046 DCHECK(object->HasDictionaryElements() || |
13047 object->HasDictionaryArgumentsElements() || | 13047 object->HasDictionaryArgumentsElements() || |
13048 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); | 13048 (attributes & (DONT_DELETE | DONT_ENUM | READ_ONLY)) == 0); |
13049 Isolate* isolate = object->GetIsolate(); | 13049 Isolate* isolate = object->GetIsolate(); |
13050 if (FLAG_trace_external_array_abuse && | 13050 if (FLAG_trace_external_array_abuse && |
13051 IsExternalArrayElementsKind(object->GetElementsKind())) { | 13051 IsExternalArrayElementsKind(object->GetElementsKind())) { |
13052 CheckArrayAbuse(object, "external elements write", index); | 13052 CheckArrayAbuse(object, "external elements write", index); |
13053 } | 13053 } |
13054 if (FLAG_trace_js_array_abuse && | 13054 if (FLAG_trace_js_array_abuse && |
13055 !IsExternalArrayElementsKind(object->GetElementsKind())) { | 13055 !IsExternalArrayElementsKind(object->GetElementsKind())) { |
13056 if (object->IsJSArray()) { | 13056 if (object->IsJSArray()) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13098 set_mode); | 13098 set_mode); |
13099 case SLOPPY_ARGUMENTS_ELEMENTS: { | 13099 case SLOPPY_ARGUMENTS_ELEMENTS: { |
13100 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); | 13100 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
13101 uint32_t length = parameter_map->length(); | 13101 uint32_t length = parameter_map->length(); |
13102 Handle<Object> probe = index < length - 2 ? | 13102 Handle<Object> probe = index < length - 2 ? |
13103 Handle<Object>(parameter_map->get(index + 2), isolate) : | 13103 Handle<Object>(parameter_map->get(index + 2), isolate) : |
13104 Handle<Object>(); | 13104 Handle<Object>(); |
13105 if (!probe.is_null() && !probe->IsTheHole()) { | 13105 if (!probe.is_null() && !probe->IsTheHole()) { |
13106 Handle<Context> context(Context::cast(parameter_map->get(0))); | 13106 Handle<Context> context(Context::cast(parameter_map->get(0))); |
13107 int context_index = Handle<Smi>::cast(probe)->value(); | 13107 int context_index = Handle<Smi>::cast(probe)->value(); |
13108 ASSERT(!context->get(context_index)->IsTheHole()); | 13108 DCHECK(!context->get(context_index)->IsTheHole()); |
13109 context->set(context_index, *value); | 13109 context->set(context_index, *value); |
13110 // Redefining attributes of an aliased element destroys fast aliasing. | 13110 // Redefining attributes of an aliased element destroys fast aliasing. |
13111 if (set_mode == SET_PROPERTY || attributes == NONE) return value; | 13111 if (set_mode == SET_PROPERTY || attributes == NONE) return value; |
13112 parameter_map->set_the_hole(index + 2); | 13112 parameter_map->set_the_hole(index + 2); |
13113 // For elements that are still writable we re-establish slow aliasing. | 13113 // For elements that are still writable we re-establish slow aliasing. |
13114 if ((attributes & READ_ONLY) == 0) { | 13114 if ((attributes & READ_ONLY) == 0) { |
13115 value = Handle<Object>::cast( | 13115 value = Handle<Object>::cast( |
13116 isolate->factory()->NewAliasedArgumentsEntry(context_index)); | 13116 isolate->factory()->NewAliasedArgumentsEntry(context_index)); |
13117 } | 13117 } |
13118 } | 13118 } |
(...skipping 27 matching lines...) Expand all Loading... |
13146 | 13146 |
13147 | 13147 |
13148 PretenureFlag AllocationSite::GetPretenureMode() { | 13148 PretenureFlag AllocationSite::GetPretenureMode() { |
13149 PretenureDecision mode = pretenure_decision(); | 13149 PretenureDecision mode = pretenure_decision(); |
13150 // Zombie objects "decide" to be untenured. | 13150 // Zombie objects "decide" to be untenured. |
13151 return mode == kTenure ? TENURED : NOT_TENURED; | 13151 return mode == kTenure ? TENURED : NOT_TENURED; |
13152 } | 13152 } |
13153 | 13153 |
13154 | 13154 |
13155 bool AllocationSite::IsNestedSite() { | 13155 bool AllocationSite::IsNestedSite() { |
13156 ASSERT(FLAG_trace_track_allocation_sites); | 13156 DCHECK(FLAG_trace_track_allocation_sites); |
13157 Object* current = GetHeap()->allocation_sites_list(); | 13157 Object* current = GetHeap()->allocation_sites_list(); |
13158 while (current->IsAllocationSite()) { | 13158 while (current->IsAllocationSite()) { |
13159 AllocationSite* current_site = AllocationSite::cast(current); | 13159 AllocationSite* current_site = AllocationSite::cast(current); |
13160 if (current_site->nested_site() == this) { | 13160 if (current_site->nested_site() == this) { |
13161 return true; | 13161 return true; |
13162 } | 13162 } |
13163 current = current_site->weak_next(); | 13163 current = current_site->weak_next(); |
13164 } | 13164 } |
13165 return false; | 13165 return false; |
13166 } | 13166 } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13279 if (IsFastElementsKind(to_kind)) { | 13279 if (IsFastElementsKind(to_kind)) { |
13280 UpdateAllocationSite(object, to_kind); | 13280 UpdateAllocationSite(object, to_kind); |
13281 } | 13281 } |
13282 | 13282 |
13283 Isolate* isolate = object->GetIsolate(); | 13283 Isolate* isolate = object->GetIsolate(); |
13284 if (object->elements() == isolate->heap()->empty_fixed_array() || | 13284 if (object->elements() == isolate->heap()->empty_fixed_array() || |
13285 (IsFastSmiOrObjectElementsKind(from_kind) && | 13285 (IsFastSmiOrObjectElementsKind(from_kind) && |
13286 IsFastSmiOrObjectElementsKind(to_kind)) || | 13286 IsFastSmiOrObjectElementsKind(to_kind)) || |
13287 (from_kind == FAST_DOUBLE_ELEMENTS && | 13287 (from_kind == FAST_DOUBLE_ELEMENTS && |
13288 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { | 13288 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { |
13289 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); | 13289 DCHECK(from_kind != TERMINAL_FAST_ELEMENTS_KIND); |
13290 // No change is needed to the elements() buffer, the transition | 13290 // No change is needed to the elements() buffer, the transition |
13291 // only requires a map change. | 13291 // only requires a map change. |
13292 Handle<Map> new_map = GetElementsTransitionMap(object, to_kind); | 13292 Handle<Map> new_map = GetElementsTransitionMap(object, to_kind); |
13293 MigrateToMap(object, new_map); | 13293 MigrateToMap(object, new_map); |
13294 if (FLAG_trace_elements_transitions) { | 13294 if (FLAG_trace_elements_transitions) { |
13295 Handle<FixedArrayBase> elms(object->elements()); | 13295 Handle<FixedArrayBase> elms(object->elements()); |
13296 PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms); | 13296 PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms); |
13297 } | 13297 } |
13298 return; | 13298 return; |
13299 } | 13299 } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13358 if (index >= old_len && index != 0xffffffff) { | 13358 if (index >= old_len && index != 0xffffffff) { |
13359 Handle<Object> len = array->GetIsolate()->factory()->NewNumber( | 13359 Handle<Object> len = array->GetIsolate()->factory()->NewNumber( |
13360 static_cast<double>(index) + 1); | 13360 static_cast<double>(index) + 1); |
13361 array->set_length(*len); | 13361 array->set_length(*len); |
13362 } | 13362 } |
13363 } | 13363 } |
13364 | 13364 |
13365 | 13365 |
13366 bool JSArray::IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map) { | 13366 bool JSArray::IsReadOnlyLengthDescriptor(Handle<Map> jsarray_map) { |
13367 Isolate* isolate = jsarray_map->GetIsolate(); | 13367 Isolate* isolate = jsarray_map->GetIsolate(); |
13368 ASSERT(!jsarray_map->is_dictionary_map()); | 13368 DCHECK(!jsarray_map->is_dictionary_map()); |
13369 LookupResult lookup(isolate); | 13369 LookupResult lookup(isolate); |
13370 Handle<Name> length_string = isolate->factory()->length_string(); | 13370 Handle<Name> length_string = isolate->factory()->length_string(); |
13371 jsarray_map->LookupDescriptor(NULL, *length_string, &lookup); | 13371 jsarray_map->LookupDescriptor(NULL, *length_string, &lookup); |
13372 return lookup.IsReadOnly(); | 13372 return lookup.IsReadOnly(); |
13373 } | 13373 } |
13374 | 13374 |
13375 | 13375 |
13376 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array, | 13376 bool JSArray::WouldChangeReadOnlyLength(Handle<JSArray> array, |
13377 uint32_t index) { | 13377 uint32_t index) { |
13378 uint32_t length = 0; | 13378 uint32_t length = 0; |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13552 int old_capacity = 0; | 13552 int old_capacity = 0; |
13553 int used_elements = 0; | 13553 int used_elements = 0; |
13554 GetElementsCapacityAndUsage(&old_capacity, &used_elements); | 13554 GetElementsCapacityAndUsage(&old_capacity, &used_elements); |
13555 int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) * | 13555 int dictionary_size = SeededNumberDictionary::ComputeCapacity(used_elements) * |
13556 SeededNumberDictionary::kEntrySize; | 13556 SeededNumberDictionary::kEntrySize; |
13557 return 3 * dictionary_size <= new_capacity; | 13557 return 3 * dictionary_size <= new_capacity; |
13558 } | 13558 } |
13559 | 13559 |
13560 | 13560 |
13561 bool JSObject::ShouldConvertToFastElements() { | 13561 bool JSObject::ShouldConvertToFastElements() { |
13562 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 13562 DCHECK(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
13563 // If the elements are sparse, we should not go back to fast case. | 13563 // If the elements are sparse, we should not go back to fast case. |
13564 if (!HasDenseElements()) return false; | 13564 if (!HasDenseElements()) return false; |
13565 // An object requiring access checks is never allowed to have fast | 13565 // An object requiring access checks is never allowed to have fast |
13566 // elements. If it had fast elements we would skip security checks. | 13566 // elements. If it had fast elements we would skip security checks. |
13567 if (IsAccessCheckNeeded()) return false; | 13567 if (IsAccessCheckNeeded()) return false; |
13568 // Observed objects may not go to fast mode because they rely on map checks, | 13568 // Observed objects may not go to fast mode because they rely on map checks, |
13569 // and for fast element accesses we sometimes check element kinds only. | 13569 // and for fast element accesses we sometimes check element kinds only. |
13570 if (map()->is_observed()) return false; | 13570 if (map()->is_observed()) return false; |
13571 | 13571 |
13572 FixedArray* elements = FixedArray::cast(this->elements()); | 13572 FixedArray* elements = FixedArray::cast(this->elements()); |
(...skipping 19 matching lines...) Expand all Loading... |
13592 SeededNumberDictionary::kEntrySize; | 13592 SeededNumberDictionary::kEntrySize; |
13593 return 2 * dictionary_size >= array_size; | 13593 return 2 * dictionary_size >= array_size; |
13594 } | 13594 } |
13595 | 13595 |
13596 | 13596 |
13597 bool JSObject::ShouldConvertToFastDoubleElements( | 13597 bool JSObject::ShouldConvertToFastDoubleElements( |
13598 bool* has_smi_only_elements) { | 13598 bool* has_smi_only_elements) { |
13599 *has_smi_only_elements = false; | 13599 *has_smi_only_elements = false; |
13600 if (HasSloppyArgumentsElements()) return false; | 13600 if (HasSloppyArgumentsElements()) return false; |
13601 if (FLAG_unbox_double_arrays) { | 13601 if (FLAG_unbox_double_arrays) { |
13602 ASSERT(HasDictionaryElements()); | 13602 DCHECK(HasDictionaryElements()); |
13603 SeededNumberDictionary* dictionary = element_dictionary(); | 13603 SeededNumberDictionary* dictionary = element_dictionary(); |
13604 bool found_double = false; | 13604 bool found_double = false; |
13605 for (int i = 0; i < dictionary->Capacity(); i++) { | 13605 for (int i = 0; i < dictionary->Capacity(); i++) { |
13606 Object* key = dictionary->KeyAt(i); | 13606 Object* key = dictionary->KeyAt(i); |
13607 if (key->IsNumber()) { | 13607 if (key->IsNumber()) { |
13608 Object* value = dictionary->ValueAt(i); | 13608 Object* value = dictionary->ValueAt(i); |
13609 if (!value->IsNumber()) return false; | 13609 if (!value->IsNumber()) return false; |
13610 if (!value->IsSmi()) { | 13610 if (!value->IsSmi()) { |
13611 found_double = true; | 13611 found_double = true; |
13612 } | 13612 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13650 int pos = 0; | 13650 int pos = 0; |
13651 int capacity = DerivedHashTable::Capacity(); | 13651 int capacity = DerivedHashTable::Capacity(); |
13652 DisallowHeapAllocation no_gc; | 13652 DisallowHeapAllocation no_gc; |
13653 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); | 13653 WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc); |
13654 for (int i = 0; i < capacity; i++) { | 13654 for (int i = 0; i < capacity; i++) { |
13655 Object* k = Dictionary::KeyAt(i); | 13655 Object* k = Dictionary::KeyAt(i); |
13656 if (Dictionary::IsKey(k)) { | 13656 if (Dictionary::IsKey(k)) { |
13657 elements->set(pos++, ValueAt(i), mode); | 13657 elements->set(pos++, ValueAt(i), mode); |
13658 } | 13658 } |
13659 } | 13659 } |
13660 ASSERT(pos == elements->length()); | 13660 DCHECK(pos == elements->length()); |
13661 } | 13661 } |
13662 | 13662 |
13663 | 13663 |
13664 InterceptorInfo* JSObject::GetNamedInterceptor() { | 13664 InterceptorInfo* JSObject::GetNamedInterceptor() { |
13665 ASSERT(map()->has_named_interceptor()); | 13665 DCHECK(map()->has_named_interceptor()); |
13666 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 13666 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
13667 ASSERT(constructor->shared()->IsApiFunction()); | 13667 DCHECK(constructor->shared()->IsApiFunction()); |
13668 Object* result = | 13668 Object* result = |
13669 constructor->shared()->get_api_func_data()->named_property_handler(); | 13669 constructor->shared()->get_api_func_data()->named_property_handler(); |
13670 return InterceptorInfo::cast(result); | 13670 return InterceptorInfo::cast(result); |
13671 } | 13671 } |
13672 | 13672 |
13673 | 13673 |
13674 InterceptorInfo* JSObject::GetIndexedInterceptor() { | 13674 InterceptorInfo* JSObject::GetIndexedInterceptor() { |
13675 ASSERT(map()->has_indexed_interceptor()); | 13675 DCHECK(map()->has_indexed_interceptor()); |
13676 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 13676 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
13677 ASSERT(constructor->shared()->IsApiFunction()); | 13677 DCHECK(constructor->shared()->IsApiFunction()); |
13678 Object* result = | 13678 Object* result = |
13679 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 13679 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
13680 return InterceptorInfo::cast(result); | 13680 return InterceptorInfo::cast(result); |
13681 } | 13681 } |
13682 | 13682 |
13683 | 13683 |
13684 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor( | 13684 MaybeHandle<Object> JSObject::GetPropertyWithInterceptor( |
13685 Handle<JSObject> holder, | 13685 Handle<JSObject> holder, |
13686 Handle<Object> receiver, | 13686 Handle<Object> receiver, |
13687 Handle<Name> name) { | 13687 Handle<Name> name) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13793 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); | 13793 isolate->ReportFailedAccessCheck(object, v8::ACCESS_HAS); |
13794 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>()); | 13794 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Maybe<bool>()); |
13795 return maybe(false); | 13795 return maybe(false); |
13796 } | 13796 } |
13797 } | 13797 } |
13798 | 13798 |
13799 if (object->IsJSGlobalProxy()) { | 13799 if (object->IsJSGlobalProxy()) { |
13800 HandleScope scope(isolate); | 13800 HandleScope scope(isolate); |
13801 PrototypeIterator iter(isolate, object); | 13801 PrototypeIterator iter(isolate, object); |
13802 if (iter.IsAtEnd()) return maybe(false); | 13802 if (iter.IsAtEnd()) return maybe(false); |
13803 ASSERT(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); | 13803 DCHECK(PrototypeIterator::GetCurrent(iter)->IsJSGlobalObject()); |
13804 return HasRealElementProperty( | 13804 return HasRealElementProperty( |
13805 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index); | 13805 Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)), index); |
13806 } | 13806 } |
13807 | 13807 |
13808 Maybe<PropertyAttributes> result = | 13808 Maybe<PropertyAttributes> result = |
13809 GetElementAttributeWithoutInterceptor(object, object, index, false); | 13809 GetElementAttributeWithoutInterceptor(object, object, index, false); |
13810 if (!result.has_value) return Maybe<bool>(); | 13810 if (!result.has_value) return Maybe<bool>(); |
13811 return maybe(result.value != ABSENT); | 13811 return maybe(result.value != ABSENT); |
13812 } | 13812 } |
13813 | 13813 |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13867 NumberToUint32(numbers->get(j)))) { | 13867 NumberToUint32(numbers->get(j)))) { |
13868 content->SwapPairs(numbers, j - 1, j); | 13868 content->SwapPairs(numbers, j - 1, j); |
13869 j--; | 13869 j--; |
13870 } | 13870 } |
13871 } | 13871 } |
13872 } | 13872 } |
13873 | 13873 |
13874 | 13874 |
13875 void HeapSortPairs(FixedArray* content, FixedArray* numbers, int len) { | 13875 void HeapSortPairs(FixedArray* content, FixedArray* numbers, int len) { |
13876 // In-place heap sort. | 13876 // In-place heap sort. |
13877 ASSERT(content->length() == numbers->length()); | 13877 DCHECK(content->length() == numbers->length()); |
13878 | 13878 |
13879 // Bottom-up max-heap construction. | 13879 // Bottom-up max-heap construction. |
13880 for (int i = 1; i < len; ++i) { | 13880 for (int i = 1; i < len; ++i) { |
13881 int child_index = i; | 13881 int child_index = i; |
13882 while (child_index > 0) { | 13882 while (child_index > 0) { |
13883 int parent_index = ((child_index + 1) >> 1) - 1; | 13883 int parent_index = ((child_index + 1) >> 1) - 1; |
13884 uint32_t parent_value = NumberToUint32(numbers->get(parent_index)); | 13884 uint32_t parent_value = NumberToUint32(numbers->get(parent_index)); |
13885 uint32_t child_value = NumberToUint32(numbers->get(child_index)); | 13885 uint32_t child_value = NumberToUint32(numbers->get(child_index)); |
13886 if (parent_value < child_value) { | 13886 if (parent_value < child_value) { |
13887 content->SwapPairs(numbers, parent_index, child_index); | 13887 content->SwapPairs(numbers, parent_index, child_index); |
(...skipping 25 matching lines...) Expand all Loading... |
13913 content->SwapPairs(numbers, parent_index, child_index + 1); | 13913 content->SwapPairs(numbers, parent_index, child_index + 1); |
13914 parent_index = child_index + 1; | 13914 parent_index = child_index + 1; |
13915 } | 13915 } |
13916 } | 13916 } |
13917 } | 13917 } |
13918 } | 13918 } |
13919 | 13919 |
13920 | 13920 |
13921 // Sort this array and the numbers as pairs wrt. the (distinct) numbers. | 13921 // Sort this array and the numbers as pairs wrt. the (distinct) numbers. |
13922 void FixedArray::SortPairs(FixedArray* numbers, uint32_t len) { | 13922 void FixedArray::SortPairs(FixedArray* numbers, uint32_t len) { |
13923 ASSERT(this->length() == numbers->length()); | 13923 DCHECK(this->length() == numbers->length()); |
13924 // For small arrays, simply use insertion sort. | 13924 // For small arrays, simply use insertion sort. |
13925 if (len <= 10) { | 13925 if (len <= 10) { |
13926 InsertionSortPairs(this, numbers, len); | 13926 InsertionSortPairs(this, numbers, len); |
13927 return; | 13927 return; |
13928 } | 13928 } |
13929 // Check the range of indices. | 13929 // Check the range of indices. |
13930 uint32_t min_index = NumberToUint32(numbers->get(0)); | 13930 uint32_t min_index = NumberToUint32(numbers->get(0)); |
13931 uint32_t max_index = min_index; | 13931 uint32_t max_index = min_index; |
13932 uint32_t i; | 13932 uint32_t i; |
13933 for (i = 1; i < len; i++) { | 13933 for (i = 1; i < len; i++) { |
(...skipping 22 matching lines...) Expand all Loading... |
13956 return; | 13956 return; |
13957 } | 13957 } |
13958 } | 13958 } |
13959 | 13959 |
13960 | 13960 |
13961 // Fill in the names of own properties into the supplied storage. The main | 13961 // Fill in the names of own properties into the supplied storage. The main |
13962 // purpose of this function is to provide reflection information for the object | 13962 // purpose of this function is to provide reflection information for the object |
13963 // mirrors. | 13963 // mirrors. |
13964 void JSObject::GetOwnPropertyNames( | 13964 void JSObject::GetOwnPropertyNames( |
13965 FixedArray* storage, int index, PropertyAttributes filter) { | 13965 FixedArray* storage, int index, PropertyAttributes filter) { |
13966 ASSERT(storage->length() >= (NumberOfOwnProperties(filter) - index)); | 13966 DCHECK(storage->length() >= (NumberOfOwnProperties(filter) - index)); |
13967 if (HasFastProperties()) { | 13967 if (HasFastProperties()) { |
13968 int real_size = map()->NumberOfOwnDescriptors(); | 13968 int real_size = map()->NumberOfOwnDescriptors(); |
13969 DescriptorArray* descs = map()->instance_descriptors(); | 13969 DescriptorArray* descs = map()->instance_descriptors(); |
13970 for (int i = 0; i < real_size; i++) { | 13970 for (int i = 0; i < real_size; i++) { |
13971 if ((descs->GetDetails(i).attributes() & filter) == 0 && | 13971 if ((descs->GetDetails(i).attributes() & filter) == 0 && |
13972 !FilterKey(descs->GetKey(i), filter)) { | 13972 !FilterKey(descs->GetKey(i), filter)) { |
13973 storage->set(index++, descs->GetKey(i)); | 13973 storage->set(index++, descs->GetKey(i)); |
13974 } | 13974 } |
13975 } | 13975 } |
13976 } else { | 13976 } else { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14013 Smi::cast(JSArray::cast(this)->length())->value() : | 14013 Smi::cast(JSArray::cast(this)->length())->value() : |
14014 FixedArray::cast(elements())->length(); | 14014 FixedArray::cast(elements())->length(); |
14015 for (int i = 0; i < length; i++) { | 14015 for (int i = 0; i < length; i++) { |
14016 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { | 14016 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { |
14017 if (storage != NULL) { | 14017 if (storage != NULL) { |
14018 storage->set(counter, Smi::FromInt(i)); | 14018 storage->set(counter, Smi::FromInt(i)); |
14019 } | 14019 } |
14020 counter++; | 14020 counter++; |
14021 } | 14021 } |
14022 } | 14022 } |
14023 ASSERT(!storage || storage->length() >= counter); | 14023 DCHECK(!storage || storage->length() >= counter); |
14024 break; | 14024 break; |
14025 } | 14025 } |
14026 case FAST_DOUBLE_ELEMENTS: | 14026 case FAST_DOUBLE_ELEMENTS: |
14027 case FAST_HOLEY_DOUBLE_ELEMENTS: { | 14027 case FAST_HOLEY_DOUBLE_ELEMENTS: { |
14028 int length = IsJSArray() ? | 14028 int length = IsJSArray() ? |
14029 Smi::cast(JSArray::cast(this)->length())->value() : | 14029 Smi::cast(JSArray::cast(this)->length())->value() : |
14030 FixedArrayBase::cast(elements())->length(); | 14030 FixedArrayBase::cast(elements())->length(); |
14031 for (int i = 0; i < length; i++) { | 14031 for (int i = 0; i < length; i++) { |
14032 if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) { | 14032 if (!FixedDoubleArray::cast(elements())->is_the_hole(i)) { |
14033 if (storage != NULL) { | 14033 if (storage != NULL) { |
14034 storage->set(counter, Smi::FromInt(i)); | 14034 storage->set(counter, Smi::FromInt(i)); |
14035 } | 14035 } |
14036 counter++; | 14036 counter++; |
14037 } | 14037 } |
14038 } | 14038 } |
14039 ASSERT(!storage || storage->length() >= counter); | 14039 DCHECK(!storage || storage->length() >= counter); |
14040 break; | 14040 break; |
14041 } | 14041 } |
14042 | 14042 |
14043 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 14043 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
14044 case EXTERNAL_##TYPE##_ELEMENTS: \ | 14044 case EXTERNAL_##TYPE##_ELEMENTS: \ |
14045 case TYPE##_ELEMENTS: \ | 14045 case TYPE##_ELEMENTS: \ |
14046 | 14046 |
14047 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 14047 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
14048 #undef TYPED_ARRAY_CASE | 14048 #undef TYPED_ARRAY_CASE |
14049 { | 14049 { |
14050 int length = FixedArrayBase::cast(elements())->length(); | 14050 int length = FixedArrayBase::cast(elements())->length(); |
14051 while (counter < length) { | 14051 while (counter < length) { |
14052 if (storage != NULL) { | 14052 if (storage != NULL) { |
14053 storage->set(counter, Smi::FromInt(counter)); | 14053 storage->set(counter, Smi::FromInt(counter)); |
14054 } | 14054 } |
14055 counter++; | 14055 counter++; |
14056 } | 14056 } |
14057 ASSERT(!storage || storage->length() >= counter); | 14057 DCHECK(!storage || storage->length() >= counter); |
14058 break; | 14058 break; |
14059 } | 14059 } |
14060 | 14060 |
14061 case DICTIONARY_ELEMENTS: { | 14061 case DICTIONARY_ELEMENTS: { |
14062 if (storage != NULL) { | 14062 if (storage != NULL) { |
14063 element_dictionary()->CopyKeysTo(storage, | 14063 element_dictionary()->CopyKeysTo(storage, |
14064 filter, | 14064 filter, |
14065 SeededNumberDictionary::SORTED); | 14065 SeededNumberDictionary::SORTED); |
14066 } | 14066 } |
14067 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); | 14067 counter += element_dictionary()->NumberOfElementsFilterAttributes(filter); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14115 if (val->IsString()) { | 14115 if (val->IsString()) { |
14116 String* str = String::cast(val); | 14116 String* str = String::cast(val); |
14117 if (storage) { | 14117 if (storage) { |
14118 for (int i = 0; i < str->length(); i++) { | 14118 for (int i = 0; i < str->length(); i++) { |
14119 storage->set(counter + i, Smi::FromInt(i)); | 14119 storage->set(counter + i, Smi::FromInt(i)); |
14120 } | 14120 } |
14121 } | 14121 } |
14122 counter += str->length(); | 14122 counter += str->length(); |
14123 } | 14123 } |
14124 } | 14124 } |
14125 ASSERT(!storage || storage->length() == counter); | 14125 DCHECK(!storage || storage->length() == counter); |
14126 return counter; | 14126 return counter; |
14127 } | 14127 } |
14128 | 14128 |
14129 | 14129 |
14130 int JSObject::GetEnumElementKeys(FixedArray* storage) { | 14130 int JSObject::GetEnumElementKeys(FixedArray* storage) { |
14131 return GetOwnElementKeys(storage, static_cast<PropertyAttributes>(DONT_ENUM)); | 14131 return GetOwnElementKeys(storage, static_cast<PropertyAttributes>(DONT_ENUM)); |
14132 } | 14132 } |
14133 | 14133 |
14134 | 14134 |
14135 // StringSharedKeys are used as keys in the eval cache. | 14135 // StringSharedKeys are used as keys in the eval cache. |
14136 class StringSharedKey : public HashTableKey { | 14136 class StringSharedKey : public HashTableKey { |
14137 public: | 14137 public: |
14138 StringSharedKey(Handle<String> source, | 14138 StringSharedKey(Handle<String> source, |
14139 Handle<SharedFunctionInfo> shared, | 14139 Handle<SharedFunctionInfo> shared, |
14140 StrictMode strict_mode, | 14140 StrictMode strict_mode, |
14141 int scope_position) | 14141 int scope_position) |
14142 : source_(source), | 14142 : source_(source), |
14143 shared_(shared), | 14143 shared_(shared), |
14144 strict_mode_(strict_mode), | 14144 strict_mode_(strict_mode), |
14145 scope_position_(scope_position) { } | 14145 scope_position_(scope_position) { } |
14146 | 14146 |
14147 bool IsMatch(Object* other) V8_OVERRIDE { | 14147 bool IsMatch(Object* other) V8_OVERRIDE { |
14148 DisallowHeapAllocation no_allocation; | 14148 DisallowHeapAllocation no_allocation; |
14149 if (!other->IsFixedArray()) return false; | 14149 if (!other->IsFixedArray()) return false; |
14150 FixedArray* other_array = FixedArray::cast(other); | 14150 FixedArray* other_array = FixedArray::cast(other); |
14151 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 14151 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
14152 if (shared != *shared_) return false; | 14152 if (shared != *shared_) return false; |
14153 int strict_unchecked = Smi::cast(other_array->get(2))->value(); | 14153 int strict_unchecked = Smi::cast(other_array->get(2))->value(); |
14154 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); | 14154 DCHECK(strict_unchecked == SLOPPY || strict_unchecked == STRICT); |
14155 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); | 14155 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); |
14156 if (strict_mode != strict_mode_) return false; | 14156 if (strict_mode != strict_mode_) return false; |
14157 int scope_position = Smi::cast(other_array->get(3))->value(); | 14157 int scope_position = Smi::cast(other_array->get(3))->value(); |
14158 if (scope_position != scope_position_) return false; | 14158 if (scope_position != scope_position_) return false; |
14159 String* source = String::cast(other_array->get(1)); | 14159 String* source = String::cast(other_array->get(1)); |
14160 return source->Equals(*source_); | 14160 return source->Equals(*source_); |
14161 } | 14161 } |
14162 | 14162 |
14163 static uint32_t StringSharedHashHelper(String* source, | 14163 static uint32_t StringSharedHashHelper(String* source, |
14164 SharedFunctionInfo* shared, | 14164 SharedFunctionInfo* shared, |
(...skipping 18 matching lines...) Expand all Loading... |
14183 return StringSharedHashHelper(*source_, *shared_, strict_mode_, | 14183 return StringSharedHashHelper(*source_, *shared_, strict_mode_, |
14184 scope_position_); | 14184 scope_position_); |
14185 } | 14185 } |
14186 | 14186 |
14187 uint32_t HashForObject(Object* obj) V8_OVERRIDE { | 14187 uint32_t HashForObject(Object* obj) V8_OVERRIDE { |
14188 DisallowHeapAllocation no_allocation; | 14188 DisallowHeapAllocation no_allocation; |
14189 FixedArray* other_array = FixedArray::cast(obj); | 14189 FixedArray* other_array = FixedArray::cast(obj); |
14190 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); | 14190 SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0)); |
14191 String* source = String::cast(other_array->get(1)); | 14191 String* source = String::cast(other_array->get(1)); |
14192 int strict_unchecked = Smi::cast(other_array->get(2))->value(); | 14192 int strict_unchecked = Smi::cast(other_array->get(2))->value(); |
14193 ASSERT(strict_unchecked == SLOPPY || strict_unchecked == STRICT); | 14193 DCHECK(strict_unchecked == SLOPPY || strict_unchecked == STRICT); |
14194 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); | 14194 StrictMode strict_mode = static_cast<StrictMode>(strict_unchecked); |
14195 int scope_position = Smi::cast(other_array->get(3))->value(); | 14195 int scope_position = Smi::cast(other_array->get(3))->value(); |
14196 return StringSharedHashHelper( | 14196 return StringSharedHashHelper( |
14197 source, shared, strict_mode, scope_position); | 14197 source, shared, strict_mode, scope_position); |
14198 } | 14198 } |
14199 | 14199 |
14200 | 14200 |
14201 Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { | 14201 Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { |
14202 Handle<FixedArray> array = isolate->factory()->NewFixedArray(4); | 14202 Handle<FixedArray> array = isolate->factory()->NewFixedArray(4); |
14203 array->set(0, *shared_); | 14203 array->set(0, *shared_); |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14334 return String::cast(other)->Hash(); | 14334 return String::cast(other)->Hash(); |
14335 } | 14335 } |
14336 | 14336 |
14337 virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { | 14337 virtual Handle<Object> AsHandle(Isolate* isolate) V8_OVERRIDE { |
14338 // Internalize the string if possible. | 14338 // Internalize the string if possible. |
14339 MaybeHandle<Map> maybe_map = | 14339 MaybeHandle<Map> maybe_map = |
14340 isolate->factory()->InternalizedStringMapForString(string_); | 14340 isolate->factory()->InternalizedStringMapForString(string_); |
14341 Handle<Map> map; | 14341 Handle<Map> map; |
14342 if (maybe_map.ToHandle(&map)) { | 14342 if (maybe_map.ToHandle(&map)) { |
14343 string_->set_map_no_write_barrier(*map); | 14343 string_->set_map_no_write_barrier(*map); |
14344 ASSERT(string_->IsInternalizedString()); | 14344 DCHECK(string_->IsInternalizedString()); |
14345 return string_; | 14345 return string_; |
14346 } | 14346 } |
14347 // Otherwise allocate a new internalized string. | 14347 // Otherwise allocate a new internalized string. |
14348 return isolate->factory()->NewInternalizedStringImpl( | 14348 return isolate->factory()->NewInternalizedStringImpl( |
14349 string_, string_->length(), string_->hash_field()); | 14349 string_, string_->length(), string_->hash_field()); |
14350 } | 14350 } |
14351 | 14351 |
14352 static uint32_t StringHash(Object* obj) { | 14352 static uint32_t StringHash(Object* obj) { |
14353 return String::cast(obj)->Hash(); | 14353 return String::cast(obj)->Hash(); |
14354 } | 14354 } |
(...skipping 15 matching lines...) Expand all Loading... |
14370 kHeaderSize + length() * kPointerSize); | 14370 kHeaderSize + length() * kPointerSize); |
14371 } | 14371 } |
14372 | 14372 |
14373 | 14373 |
14374 template<typename Derived, typename Shape, typename Key> | 14374 template<typename Derived, typename Shape, typename Key> |
14375 Handle<Derived> HashTable<Derived, Shape, Key>::New( | 14375 Handle<Derived> HashTable<Derived, Shape, Key>::New( |
14376 Isolate* isolate, | 14376 Isolate* isolate, |
14377 int at_least_space_for, | 14377 int at_least_space_for, |
14378 MinimumCapacity capacity_option, | 14378 MinimumCapacity capacity_option, |
14379 PretenureFlag pretenure) { | 14379 PretenureFlag pretenure) { |
14380 ASSERT(0 <= at_least_space_for); | 14380 DCHECK(0 <= at_least_space_for); |
14381 ASSERT(!capacity_option || IsPowerOf2(at_least_space_for)); | 14381 DCHECK(!capacity_option || IsPowerOf2(at_least_space_for)); |
14382 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) | 14382 int capacity = (capacity_option == USE_CUSTOM_MINIMUM_CAPACITY) |
14383 ? at_least_space_for | 14383 ? at_least_space_for |
14384 : ComputeCapacity(at_least_space_for); | 14384 : ComputeCapacity(at_least_space_for); |
14385 if (capacity > HashTable::kMaxCapacity) { | 14385 if (capacity > HashTable::kMaxCapacity) { |
14386 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); | 14386 v8::internal::Heap::FatalProcessOutOfMemory("invalid table size", true); |
14387 } | 14387 } |
14388 | 14388 |
14389 Factory* factory = isolate->factory(); | 14389 Factory* factory = isolate->factory(); |
14390 int length = EntryToIndex(capacity); | 14390 int length = EntryToIndex(capacity); |
14391 Handle<FixedArray> array = factory->NewFixedArray(length, pretenure); | 14391 Handle<FixedArray> array = factory->NewFixedArray(length, pretenure); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14425 if (element->IsUndefined()) break; // Empty entry. | 14425 if (element->IsUndefined()) break; // Empty entry. |
14426 if (*key == element) return entry; | 14426 if (*key == element) return entry; |
14427 if (!element->IsUniqueName() && | 14427 if (!element->IsUniqueName() && |
14428 !element->IsTheHole() && | 14428 !element->IsTheHole() && |
14429 Name::cast(element)->Equals(*key)) { | 14429 Name::cast(element)->Equals(*key)) { |
14430 // Replace a key that is a non-internalized string by the equivalent | 14430 // Replace a key that is a non-internalized string by the equivalent |
14431 // internalized string for faster further lookups. | 14431 // internalized string for faster further lookups. |
14432 set(index, *key); | 14432 set(index, *key); |
14433 return entry; | 14433 return entry; |
14434 } | 14434 } |
14435 ASSERT(element->IsTheHole() || !Name::cast(element)->Equals(*key)); | 14435 DCHECK(element->IsTheHole() || !Name::cast(element)->Equals(*key)); |
14436 entry = NextProbe(entry, count++, capacity); | 14436 entry = NextProbe(entry, count++, capacity); |
14437 } | 14437 } |
14438 return kNotFound; | 14438 return kNotFound; |
14439 } | 14439 } |
14440 | 14440 |
14441 | 14441 |
14442 template<typename Derived, typename Shape, typename Key> | 14442 template<typename Derived, typename Shape, typename Key> |
14443 void HashTable<Derived, Shape, Key>::Rehash( | 14443 void HashTable<Derived, Shape, Key>::Rehash( |
14444 Handle<Derived> new_table, | 14444 Handle<Derived> new_table, |
14445 Key key) { | 14445 Key key) { |
14446 ASSERT(NumberOfElements() < new_table->Capacity()); | 14446 DCHECK(NumberOfElements() < new_table->Capacity()); |
14447 | 14447 |
14448 DisallowHeapAllocation no_gc; | 14448 DisallowHeapAllocation no_gc; |
14449 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); | 14449 WriteBarrierMode mode = new_table->GetWriteBarrierMode(no_gc); |
14450 | 14450 |
14451 // Copy prefix to new array. | 14451 // Copy prefix to new array. |
14452 for (int i = kPrefixStartIndex; | 14452 for (int i = kPrefixStartIndex; |
14453 i < kPrefixStartIndex + Shape::kPrefixSize; | 14453 i < kPrefixStartIndex + Shape::kPrefixSize; |
14454 i++) { | 14454 i++) { |
14455 new_table->set(i, get(i), mode); | 14455 new_table->set(i, get(i), mode); |
14456 } | 14456 } |
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14765 int Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: | 14765 int Dictionary<NameDictionary, NameDictionaryShape, Handle<Name> >:: |
14766 NumberOfEnumElements(); | 14766 NumberOfEnumElements(); |
14767 | 14767 |
14768 template | 14768 template |
14769 int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: | 14769 int HashTable<SeededNumberDictionary, SeededNumberDictionaryShape, uint32_t>:: |
14770 FindEntry(uint32_t); | 14770 FindEntry(uint32_t); |
14771 | 14771 |
14772 | 14772 |
14773 Handle<Object> JSObject::PrepareSlowElementsForSort( | 14773 Handle<Object> JSObject::PrepareSlowElementsForSort( |
14774 Handle<JSObject> object, uint32_t limit) { | 14774 Handle<JSObject> object, uint32_t limit) { |
14775 ASSERT(object->HasDictionaryElements()); | 14775 DCHECK(object->HasDictionaryElements()); |
14776 Isolate* isolate = object->GetIsolate(); | 14776 Isolate* isolate = object->GetIsolate(); |
14777 // Must stay in dictionary mode, either because of requires_slow_elements, | 14777 // Must stay in dictionary mode, either because of requires_slow_elements, |
14778 // or because we are not going to sort (and therefore compact) all of the | 14778 // or because we are not going to sort (and therefore compact) all of the |
14779 // elements. | 14779 // elements. |
14780 Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate); | 14780 Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate); |
14781 Handle<SeededNumberDictionary> new_dict = | 14781 Handle<SeededNumberDictionary> new_dict = |
14782 SeededNumberDictionary::New(isolate, dict->NumberOfElements()); | 14782 SeededNumberDictionary::New(isolate, dict->NumberOfElements()); |
14783 | 14783 |
14784 uint32_t pos = 0; | 14784 uint32_t pos = 0; |
14785 uint32_t undefs = 0; | 14785 uint32_t undefs = 0; |
14786 int capacity = dict->Capacity(); | 14786 int capacity = dict->Capacity(); |
14787 Handle<Smi> bailout(Smi::FromInt(-1), isolate); | 14787 Handle<Smi> bailout(Smi::FromInt(-1), isolate); |
14788 // Entry to the new dictionary does not cause it to grow, as we have | 14788 // Entry to the new dictionary does not cause it to grow, as we have |
14789 // allocated one that is large enough for all entries. | 14789 // allocated one that is large enough for all entries. |
14790 DisallowHeapAllocation no_gc; | 14790 DisallowHeapAllocation no_gc; |
14791 for (int i = 0; i < capacity; i++) { | 14791 for (int i = 0; i < capacity; i++) { |
14792 Object* k = dict->KeyAt(i); | 14792 Object* k = dict->KeyAt(i); |
14793 if (!dict->IsKey(k)) continue; | 14793 if (!dict->IsKey(k)) continue; |
14794 | 14794 |
14795 ASSERT(k->IsNumber()); | 14795 DCHECK(k->IsNumber()); |
14796 ASSERT(!k->IsSmi() || Smi::cast(k)->value() >= 0); | 14796 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0); |
14797 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); | 14797 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); |
14798 ASSERT(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); | 14798 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); |
14799 | 14799 |
14800 HandleScope scope(isolate); | 14800 HandleScope scope(isolate); |
14801 Handle<Object> value(dict->ValueAt(i), isolate); | 14801 Handle<Object> value(dict->ValueAt(i), isolate); |
14802 PropertyDetails details = dict->DetailsAt(i); | 14802 PropertyDetails details = dict->DetailsAt(i); |
14803 if (details.type() == CALLBACKS || details.IsReadOnly()) { | 14803 if (details.type() == CALLBACKS || details.IsReadOnly()) { |
14804 // Bail out and do the sorting of undefineds and array holes in JS. | 14804 // Bail out and do the sorting of undefineds and array holes in JS. |
14805 // Also bail out if the element is not supposed to be moved. | 14805 // Also bail out if the element is not supposed to be moved. |
14806 return bailout; | 14806 return bailout; |
14807 } | 14807 } |
14808 | 14808 |
14809 uint32_t key = NumberToUint32(k); | 14809 uint32_t key = NumberToUint32(k); |
14810 if (key < limit) { | 14810 if (key < limit) { |
14811 if (value->IsUndefined()) { | 14811 if (value->IsUndefined()) { |
14812 undefs++; | 14812 undefs++; |
14813 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { | 14813 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
14814 // Adding an entry with the key beyond smi-range requires | 14814 // Adding an entry with the key beyond smi-range requires |
14815 // allocation. Bailout. | 14815 // allocation. Bailout. |
14816 return bailout; | 14816 return bailout; |
14817 } else { | 14817 } else { |
14818 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( | 14818 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
14819 new_dict, pos, value, details); | 14819 new_dict, pos, value, details); |
14820 ASSERT(result.is_identical_to(new_dict)); | 14820 DCHECK(result.is_identical_to(new_dict)); |
14821 USE(result); | 14821 USE(result); |
14822 pos++; | 14822 pos++; |
14823 } | 14823 } |
14824 } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) { | 14824 } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) { |
14825 // Adding an entry with the key beyond smi-range requires | 14825 // Adding an entry with the key beyond smi-range requires |
14826 // allocation. Bailout. | 14826 // allocation. Bailout. |
14827 return bailout; | 14827 return bailout; |
14828 } else { | 14828 } else { |
14829 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( | 14829 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
14830 new_dict, key, value, details); | 14830 new_dict, key, value, details); |
14831 ASSERT(result.is_identical_to(new_dict)); | 14831 DCHECK(result.is_identical_to(new_dict)); |
14832 USE(result); | 14832 USE(result); |
14833 } | 14833 } |
14834 } | 14834 } |
14835 | 14835 |
14836 uint32_t result = pos; | 14836 uint32_t result = pos; |
14837 PropertyDetails no_details = PropertyDetails(NONE, NORMAL, 0); | 14837 PropertyDetails no_details = PropertyDetails(NONE, NORMAL, 0); |
14838 while (undefs > 0) { | 14838 while (undefs > 0) { |
14839 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { | 14839 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
14840 // Adding an entry with the key beyond smi-range requires | 14840 // Adding an entry with the key beyond smi-range requires |
14841 // allocation. Bailout. | 14841 // allocation. Bailout. |
14842 return bailout; | 14842 return bailout; |
14843 } | 14843 } |
14844 HandleScope scope(isolate); | 14844 HandleScope scope(isolate); |
14845 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( | 14845 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( |
14846 new_dict, pos, isolate->factory()->undefined_value(), no_details); | 14846 new_dict, pos, isolate->factory()->undefined_value(), no_details); |
14847 ASSERT(result.is_identical_to(new_dict)); | 14847 DCHECK(result.is_identical_to(new_dict)); |
14848 USE(result); | 14848 USE(result); |
14849 pos++; | 14849 pos++; |
14850 undefs--; | 14850 undefs--; |
14851 } | 14851 } |
14852 | 14852 |
14853 object->set_elements(*new_dict); | 14853 object->set_elements(*new_dict); |
14854 | 14854 |
14855 AllowHeapAllocation allocate_return_value; | 14855 AllowHeapAllocation allocate_return_value; |
14856 return isolate->factory()->NewNumberFromUint(result); | 14856 return isolate->factory()->NewNumberFromUint(result); |
14857 } | 14857 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14891 | 14891 |
14892 JSObject::SetMapAndElements(object, new_map, fast_elements); | 14892 JSObject::SetMapAndElements(object, new_map, fast_elements); |
14893 } else if (object->HasExternalArrayElements() || | 14893 } else if (object->HasExternalArrayElements() || |
14894 object->HasFixedTypedArrayElements()) { | 14894 object->HasFixedTypedArrayElements()) { |
14895 // Typed arrays cannot have holes or undefined elements. | 14895 // Typed arrays cannot have holes or undefined elements. |
14896 return handle(Smi::FromInt( | 14896 return handle(Smi::FromInt( |
14897 FixedArrayBase::cast(object->elements())->length()), isolate); | 14897 FixedArrayBase::cast(object->elements())->length()), isolate); |
14898 } else if (!object->HasFastDoubleElements()) { | 14898 } else if (!object->HasFastDoubleElements()) { |
14899 EnsureWritableFastElements(object); | 14899 EnsureWritableFastElements(object); |
14900 } | 14900 } |
14901 ASSERT(object->HasFastSmiOrObjectElements() || | 14901 DCHECK(object->HasFastSmiOrObjectElements() || |
14902 object->HasFastDoubleElements()); | 14902 object->HasFastDoubleElements()); |
14903 | 14903 |
14904 // Collect holes at the end, undefined before that and the rest at the | 14904 // Collect holes at the end, undefined before that and the rest at the |
14905 // start, and return the number of non-hole, non-undefined values. | 14905 // start, and return the number of non-hole, non-undefined values. |
14906 | 14906 |
14907 Handle<FixedArrayBase> elements_base(object->elements()); | 14907 Handle<FixedArrayBase> elements_base(object->elements()); |
14908 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); | 14908 uint32_t elements_length = static_cast<uint32_t>(elements_base->length()); |
14909 if (limit > elements_length) { | 14909 if (limit > elements_length) { |
14910 limit = elements_length ; | 14910 limit = elements_length ; |
14911 } | 14911 } |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15047 } else if (double_value > 255) { | 15047 } else if (double_value > 255) { |
15048 // Greater than 255 clamp to 255. | 15048 // Greater than 255 clamp to 255. |
15049 clamped_value = 255; | 15049 clamped_value = 255; |
15050 } else { | 15050 } else { |
15051 // Other doubles are rounded to the nearest integer. | 15051 // Other doubles are rounded to the nearest integer. |
15052 clamped_value = static_cast<uint8_t>(lrint(double_value)); | 15052 clamped_value = static_cast<uint8_t>(lrint(double_value)); |
15053 } | 15053 } |
15054 } else { | 15054 } else { |
15055 // Clamp undefined to zero (default). All other types have been | 15055 // Clamp undefined to zero (default). All other types have been |
15056 // converted to a number type further up in the call chain. | 15056 // converted to a number type further up in the call chain. |
15057 ASSERT(value->IsUndefined()); | 15057 DCHECK(value->IsUndefined()); |
15058 } | 15058 } |
15059 array->set(index, clamped_value); | 15059 array->set(index, clamped_value); |
15060 } | 15060 } |
15061 return handle(Smi::FromInt(clamped_value), array->GetIsolate()); | 15061 return handle(Smi::FromInt(clamped_value), array->GetIsolate()); |
15062 } | 15062 } |
15063 | 15063 |
15064 | 15064 |
15065 template<typename ExternalArrayClass, typename ValueType> | 15065 template<typename ExternalArrayClass, typename ValueType> |
15066 static Handle<Object> ExternalArrayIntSetter( | 15066 static Handle<Object> ExternalArrayIntSetter( |
15067 Isolate* isolate, | 15067 Isolate* isolate, |
15068 Handle<ExternalArrayClass> receiver, | 15068 Handle<ExternalArrayClass> receiver, |
15069 uint32_t index, | 15069 uint32_t index, |
15070 Handle<Object> value) { | 15070 Handle<Object> value) { |
15071 ValueType cast_value = 0; | 15071 ValueType cast_value = 0; |
15072 if (index < static_cast<uint32_t>(receiver->length())) { | 15072 if (index < static_cast<uint32_t>(receiver->length())) { |
15073 if (value->IsSmi()) { | 15073 if (value->IsSmi()) { |
15074 int int_value = Handle<Smi>::cast(value)->value(); | 15074 int int_value = Handle<Smi>::cast(value)->value(); |
15075 cast_value = static_cast<ValueType>(int_value); | 15075 cast_value = static_cast<ValueType>(int_value); |
15076 } else if (value->IsHeapNumber()) { | 15076 } else if (value->IsHeapNumber()) { |
15077 double double_value = Handle<HeapNumber>::cast(value)->value(); | 15077 double double_value = Handle<HeapNumber>::cast(value)->value(); |
15078 cast_value = static_cast<ValueType>(DoubleToInt32(double_value)); | 15078 cast_value = static_cast<ValueType>(DoubleToInt32(double_value)); |
15079 } else { | 15079 } else { |
15080 // Clamp undefined to zero (default). All other types have been | 15080 // Clamp undefined to zero (default). All other types have been |
15081 // converted to a number type further up in the call chain. | 15081 // converted to a number type further up in the call chain. |
15082 ASSERT(value->IsUndefined()); | 15082 DCHECK(value->IsUndefined()); |
15083 } | 15083 } |
15084 receiver->set(index, cast_value); | 15084 receiver->set(index, cast_value); |
15085 } | 15085 } |
15086 return isolate->factory()->NewNumberFromInt(cast_value); | 15086 return isolate->factory()->NewNumberFromInt(cast_value); |
15087 } | 15087 } |
15088 | 15088 |
15089 | 15089 |
15090 Handle<Object> ExternalInt8Array::SetValue(Handle<ExternalInt8Array> array, | 15090 Handle<Object> ExternalInt8Array::SetValue(Handle<ExternalInt8Array> array, |
15091 uint32_t index, | 15091 uint32_t index, |
15092 Handle<Object> value) { | 15092 Handle<Object> value) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15135 if (index < static_cast<uint32_t>(array->length())) { | 15135 if (index < static_cast<uint32_t>(array->length())) { |
15136 if (value->IsSmi()) { | 15136 if (value->IsSmi()) { |
15137 int int_value = Handle<Smi>::cast(value)->value(); | 15137 int int_value = Handle<Smi>::cast(value)->value(); |
15138 cast_value = static_cast<uint32_t>(int_value); | 15138 cast_value = static_cast<uint32_t>(int_value); |
15139 } else if (value->IsHeapNumber()) { | 15139 } else if (value->IsHeapNumber()) { |
15140 double double_value = Handle<HeapNumber>::cast(value)->value(); | 15140 double double_value = Handle<HeapNumber>::cast(value)->value(); |
15141 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); | 15141 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); |
15142 } else { | 15142 } else { |
15143 // Clamp undefined to zero (default). All other types have been | 15143 // Clamp undefined to zero (default). All other types have been |
15144 // converted to a number type further up in the call chain. | 15144 // converted to a number type further up in the call chain. |
15145 ASSERT(value->IsUndefined()); | 15145 DCHECK(value->IsUndefined()); |
15146 } | 15146 } |
15147 array->set(index, cast_value); | 15147 array->set(index, cast_value); |
15148 } | 15148 } |
15149 return array->GetIsolate()->factory()->NewNumberFromUint(cast_value); | 15149 return array->GetIsolate()->factory()->NewNumberFromUint(cast_value); |
15150 } | 15150 } |
15151 | 15151 |
15152 | 15152 |
15153 Handle<Object> ExternalFloat32Array::SetValue( | 15153 Handle<Object> ExternalFloat32Array::SetValue( |
15154 Handle<ExternalFloat32Array> array, | 15154 Handle<ExternalFloat32Array> array, |
15155 uint32_t index, | 15155 uint32_t index, |
15156 Handle<Object> value) { | 15156 Handle<Object> value) { |
15157 float cast_value = static_cast<float>(base::OS::nan_value()); | 15157 float cast_value = static_cast<float>(base::OS::nan_value()); |
15158 if (index < static_cast<uint32_t>(array->length())) { | 15158 if (index < static_cast<uint32_t>(array->length())) { |
15159 if (value->IsSmi()) { | 15159 if (value->IsSmi()) { |
15160 int int_value = Handle<Smi>::cast(value)->value(); | 15160 int int_value = Handle<Smi>::cast(value)->value(); |
15161 cast_value = static_cast<float>(int_value); | 15161 cast_value = static_cast<float>(int_value); |
15162 } else if (value->IsHeapNumber()) { | 15162 } else if (value->IsHeapNumber()) { |
15163 double double_value = Handle<HeapNumber>::cast(value)->value(); | 15163 double double_value = Handle<HeapNumber>::cast(value)->value(); |
15164 cast_value = static_cast<float>(double_value); | 15164 cast_value = static_cast<float>(double_value); |
15165 } else { | 15165 } else { |
15166 // Clamp undefined to NaN (default). All other types have been | 15166 // Clamp undefined to NaN (default). All other types have been |
15167 // converted to a number type further up in the call chain. | 15167 // converted to a number type further up in the call chain. |
15168 ASSERT(value->IsUndefined()); | 15168 DCHECK(value->IsUndefined()); |
15169 } | 15169 } |
15170 array->set(index, cast_value); | 15170 array->set(index, cast_value); |
15171 } | 15171 } |
15172 return array->GetIsolate()->factory()->NewNumber(cast_value); | 15172 return array->GetIsolate()->factory()->NewNumber(cast_value); |
15173 } | 15173 } |
15174 | 15174 |
15175 | 15175 |
15176 Handle<Object> ExternalFloat64Array::SetValue( | 15176 Handle<Object> ExternalFloat64Array::SetValue( |
15177 Handle<ExternalFloat64Array> array, | 15177 Handle<ExternalFloat64Array> array, |
15178 uint32_t index, | 15178 uint32_t index, |
15179 Handle<Object> value) { | 15179 Handle<Object> value) { |
15180 double double_value = base::OS::nan_value(); | 15180 double double_value = base::OS::nan_value(); |
15181 if (index < static_cast<uint32_t>(array->length())) { | 15181 if (index < static_cast<uint32_t>(array->length())) { |
15182 if (value->IsNumber()) { | 15182 if (value->IsNumber()) { |
15183 double_value = value->Number(); | 15183 double_value = value->Number(); |
15184 } else { | 15184 } else { |
15185 // Clamp undefined to NaN (default). All other types have been | 15185 // Clamp undefined to NaN (default). All other types have been |
15186 // converted to a number type further up in the call chain. | 15186 // converted to a number type further up in the call chain. |
15187 ASSERT(value->IsUndefined()); | 15187 DCHECK(value->IsUndefined()); |
15188 } | 15188 } |
15189 array->set(index, double_value); | 15189 array->set(index, double_value); |
15190 } | 15190 } |
15191 return array->GetIsolate()->factory()->NewNumber(double_value); | 15191 return array->GetIsolate()->factory()->NewNumber(double_value); |
15192 } | 15192 } |
15193 | 15193 |
15194 | 15194 |
15195 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { | 15195 PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { |
15196 ASSERT(!HasFastProperties()); | 15196 DCHECK(!HasFastProperties()); |
15197 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 15197 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
15198 return PropertyCell::cast(value); | 15198 return PropertyCell::cast(value); |
15199 } | 15199 } |
15200 | 15200 |
15201 | 15201 |
15202 Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell( | 15202 Handle<PropertyCell> JSGlobalObject::EnsurePropertyCell( |
15203 Handle<JSGlobalObject> global, | 15203 Handle<JSGlobalObject> global, |
15204 Handle<Name> name) { | 15204 Handle<Name> name) { |
15205 ASSERT(!global->HasFastProperties()); | 15205 DCHECK(!global->HasFastProperties()); |
15206 int entry = global->property_dictionary()->FindEntry(name); | 15206 int entry = global->property_dictionary()->FindEntry(name); |
15207 if (entry == NameDictionary::kNotFound) { | 15207 if (entry == NameDictionary::kNotFound) { |
15208 Isolate* isolate = global->GetIsolate(); | 15208 Isolate* isolate = global->GetIsolate(); |
15209 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell( | 15209 Handle<PropertyCell> cell = isolate->factory()->NewPropertyCell( |
15210 isolate->factory()->the_hole_value()); | 15210 isolate->factory()->the_hole_value()); |
15211 PropertyDetails details(NONE, NORMAL, 0); | 15211 PropertyDetails details(NONE, NORMAL, 0); |
15212 details = details.AsDeleted(); | 15212 details = details.AsDeleted(); |
15213 Handle<NameDictionary> dictionary = NameDictionary::Add( | 15213 Handle<NameDictionary> dictionary = NameDictionary::Add( |
15214 handle(global->property_dictionary()), name, cell, details); | 15214 handle(global->property_dictionary()), name, cell, details); |
15215 global->set_properties(*dictionary); | 15215 global->set_properties(*dictionary); |
15216 return cell; | 15216 return cell; |
15217 } else { | 15217 } else { |
15218 Object* value = global->property_dictionary()->ValueAt(entry); | 15218 Object* value = global->property_dictionary()->ValueAt(entry); |
15219 ASSERT(value->IsPropertyCell()); | 15219 DCHECK(value->IsPropertyCell()); |
15220 return handle(PropertyCell::cast(value)); | 15220 return handle(PropertyCell::cast(value)); |
15221 } | 15221 } |
15222 } | 15222 } |
15223 | 15223 |
15224 | 15224 |
15225 // This class is used for looking up two character strings in the string table. | 15225 // This class is used for looking up two character strings in the string table. |
15226 // If we don't have a hit we don't want to waste much time so we unroll the | 15226 // If we don't have a hit we don't want to waste much time so we unroll the |
15227 // string hash calculation loop here for speed. Doesn't work if the two | 15227 // string hash calculation loop here for speed. Doesn't work if the two |
15228 // characters form a decimal integer, since such strings have a different hash | 15228 // characters form a decimal integer, since such strings have a different hash |
15229 // algorithm. | 15229 // algorithm. |
(...skipping 17 matching lines...) Expand all Loading... |
15247 if ((hash & String::kHashBitMask) == 0) hash = StringHasher::kZeroHash; | 15247 if ((hash & String::kHashBitMask) == 0) hash = StringHasher::kZeroHash; |
15248 hash_ = hash; | 15248 hash_ = hash; |
15249 #ifdef DEBUG | 15249 #ifdef DEBUG |
15250 // If this assert fails then we failed to reproduce the two-character | 15250 // If this assert fails then we failed to reproduce the two-character |
15251 // version of the string hashing algorithm above. One reason could be | 15251 // version of the string hashing algorithm above. One reason could be |
15252 // that we were passed two digits as characters, since the hash | 15252 // that we were passed two digits as characters, since the hash |
15253 // algorithm is different in that case. | 15253 // algorithm is different in that case. |
15254 uint16_t chars[2] = {c1, c2}; | 15254 uint16_t chars[2] = {c1, c2}; |
15255 uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed); | 15255 uint32_t check_hash = StringHasher::HashSequentialString(chars, 2, seed); |
15256 hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask; | 15256 hash = (hash << String::kHashShift) | String::kIsNotArrayIndexMask; |
15257 ASSERT_EQ(static_cast<int32_t>(hash), static_cast<int32_t>(check_hash)); | 15257 DCHECK_EQ(static_cast<int32_t>(hash), static_cast<int32_t>(check_hash)); |
15258 #endif | 15258 #endif |
15259 } | 15259 } |
15260 | 15260 |
15261 bool IsMatch(Object* o) V8_OVERRIDE { | 15261 bool IsMatch(Object* o) V8_OVERRIDE { |
15262 if (!o->IsString()) return false; | 15262 if (!o->IsString()) return false; |
15263 String* other = String::cast(o); | 15263 String* other = String::cast(o); |
15264 if (other->length() != 2) return false; | 15264 if (other->length() != 2) return false; |
15265 if (other->Get(0) != c1_) return false; | 15265 if (other->Get(0) != c1_) return false; |
15266 return other->Get(1) == c2_; | 15266 return other->Get(1) == c2_; |
15267 } | 15267 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15299 MaybeHandle<String> StringTable::LookupStringIfExists( | 15299 MaybeHandle<String> StringTable::LookupStringIfExists( |
15300 Isolate* isolate, | 15300 Isolate* isolate, |
15301 Handle<String> string) { | 15301 Handle<String> string) { |
15302 Handle<StringTable> string_table = isolate->factory()->string_table(); | 15302 Handle<StringTable> string_table = isolate->factory()->string_table(); |
15303 InternalizedStringKey key(string); | 15303 InternalizedStringKey key(string); |
15304 int entry = string_table->FindEntry(&key); | 15304 int entry = string_table->FindEntry(&key); |
15305 if (entry == kNotFound) { | 15305 if (entry == kNotFound) { |
15306 return MaybeHandle<String>(); | 15306 return MaybeHandle<String>(); |
15307 } else { | 15307 } else { |
15308 Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate); | 15308 Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate); |
15309 ASSERT(StringShape(*result).IsInternalized()); | 15309 DCHECK(StringShape(*result).IsInternalized()); |
15310 return result; | 15310 return result; |
15311 } | 15311 } |
15312 } | 15312 } |
15313 | 15313 |
15314 | 15314 |
15315 MaybeHandle<String> StringTable::LookupTwoCharsStringIfExists( | 15315 MaybeHandle<String> StringTable::LookupTwoCharsStringIfExists( |
15316 Isolate* isolate, | 15316 Isolate* isolate, |
15317 uint16_t c1, | 15317 uint16_t c1, |
15318 uint16_t c2) { | 15318 uint16_t c2) { |
15319 Handle<StringTable> string_table = isolate->factory()->string_table(); | 15319 Handle<StringTable> string_table = isolate->factory()->string_table(); |
15320 TwoCharHashTableKey key(c1, c2, isolate->heap()->HashSeed()); | 15320 TwoCharHashTableKey key(c1, c2, isolate->heap()->HashSeed()); |
15321 int entry = string_table->FindEntry(&key); | 15321 int entry = string_table->FindEntry(&key); |
15322 if (entry == kNotFound) { | 15322 if (entry == kNotFound) { |
15323 return MaybeHandle<String>(); | 15323 return MaybeHandle<String>(); |
15324 } else { | 15324 } else { |
15325 Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate); | 15325 Handle<String> result(String::cast(string_table->KeyAt(entry)), isolate); |
15326 ASSERT(StringShape(*result).IsInternalized()); | 15326 DCHECK(StringShape(*result).IsInternalized()); |
15327 return result; | 15327 return result; |
15328 } | 15328 } |
15329 } | 15329 } |
15330 | 15330 |
15331 | 15331 |
15332 Handle<String> StringTable::LookupString(Isolate* isolate, | 15332 Handle<String> StringTable::LookupString(Isolate* isolate, |
15333 Handle<String> string) { | 15333 Handle<String> string) { |
15334 InternalizedStringKey key(string); | 15334 InternalizedStringKey key(string); |
15335 return LookupKey(isolate, &key); | 15335 return LookupKey(isolate, &key); |
15336 } | 15336 } |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15519 new_cache->ElementAdded(); | 15519 new_cache->ElementAdded(); |
15520 return new_cache; | 15520 return new_cache; |
15521 } | 15521 } |
15522 | 15522 |
15523 | 15523 |
15524 template<typename Derived, typename Shape, typename Key> | 15524 template<typename Derived, typename Shape, typename Key> |
15525 Handle<Derived> Dictionary<Derived, Shape, Key>::New( | 15525 Handle<Derived> Dictionary<Derived, Shape, Key>::New( |
15526 Isolate* isolate, | 15526 Isolate* isolate, |
15527 int at_least_space_for, | 15527 int at_least_space_for, |
15528 PretenureFlag pretenure) { | 15528 PretenureFlag pretenure) { |
15529 ASSERT(0 <= at_least_space_for); | 15529 DCHECK(0 <= at_least_space_for); |
15530 Handle<Derived> dict = DerivedHashTable::New(isolate, | 15530 Handle<Derived> dict = DerivedHashTable::New(isolate, |
15531 at_least_space_for, | 15531 at_least_space_for, |
15532 USE_DEFAULT_MINIMUM_CAPACITY, | 15532 USE_DEFAULT_MINIMUM_CAPACITY, |
15533 pretenure); | 15533 pretenure); |
15534 | 15534 |
15535 // Initialize the next enumeration index. | 15535 // Initialize the next enumeration index. |
15536 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 15536 dict->SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
15537 return dict; | 15537 return dict; |
15538 } | 15538 } |
15539 | 15539 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15646 } | 15646 } |
15647 | 15647 |
15648 | 15648 |
15649 template<typename Derived, typename Shape, typename Key> | 15649 template<typename Derived, typename Shape, typename Key> |
15650 Handle<Derived> Dictionary<Derived, Shape, Key>::Add( | 15650 Handle<Derived> Dictionary<Derived, Shape, Key>::Add( |
15651 Handle<Derived> dictionary, | 15651 Handle<Derived> dictionary, |
15652 Key key, | 15652 Key key, |
15653 Handle<Object> value, | 15653 Handle<Object> value, |
15654 PropertyDetails details) { | 15654 PropertyDetails details) { |
15655 // Valdate key is absent. | 15655 // Valdate key is absent. |
15656 SLOW_ASSERT((dictionary->FindEntry(key) == Dictionary::kNotFound)); | 15656 SLOW_DCHECK((dictionary->FindEntry(key) == Dictionary::kNotFound)); |
15657 // Check whether the dictionary should be extended. | 15657 // Check whether the dictionary should be extended. |
15658 dictionary = EnsureCapacity(dictionary, 1, key); | 15658 dictionary = EnsureCapacity(dictionary, 1, key); |
15659 | 15659 |
15660 AddEntry(dictionary, key, value, details, dictionary->Hash(key)); | 15660 AddEntry(dictionary, key, value, details, dictionary->Hash(key)); |
15661 return dictionary; | 15661 return dictionary; |
15662 } | 15662 } |
15663 | 15663 |
15664 | 15664 |
15665 // Add a key, value pair to the dictionary. | 15665 // Add a key, value pair to the dictionary. |
15666 template<typename Derived, typename Shape, typename Key> | 15666 template<typename Derived, typename Shape, typename Key> |
(...skipping 11 matching lines...) Expand all Loading... |
15678 if (!details.IsDeleted() && | 15678 if (!details.IsDeleted() && |
15679 details.dictionary_index() == 0 && | 15679 details.dictionary_index() == 0 && |
15680 Shape::kIsEnumerable) { | 15680 Shape::kIsEnumerable) { |
15681 // Assign an enumeration index to the property and update | 15681 // Assign an enumeration index to the property and update |
15682 // SetNextEnumerationIndex. | 15682 // SetNextEnumerationIndex. |
15683 int index = dictionary->NextEnumerationIndex(); | 15683 int index = dictionary->NextEnumerationIndex(); |
15684 details = PropertyDetails(details.attributes(), details.type(), index); | 15684 details = PropertyDetails(details.attributes(), details.type(), index); |
15685 dictionary->SetNextEnumerationIndex(index + 1); | 15685 dictionary->SetNextEnumerationIndex(index + 1); |
15686 } | 15686 } |
15687 dictionary->SetEntry(entry, k, value, details); | 15687 dictionary->SetEntry(entry, k, value, details); |
15688 ASSERT((dictionary->KeyAt(entry)->IsNumber() || | 15688 DCHECK((dictionary->KeyAt(entry)->IsNumber() || |
15689 dictionary->KeyAt(entry)->IsName())); | 15689 dictionary->KeyAt(entry)->IsName())); |
15690 dictionary->ElementAdded(); | 15690 dictionary->ElementAdded(); |
15691 } | 15691 } |
15692 | 15692 |
15693 | 15693 |
15694 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { | 15694 void SeededNumberDictionary::UpdateMaxNumberKey(uint32_t key) { |
15695 DisallowHeapAllocation no_allocation; | 15695 DisallowHeapAllocation no_allocation; |
15696 // If the dictionary requires slow elements an element has already | 15696 // If the dictionary requires slow elements an element has already |
15697 // been added at a high index. | 15697 // been added at a high index. |
15698 if (requires_slow_elements()) return; | 15698 if (requires_slow_elements()) return; |
(...skipping 11 matching lines...) Expand all Loading... |
15710 } | 15710 } |
15711 } | 15711 } |
15712 | 15712 |
15713 | 15713 |
15714 Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry( | 15714 Handle<SeededNumberDictionary> SeededNumberDictionary::AddNumberEntry( |
15715 Handle<SeededNumberDictionary> dictionary, | 15715 Handle<SeededNumberDictionary> dictionary, |
15716 uint32_t key, | 15716 uint32_t key, |
15717 Handle<Object> value, | 15717 Handle<Object> value, |
15718 PropertyDetails details) { | 15718 PropertyDetails details) { |
15719 dictionary->UpdateMaxNumberKey(key); | 15719 dictionary->UpdateMaxNumberKey(key); |
15720 SLOW_ASSERT(dictionary->FindEntry(key) == kNotFound); | 15720 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); |
15721 return Add(dictionary, key, value, details); | 15721 return Add(dictionary, key, value, details); |
15722 } | 15722 } |
15723 | 15723 |
15724 | 15724 |
15725 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry( | 15725 Handle<UnseededNumberDictionary> UnseededNumberDictionary::AddNumberEntry( |
15726 Handle<UnseededNumberDictionary> dictionary, | 15726 Handle<UnseededNumberDictionary> dictionary, |
15727 uint32_t key, | 15727 uint32_t key, |
15728 Handle<Object> value) { | 15728 Handle<Object> value) { |
15729 SLOW_ASSERT(dictionary->FindEntry(key) == kNotFound); | 15729 SLOW_DCHECK(dictionary->FindEntry(key) == kNotFound); |
15730 return Add(dictionary, key, value, PropertyDetails(NONE, NORMAL, 0)); | 15730 return Add(dictionary, key, value, PropertyDetails(NONE, NORMAL, 0)); |
15731 } | 15731 } |
15732 | 15732 |
15733 | 15733 |
15734 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut( | 15734 Handle<SeededNumberDictionary> SeededNumberDictionary::AtNumberPut( |
15735 Handle<SeededNumberDictionary> dictionary, | 15735 Handle<SeededNumberDictionary> dictionary, |
15736 uint32_t key, | 15736 uint32_t key, |
15737 Handle<Object> value) { | 15737 Handle<Object> value) { |
15738 dictionary->UpdateMaxNumberKey(key); | 15738 dictionary->UpdateMaxNumberKey(key); |
15739 return AtPut(dictionary, key, value); | 15739 return AtPut(dictionary, key, value); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15805 return NumberOfElementsFilterAttributes( | 15805 return NumberOfElementsFilterAttributes( |
15806 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); | 15806 static_cast<PropertyAttributes>(DONT_ENUM | SYMBOLIC)); |
15807 } | 15807 } |
15808 | 15808 |
15809 | 15809 |
15810 template<typename Derived, typename Shape, typename Key> | 15810 template<typename Derived, typename Shape, typename Key> |
15811 void Dictionary<Derived, Shape, Key>::CopyKeysTo( | 15811 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
15812 FixedArray* storage, | 15812 FixedArray* storage, |
15813 PropertyAttributes filter, | 15813 PropertyAttributes filter, |
15814 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { | 15814 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
15815 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15815 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
15816 int capacity = DerivedHashTable::Capacity(); | 15816 int capacity = DerivedHashTable::Capacity(); |
15817 int index = 0; | 15817 int index = 0; |
15818 for (int i = 0; i < capacity; i++) { | 15818 for (int i = 0; i < capacity; i++) { |
15819 Object* k = DerivedHashTable::KeyAt(i); | 15819 Object* k = DerivedHashTable::KeyAt(i); |
15820 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { | 15820 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
15821 PropertyDetails details = DetailsAt(i); | 15821 PropertyDetails details = DetailsAt(i); |
15822 if (details.IsDeleted()) continue; | 15822 if (details.IsDeleted()) continue; |
15823 PropertyAttributes attr = details.attributes(); | 15823 PropertyAttributes attr = details.attributes(); |
15824 if ((attr & filter) == 0) storage->set(index++, k); | 15824 if ((attr & filter) == 0) storage->set(index++, k); |
15825 } | 15825 } |
15826 } | 15826 } |
15827 if (sort_mode == Dictionary::SORTED) { | 15827 if (sort_mode == Dictionary::SORTED) { |
15828 storage->SortPairs(storage, index); | 15828 storage->SortPairs(storage, index); |
15829 } | 15829 } |
15830 ASSERT(storage->length() >= index); | 15830 DCHECK(storage->length() >= index); |
15831 } | 15831 } |
15832 | 15832 |
15833 | 15833 |
15834 struct EnumIndexComparator { | 15834 struct EnumIndexComparator { |
15835 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } | 15835 explicit EnumIndexComparator(NameDictionary* dict) : dict(dict) { } |
15836 bool operator() (Smi* a, Smi* b) { | 15836 bool operator() (Smi* a, Smi* b) { |
15837 PropertyDetails da(dict->DetailsAt(a->value())); | 15837 PropertyDetails da(dict->DetailsAt(a->value())); |
15838 PropertyDetails db(dict->DetailsAt(b->value())); | 15838 PropertyDetails db(dict->DetailsAt(b->value())); |
15839 return da.dictionary_index() < db.dictionary_index(); | 15839 return da.dictionary_index() < db.dictionary_index(); |
15840 } | 15840 } |
(...skipping 25 matching lines...) Expand all Loading... |
15866 } | 15866 } |
15867 } | 15867 } |
15868 | 15868 |
15869 | 15869 |
15870 template<typename Derived, typename Shape, typename Key> | 15870 template<typename Derived, typename Shape, typename Key> |
15871 void Dictionary<Derived, Shape, Key>::CopyKeysTo( | 15871 void Dictionary<Derived, Shape, Key>::CopyKeysTo( |
15872 FixedArray* storage, | 15872 FixedArray* storage, |
15873 int index, | 15873 int index, |
15874 PropertyAttributes filter, | 15874 PropertyAttributes filter, |
15875 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { | 15875 typename Dictionary<Derived, Shape, Key>::SortMode sort_mode) { |
15876 ASSERT(storage->length() >= NumberOfElementsFilterAttributes(filter)); | 15876 DCHECK(storage->length() >= NumberOfElementsFilterAttributes(filter)); |
15877 int capacity = DerivedHashTable::Capacity(); | 15877 int capacity = DerivedHashTable::Capacity(); |
15878 for (int i = 0; i < capacity; i++) { | 15878 for (int i = 0; i < capacity; i++) { |
15879 Object* k = DerivedHashTable::KeyAt(i); | 15879 Object* k = DerivedHashTable::KeyAt(i); |
15880 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { | 15880 if (DerivedHashTable::IsKey(k) && !FilterKey(k, filter)) { |
15881 PropertyDetails details = DetailsAt(i); | 15881 PropertyDetails details = DetailsAt(i); |
15882 if (details.IsDeleted()) continue; | 15882 if (details.IsDeleted()) continue; |
15883 PropertyAttributes attr = details.attributes(); | 15883 PropertyAttributes attr = details.attributes(); |
15884 if ((attr & filter) == 0) storage->set(index++, k); | 15884 if ((attr & filter) == 0) storage->set(index++, k); |
15885 } | 15885 } |
15886 } | 15886 } |
15887 if (sort_mode == Dictionary::SORTED) { | 15887 if (sort_mode == Dictionary::SORTED) { |
15888 storage->SortPairs(storage, index); | 15888 storage->SortPairs(storage, index); |
15889 } | 15889 } |
15890 ASSERT(storage->length() >= index); | 15890 DCHECK(storage->length() >= index); |
15891 } | 15891 } |
15892 | 15892 |
15893 | 15893 |
15894 // Backwards lookup (slow). | 15894 // Backwards lookup (slow). |
15895 template<typename Derived, typename Shape, typename Key> | 15895 template<typename Derived, typename Shape, typename Key> |
15896 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { | 15896 Object* Dictionary<Derived, Shape, Key>::SlowReverseLookup(Object* value) { |
15897 int capacity = DerivedHashTable::Capacity(); | 15897 int capacity = DerivedHashTable::Capacity(); |
15898 for (int i = 0; i < capacity; i++) { | 15898 for (int i = 0; i < capacity; i++) { |
15899 Object* k = DerivedHashTable::KeyAt(i); | 15899 Object* k = DerivedHashTable::KeyAt(i); |
15900 if (Dictionary::IsKey(k)) { | 15900 if (Dictionary::IsKey(k)) { |
15901 Object* e = ValueAt(i); | 15901 Object* e = ValueAt(i); |
15902 if (e->IsPropertyCell()) { | 15902 if (e->IsPropertyCell()) { |
15903 e = PropertyCell::cast(e)->value(); | 15903 e = PropertyCell::cast(e)->value(); |
15904 } | 15904 } |
15905 if (e == value) return k; | 15905 if (e == value) return k; |
15906 } | 15906 } |
15907 } | 15907 } |
15908 Heap* heap = Dictionary::GetHeap(); | 15908 Heap* heap = Dictionary::GetHeap(); |
15909 return heap->undefined_value(); | 15909 return heap->undefined_value(); |
15910 } | 15910 } |
15911 | 15911 |
15912 | 15912 |
15913 Object* ObjectHashTable::Lookup(Handle<Object> key) { | 15913 Object* ObjectHashTable::Lookup(Handle<Object> key) { |
15914 DisallowHeapAllocation no_gc; | 15914 DisallowHeapAllocation no_gc; |
15915 ASSERT(IsKey(*key)); | 15915 DCHECK(IsKey(*key)); |
15916 | 15916 |
15917 // If the object does not have an identity hash, it was never used as a key. | 15917 // If the object does not have an identity hash, it was never used as a key. |
15918 Object* hash = key->GetHash(); | 15918 Object* hash = key->GetHash(); |
15919 if (hash->IsUndefined()) { | 15919 if (hash->IsUndefined()) { |
15920 return GetHeap()->the_hole_value(); | 15920 return GetHeap()->the_hole_value(); |
15921 } | 15921 } |
15922 int entry = FindEntry(key); | 15922 int entry = FindEntry(key); |
15923 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 15923 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
15924 return get(EntryToIndex(entry) + 1); | 15924 return get(EntryToIndex(entry) + 1); |
15925 } | 15925 } |
15926 | 15926 |
15927 | 15927 |
15928 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, | 15928 Handle<ObjectHashTable> ObjectHashTable::Put(Handle<ObjectHashTable> table, |
15929 Handle<Object> key, | 15929 Handle<Object> key, |
15930 Handle<Object> value) { | 15930 Handle<Object> value) { |
15931 ASSERT(table->IsKey(*key)); | 15931 DCHECK(table->IsKey(*key)); |
15932 ASSERT(!value->IsTheHole()); | 15932 DCHECK(!value->IsTheHole()); |
15933 | 15933 |
15934 Isolate* isolate = table->GetIsolate(); | 15934 Isolate* isolate = table->GetIsolate(); |
15935 | 15935 |
15936 // Make sure the key object has an identity hash code. | 15936 // Make sure the key object has an identity hash code. |
15937 Handle<Smi> hash = Object::GetOrCreateHash(isolate, key); | 15937 Handle<Smi> hash = Object::GetOrCreateHash(isolate, key); |
15938 | 15938 |
15939 int entry = table->FindEntry(key); | 15939 int entry = table->FindEntry(key); |
15940 | 15940 |
15941 // Key is already in table, just overwrite value. | 15941 // Key is already in table, just overwrite value. |
15942 if (entry != kNotFound) { | 15942 if (entry != kNotFound) { |
15943 table->set(EntryToIndex(entry) + 1, *value); | 15943 table->set(EntryToIndex(entry) + 1, *value); |
15944 return table; | 15944 return table; |
15945 } | 15945 } |
15946 | 15946 |
15947 // Check whether the hash table should be extended. | 15947 // Check whether the hash table should be extended. |
15948 table = EnsureCapacity(table, 1, key); | 15948 table = EnsureCapacity(table, 1, key); |
15949 table->AddEntry(table->FindInsertionEntry(hash->value()), | 15949 table->AddEntry(table->FindInsertionEntry(hash->value()), |
15950 *key, | 15950 *key, |
15951 *value); | 15951 *value); |
15952 return table; | 15952 return table; |
15953 } | 15953 } |
15954 | 15954 |
15955 | 15955 |
15956 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, | 15956 Handle<ObjectHashTable> ObjectHashTable::Remove(Handle<ObjectHashTable> table, |
15957 Handle<Object> key, | 15957 Handle<Object> key, |
15958 bool* was_present) { | 15958 bool* was_present) { |
15959 ASSERT(table->IsKey(*key)); | 15959 DCHECK(table->IsKey(*key)); |
15960 | 15960 |
15961 Object* hash = key->GetHash(); | 15961 Object* hash = key->GetHash(); |
15962 if (hash->IsUndefined()) { | 15962 if (hash->IsUndefined()) { |
15963 *was_present = false; | 15963 *was_present = false; |
15964 return table; | 15964 return table; |
15965 } | 15965 } |
15966 | 15966 |
15967 int entry = table->FindEntry(key); | 15967 int entry = table->FindEntry(key); |
15968 if (entry == kNotFound) { | 15968 if (entry == kNotFound) { |
15969 *was_present = false; | 15969 *was_present = false; |
(...skipping 15 matching lines...) Expand all Loading... |
15985 | 15985 |
15986 void ObjectHashTable::RemoveEntry(int entry) { | 15986 void ObjectHashTable::RemoveEntry(int entry) { |
15987 set_the_hole(EntryToIndex(entry)); | 15987 set_the_hole(EntryToIndex(entry)); |
15988 set_the_hole(EntryToIndex(entry) + 1); | 15988 set_the_hole(EntryToIndex(entry) + 1); |
15989 ElementRemoved(); | 15989 ElementRemoved(); |
15990 } | 15990 } |
15991 | 15991 |
15992 | 15992 |
15993 Object* WeakHashTable::Lookup(Handle<Object> key) { | 15993 Object* WeakHashTable::Lookup(Handle<Object> key) { |
15994 DisallowHeapAllocation no_gc; | 15994 DisallowHeapAllocation no_gc; |
15995 ASSERT(IsKey(*key)); | 15995 DCHECK(IsKey(*key)); |
15996 int entry = FindEntry(key); | 15996 int entry = FindEntry(key); |
15997 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 15997 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
15998 return get(EntryToValueIndex(entry)); | 15998 return get(EntryToValueIndex(entry)); |
15999 } | 15999 } |
16000 | 16000 |
16001 | 16001 |
16002 Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table, | 16002 Handle<WeakHashTable> WeakHashTable::Put(Handle<WeakHashTable> table, |
16003 Handle<Object> key, | 16003 Handle<Object> key, |
16004 Handle<Object> value) { | 16004 Handle<Object> value) { |
16005 ASSERT(table->IsKey(*key)); | 16005 DCHECK(table->IsKey(*key)); |
16006 int entry = table->FindEntry(key); | 16006 int entry = table->FindEntry(key); |
16007 // Key is already in table, just overwrite value. | 16007 // Key is already in table, just overwrite value. |
16008 if (entry != kNotFound) { | 16008 if (entry != kNotFound) { |
16009 // TODO(ulan): Skipping write barrier is a temporary solution to avoid | 16009 // TODO(ulan): Skipping write barrier is a temporary solution to avoid |
16010 // memory leaks. Remove this once we have special visitor for weak fixed | 16010 // memory leaks. Remove this once we have special visitor for weak fixed |
16011 // arrays. | 16011 // arrays. |
16012 table->set(EntryToValueIndex(entry), *value, SKIP_WRITE_BARRIER); | 16012 table->set(EntryToValueIndex(entry), *value, SKIP_WRITE_BARRIER); |
16013 return table; | 16013 return table; |
16014 } | 16014 } |
16015 | 16015 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16058 table->SetNumberOfBuckets(num_buckets); | 16058 table->SetNumberOfBuckets(num_buckets); |
16059 table->SetNumberOfElements(0); | 16059 table->SetNumberOfElements(0); |
16060 table->SetNumberOfDeletedElements(0); | 16060 table->SetNumberOfDeletedElements(0); |
16061 return table; | 16061 return table; |
16062 } | 16062 } |
16063 | 16063 |
16064 | 16064 |
16065 template<class Derived, class Iterator, int entrysize> | 16065 template<class Derived, class Iterator, int entrysize> |
16066 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable( | 16066 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::EnsureGrowable( |
16067 Handle<Derived> table) { | 16067 Handle<Derived> table) { |
16068 ASSERT(!table->IsObsolete()); | 16068 DCHECK(!table->IsObsolete()); |
16069 | 16069 |
16070 int nof = table->NumberOfElements(); | 16070 int nof = table->NumberOfElements(); |
16071 int nod = table->NumberOfDeletedElements(); | 16071 int nod = table->NumberOfDeletedElements(); |
16072 int capacity = table->Capacity(); | 16072 int capacity = table->Capacity(); |
16073 if ((nof + nod) < capacity) return table; | 16073 if ((nof + nod) < capacity) return table; |
16074 // Don't need to grow if we can simply clear out deleted entries instead. | 16074 // Don't need to grow if we can simply clear out deleted entries instead. |
16075 // Note that we can't compact in place, though, so we always allocate | 16075 // Note that we can't compact in place, though, so we always allocate |
16076 // a new table. | 16076 // a new table. |
16077 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); | 16077 return Rehash(table, (nod < (capacity >> 1)) ? capacity << 1 : capacity); |
16078 } | 16078 } |
16079 | 16079 |
16080 | 16080 |
16081 template<class Derived, class Iterator, int entrysize> | 16081 template<class Derived, class Iterator, int entrysize> |
16082 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink( | 16082 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Shrink( |
16083 Handle<Derived> table) { | 16083 Handle<Derived> table) { |
16084 ASSERT(!table->IsObsolete()); | 16084 DCHECK(!table->IsObsolete()); |
16085 | 16085 |
16086 int nof = table->NumberOfElements(); | 16086 int nof = table->NumberOfElements(); |
16087 int capacity = table->Capacity(); | 16087 int capacity = table->Capacity(); |
16088 if (nof >= (capacity >> 2)) return table; | 16088 if (nof >= (capacity >> 2)) return table; |
16089 return Rehash(table, capacity / 2); | 16089 return Rehash(table, capacity / 2); |
16090 } | 16090 } |
16091 | 16091 |
16092 | 16092 |
16093 template<class Derived, class Iterator, int entrysize> | 16093 template<class Derived, class Iterator, int entrysize> |
16094 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear( | 16094 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Clear( |
16095 Handle<Derived> table) { | 16095 Handle<Derived> table) { |
16096 ASSERT(!table->IsObsolete()); | 16096 DCHECK(!table->IsObsolete()); |
16097 | 16097 |
16098 Handle<Derived> new_table = | 16098 Handle<Derived> new_table = |
16099 Allocate(table->GetIsolate(), | 16099 Allocate(table->GetIsolate(), |
16100 kMinCapacity, | 16100 kMinCapacity, |
16101 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); | 16101 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); |
16102 | 16102 |
16103 table->SetNextTable(*new_table); | 16103 table->SetNextTable(*new_table); |
16104 table->SetNumberOfDeletedElements(-1); | 16104 table->SetNumberOfDeletedElements(-1); |
16105 | 16105 |
16106 return new_table; | 16106 return new_table; |
(...skipping 10 matching lines...) Expand all Loading... |
16117 } | 16117 } |
16118 *was_present = true; | 16118 *was_present = true; |
16119 table->RemoveEntry(entry); | 16119 table->RemoveEntry(entry); |
16120 return Shrink(table); | 16120 return Shrink(table); |
16121 } | 16121 } |
16122 | 16122 |
16123 | 16123 |
16124 template<class Derived, class Iterator, int entrysize> | 16124 template<class Derived, class Iterator, int entrysize> |
16125 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( | 16125 Handle<Derived> OrderedHashTable<Derived, Iterator, entrysize>::Rehash( |
16126 Handle<Derived> table, int new_capacity) { | 16126 Handle<Derived> table, int new_capacity) { |
16127 ASSERT(!table->IsObsolete()); | 16127 DCHECK(!table->IsObsolete()); |
16128 | 16128 |
16129 Handle<Derived> new_table = | 16129 Handle<Derived> new_table = |
16130 Allocate(table->GetIsolate(), | 16130 Allocate(table->GetIsolate(), |
16131 new_capacity, | 16131 new_capacity, |
16132 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); | 16132 table->GetHeap()->InNewSpace(*table) ? NOT_TENURED : TENURED); |
16133 int nof = table->NumberOfElements(); | 16133 int nof = table->NumberOfElements(); |
16134 int nod = table->NumberOfDeletedElements(); | 16134 int nod = table->NumberOfDeletedElements(); |
16135 int new_buckets = new_table->NumberOfBuckets(); | 16135 int new_buckets = new_table->NumberOfBuckets(); |
16136 int new_entry = 0; | 16136 int new_entry = 0; |
16137 int removed_holes_index = 0; | 16137 int removed_holes_index = 0; |
(...skipping 12 matching lines...) Expand all Loading... |
16150 int new_index = new_table->EntryToIndex(new_entry); | 16150 int new_index = new_table->EntryToIndex(new_entry); |
16151 int old_index = table->EntryToIndex(old_entry); | 16151 int old_index = table->EntryToIndex(old_entry); |
16152 for (int i = 0; i < entrysize; ++i) { | 16152 for (int i = 0; i < entrysize; ++i) { |
16153 Object* value = table->get(old_index + i); | 16153 Object* value = table->get(old_index + i); |
16154 new_table->set(new_index + i, value); | 16154 new_table->set(new_index + i, value); |
16155 } | 16155 } |
16156 new_table->set(new_index + kChainOffset, chain_entry); | 16156 new_table->set(new_index + kChainOffset, chain_entry); |
16157 ++new_entry; | 16157 ++new_entry; |
16158 } | 16158 } |
16159 | 16159 |
16160 ASSERT_EQ(nod, removed_holes_index); | 16160 DCHECK_EQ(nod, removed_holes_index); |
16161 | 16161 |
16162 new_table->SetNumberOfElements(nof); | 16162 new_table->SetNumberOfElements(nof); |
16163 table->SetNextTable(*new_table); | 16163 table->SetNextTable(*new_table); |
16164 | 16164 |
16165 return new_table; | 16165 return new_table; |
16166 } | 16166 } |
16167 | 16167 |
16168 | 16168 |
16169 template <class Derived, class Iterator, int entrysize> | 16169 template <class Derived, class Iterator, int entrysize> |
16170 int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry( | 16170 int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry( |
16171 Handle<Object> key, int hash) { | 16171 Handle<Object> key, int hash) { |
16172 ASSERT(!IsObsolete()); | 16172 DCHECK(!IsObsolete()); |
16173 | 16173 |
16174 DisallowHeapAllocation no_gc; | 16174 DisallowHeapAllocation no_gc; |
16175 ASSERT(!key->IsTheHole()); | 16175 DCHECK(!key->IsTheHole()); |
16176 for (int entry = HashToEntry(hash); entry != kNotFound; | 16176 for (int entry = HashToEntry(hash); entry != kNotFound; |
16177 entry = ChainAt(entry)) { | 16177 entry = ChainAt(entry)) { |
16178 Object* candidate = KeyAt(entry); | 16178 Object* candidate = KeyAt(entry); |
16179 if (candidate->SameValueZero(*key)) | 16179 if (candidate->SameValueZero(*key)) |
16180 return entry; | 16180 return entry; |
16181 } | 16181 } |
16182 return kNotFound; | 16182 return kNotFound; |
16183 } | 16183 } |
16184 | 16184 |
16185 | 16185 |
16186 template <class Derived, class Iterator, int entrysize> | 16186 template <class Derived, class Iterator, int entrysize> |
16187 int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry( | 16187 int OrderedHashTable<Derived, Iterator, entrysize>::FindEntry( |
16188 Handle<Object> key) { | 16188 Handle<Object> key) { |
16189 DisallowHeapAllocation no_gc; | 16189 DisallowHeapAllocation no_gc; |
16190 Object* hash = key->GetHash(); | 16190 Object* hash = key->GetHash(); |
16191 if (!hash->IsSmi()) return kNotFound; | 16191 if (!hash->IsSmi()) return kNotFound; |
16192 return FindEntry(key, Smi::cast(hash)->value()); | 16192 return FindEntry(key, Smi::cast(hash)->value()); |
16193 } | 16193 } |
16194 | 16194 |
16195 | 16195 |
16196 template <class Derived, class Iterator, int entrysize> | 16196 template <class Derived, class Iterator, int entrysize> |
16197 int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) { | 16197 int OrderedHashTable<Derived, Iterator, entrysize>::AddEntry(int hash) { |
16198 ASSERT(!IsObsolete()); | 16198 DCHECK(!IsObsolete()); |
16199 | 16199 |
16200 int entry = UsedCapacity(); | 16200 int entry = UsedCapacity(); |
16201 int bucket = HashToBucket(hash); | 16201 int bucket = HashToBucket(hash); |
16202 int index = EntryToIndex(entry); | 16202 int index = EntryToIndex(entry); |
16203 Object* chain_entry = get(kHashTableStartIndex + bucket); | 16203 Object* chain_entry = get(kHashTableStartIndex + bucket); |
16204 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); | 16204 set(kHashTableStartIndex + bucket, Smi::FromInt(entry)); |
16205 set(index + kChainOffset, chain_entry); | 16205 set(index + kChainOffset, chain_entry); |
16206 SetNumberOfElements(NumberOfElements() + 1); | 16206 SetNumberOfElements(NumberOfElements() + 1); |
16207 return index; | 16207 return index; |
16208 } | 16208 } |
16209 | 16209 |
16210 | 16210 |
16211 template<class Derived, class Iterator, int entrysize> | 16211 template<class Derived, class Iterator, int entrysize> |
16212 void OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) { | 16212 void OrderedHashTable<Derived, Iterator, entrysize>::RemoveEntry(int entry) { |
16213 ASSERT(!IsObsolete()); | 16213 DCHECK(!IsObsolete()); |
16214 | 16214 |
16215 int index = EntryToIndex(entry); | 16215 int index = EntryToIndex(entry); |
16216 for (int i = 0; i < entrysize; ++i) { | 16216 for (int i = 0; i < entrysize; ++i) { |
16217 set_the_hole(index + i); | 16217 set_the_hole(index + i); |
16218 } | 16218 } |
16219 SetNumberOfElements(NumberOfElements() - 1); | 16219 SetNumberOfElements(NumberOfElements() - 1); |
16220 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); | 16220 SetNumberOfDeletedElements(NumberOfDeletedElements() + 1); |
16221 } | 16221 } |
16222 | 16222 |
16223 | 16223 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16307 DisallowHeapAllocation no_gc; | 16307 DisallowHeapAllocation no_gc; |
16308 int entry = FindEntry(key); | 16308 int entry = FindEntry(key); |
16309 if (entry == kNotFound) return GetHeap()->the_hole_value(); | 16309 if (entry == kNotFound) return GetHeap()->the_hole_value(); |
16310 return ValueAt(entry); | 16310 return ValueAt(entry); |
16311 } | 16311 } |
16312 | 16312 |
16313 | 16313 |
16314 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, | 16314 Handle<OrderedHashMap> OrderedHashMap::Put(Handle<OrderedHashMap> table, |
16315 Handle<Object> key, | 16315 Handle<Object> key, |
16316 Handle<Object> value) { | 16316 Handle<Object> value) { |
16317 ASSERT(!key->IsTheHole()); | 16317 DCHECK(!key->IsTheHole()); |
16318 | 16318 |
16319 int hash = GetOrCreateHash(table->GetIsolate(), key)->value(); | 16319 int hash = GetOrCreateHash(table->GetIsolate(), key)->value(); |
16320 int entry = table->FindEntry(key, hash); | 16320 int entry = table->FindEntry(key, hash); |
16321 | 16321 |
16322 if (entry != kNotFound) { | 16322 if (entry != kNotFound) { |
16323 table->set(table->EntryToIndex(entry) + kValueOffset, *value); | 16323 table->set(table->EntryToIndex(entry) + kValueOffset, *value); |
16324 return table; | 16324 return table; |
16325 } | 16325 } |
16326 | 16326 |
16327 table = EnsureGrowable(table); | 16327 table = EnsureGrowable(table); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16441 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( | 16441 DeclaredAccessorDescriptorIterator::DeclaredAccessorDescriptorIterator( |
16442 DeclaredAccessorDescriptor* descriptor) | 16442 DeclaredAccessorDescriptor* descriptor) |
16443 : array_(descriptor->serialized_data()->GetDataStartAddress()), | 16443 : array_(descriptor->serialized_data()->GetDataStartAddress()), |
16444 length_(descriptor->serialized_data()->length()), | 16444 length_(descriptor->serialized_data()->length()), |
16445 offset_(0) { | 16445 offset_(0) { |
16446 } | 16446 } |
16447 | 16447 |
16448 | 16448 |
16449 const DeclaredAccessorDescriptorData* | 16449 const DeclaredAccessorDescriptorData* |
16450 DeclaredAccessorDescriptorIterator::Next() { | 16450 DeclaredAccessorDescriptorIterator::Next() { |
16451 ASSERT(offset_ < length_); | 16451 DCHECK(offset_ < length_); |
16452 uint8_t* ptr = &array_[offset_]; | 16452 uint8_t* ptr = &array_[offset_]; |
16453 ASSERT(reinterpret_cast<uintptr_t>(ptr) % sizeof(uintptr_t) == 0); | 16453 DCHECK(reinterpret_cast<uintptr_t>(ptr) % sizeof(uintptr_t) == 0); |
16454 const DeclaredAccessorDescriptorData* data = | 16454 const DeclaredAccessorDescriptorData* data = |
16455 reinterpret_cast<const DeclaredAccessorDescriptorData*>(ptr); | 16455 reinterpret_cast<const DeclaredAccessorDescriptorData*>(ptr); |
16456 offset_ += sizeof(*data); | 16456 offset_ += sizeof(*data); |
16457 ASSERT(offset_ <= length_); | 16457 DCHECK(offset_ <= length_); |
16458 return data; | 16458 return data; |
16459 } | 16459 } |
16460 | 16460 |
16461 | 16461 |
16462 Handle<DeclaredAccessorDescriptor> DeclaredAccessorDescriptor::Create( | 16462 Handle<DeclaredAccessorDescriptor> DeclaredAccessorDescriptor::Create( |
16463 Isolate* isolate, | 16463 Isolate* isolate, |
16464 const DeclaredAccessorDescriptorData& descriptor, | 16464 const DeclaredAccessorDescriptorData& descriptor, |
16465 Handle<DeclaredAccessorDescriptor> previous) { | 16465 Handle<DeclaredAccessorDescriptor> previous) { |
16466 int previous_length = | 16466 int previous_length = |
16467 previous.is_null() ? 0 : previous->serialized_data()->length(); | 16467 previous.is_null() ? 0 : previous->serialized_data()->length(); |
16468 int length = sizeof(descriptor) + previous_length; | 16468 int length = sizeof(descriptor) + previous_length; |
16469 Handle<ByteArray> serialized_descriptor = | 16469 Handle<ByteArray> serialized_descriptor = |
16470 isolate->factory()->NewByteArray(length); | 16470 isolate->factory()->NewByteArray(length); |
16471 Handle<DeclaredAccessorDescriptor> value = | 16471 Handle<DeclaredAccessorDescriptor> value = |
16472 isolate->factory()->NewDeclaredAccessorDescriptor(); | 16472 isolate->factory()->NewDeclaredAccessorDescriptor(); |
16473 value->set_serialized_data(*serialized_descriptor); | 16473 value->set_serialized_data(*serialized_descriptor); |
16474 // Copy in the data. | 16474 // Copy in the data. |
16475 { | 16475 { |
16476 DisallowHeapAllocation no_allocation; | 16476 DisallowHeapAllocation no_allocation; |
16477 uint8_t* array = serialized_descriptor->GetDataStartAddress(); | 16477 uint8_t* array = serialized_descriptor->GetDataStartAddress(); |
16478 if (previous_length != 0) { | 16478 if (previous_length != 0) { |
16479 uint8_t* previous_array = | 16479 uint8_t* previous_array = |
16480 previous->serialized_data()->GetDataStartAddress(); | 16480 previous->serialized_data()->GetDataStartAddress(); |
16481 MemCopy(array, previous_array, previous_length); | 16481 MemCopy(array, previous_array, previous_length); |
16482 array += previous_length; | 16482 array += previous_length; |
16483 } | 16483 } |
16484 ASSERT(reinterpret_cast<uintptr_t>(array) % sizeof(uintptr_t) == 0); | 16484 DCHECK(reinterpret_cast<uintptr_t>(array) % sizeof(uintptr_t) == 0); |
16485 DeclaredAccessorDescriptorData* data = | 16485 DeclaredAccessorDescriptorData* data = |
16486 reinterpret_cast<DeclaredAccessorDescriptorData*>(array); | 16486 reinterpret_cast<DeclaredAccessorDescriptorData*>(array); |
16487 *data = descriptor; | 16487 *data = descriptor; |
16488 } | 16488 } |
16489 return value; | 16489 return value; |
16490 } | 16490 } |
16491 | 16491 |
16492 | 16492 |
16493 // Check if there is a break point at this code position. | 16493 // Check if there is a break point at this code position. |
16494 bool DebugInfo::HasBreakPoint(int code_position) { | 16494 bool DebugInfo::HasBreakPoint(int code_position) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16558 isolate->factory()->NewFixedArray( | 16558 isolate->factory()->NewFixedArray( |
16559 old_break_points->length() + | 16559 old_break_points->length() + |
16560 DebugInfo::kEstimatedNofBreakPointsInFunction); | 16560 DebugInfo::kEstimatedNofBreakPointsInFunction); |
16561 | 16561 |
16562 debug_info->set_break_points(*new_break_points); | 16562 debug_info->set_break_points(*new_break_points); |
16563 for (int i = 0; i < old_break_points->length(); i++) { | 16563 for (int i = 0; i < old_break_points->length(); i++) { |
16564 new_break_points->set(i, old_break_points->get(i)); | 16564 new_break_points->set(i, old_break_points->get(i)); |
16565 } | 16565 } |
16566 index = old_break_points->length(); | 16566 index = old_break_points->length(); |
16567 } | 16567 } |
16568 ASSERT(index != kNoBreakPointInfo); | 16568 DCHECK(index != kNoBreakPointInfo); |
16569 | 16569 |
16570 // Allocate new BreakPointInfo object and set the break point. | 16570 // Allocate new BreakPointInfo object and set the break point. |
16571 Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast( | 16571 Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast( |
16572 isolate->factory()->NewStruct(BREAK_POINT_INFO_TYPE)); | 16572 isolate->factory()->NewStruct(BREAK_POINT_INFO_TYPE)); |
16573 new_break_point_info->set_code_position(Smi::FromInt(code_position)); | 16573 new_break_point_info->set_code_position(Smi::FromInt(code_position)); |
16574 new_break_point_info->set_source_position(Smi::FromInt(source_position)); | 16574 new_break_point_info->set_source_position(Smi::FromInt(source_position)); |
16575 new_break_point_info-> | 16575 new_break_point_info-> |
16576 set_statement_position(Smi::FromInt(statement_position)); | 16576 set_statement_position(Smi::FromInt(statement_position)); |
16577 new_break_point_info->set_break_point_objects( | 16577 new_break_point_info->set_break_point_objects( |
16578 isolate->heap()->undefined_value()); | 16578 isolate->heap()->undefined_value()); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16650 if (break_point_info->break_point_objects()->IsUndefined()) return; | 16650 if (break_point_info->break_point_objects()->IsUndefined()) return; |
16651 // If there is a single break point clear it if it is the same. | 16651 // If there is a single break point clear it if it is the same. |
16652 if (!break_point_info->break_point_objects()->IsFixedArray()) { | 16652 if (!break_point_info->break_point_objects()->IsFixedArray()) { |
16653 if (break_point_info->break_point_objects() == *break_point_object) { | 16653 if (break_point_info->break_point_objects() == *break_point_object) { |
16654 break_point_info->set_break_point_objects( | 16654 break_point_info->set_break_point_objects( |
16655 isolate->heap()->undefined_value()); | 16655 isolate->heap()->undefined_value()); |
16656 } | 16656 } |
16657 return; | 16657 return; |
16658 } | 16658 } |
16659 // If there are multiple break points shrink the array | 16659 // If there are multiple break points shrink the array |
16660 ASSERT(break_point_info->break_point_objects()->IsFixedArray()); | 16660 DCHECK(break_point_info->break_point_objects()->IsFixedArray()); |
16661 Handle<FixedArray> old_array = | 16661 Handle<FixedArray> old_array = |
16662 Handle<FixedArray>( | 16662 Handle<FixedArray>( |
16663 FixedArray::cast(break_point_info->break_point_objects())); | 16663 FixedArray::cast(break_point_info->break_point_objects())); |
16664 Handle<FixedArray> new_array = | 16664 Handle<FixedArray> new_array = |
16665 isolate->factory()->NewFixedArray(old_array->length() - 1); | 16665 isolate->factory()->NewFixedArray(old_array->length() - 1); |
16666 int found_count = 0; | 16666 int found_count = 0; |
16667 for (int i = 0; i < old_array->length(); i++) { | 16667 for (int i = 0; i < old_array->length(); i++) { |
16668 if (old_array->get(i) == *break_point_object) { | 16668 if (old_array->get(i) == *break_point_object) { |
16669 ASSERT(found_count == 0); | 16669 DCHECK(found_count == 0); |
16670 found_count++; | 16670 found_count++; |
16671 } else { | 16671 } else { |
16672 new_array->set(i - found_count, old_array->get(i)); | 16672 new_array->set(i - found_count, old_array->get(i)); |
16673 } | 16673 } |
16674 } | 16674 } |
16675 // If the break point was found in the list change it. | 16675 // If the break point was found in the list change it. |
16676 if (found_count > 0) break_point_info->set_break_point_objects(*new_array); | 16676 if (found_count > 0) break_point_info->set_break_point_objects(*new_array); |
16677 } | 16677 } |
16678 | 16678 |
16679 | 16679 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16745 } | 16745 } |
16746 | 16746 |
16747 | 16747 |
16748 Object* JSDate::GetField(Object* object, Smi* index) { | 16748 Object* JSDate::GetField(Object* object, Smi* index) { |
16749 return JSDate::cast(object)->DoGetField( | 16749 return JSDate::cast(object)->DoGetField( |
16750 static_cast<FieldIndex>(index->value())); | 16750 static_cast<FieldIndex>(index->value())); |
16751 } | 16751 } |
16752 | 16752 |
16753 | 16753 |
16754 Object* JSDate::DoGetField(FieldIndex index) { | 16754 Object* JSDate::DoGetField(FieldIndex index) { |
16755 ASSERT(index != kDateValue); | 16755 DCHECK(index != kDateValue); |
16756 | 16756 |
16757 DateCache* date_cache = GetIsolate()->date_cache(); | 16757 DateCache* date_cache = GetIsolate()->date_cache(); |
16758 | 16758 |
16759 if (index < kFirstUncachedField) { | 16759 if (index < kFirstUncachedField) { |
16760 Object* stamp = cache_stamp(); | 16760 Object* stamp = cache_stamp(); |
16761 if (stamp != date_cache->stamp() && stamp->IsSmi()) { | 16761 if (stamp != date_cache->stamp() && stamp->IsSmi()) { |
16762 // Since the stamp is not NaN, the value is also not NaN. | 16762 // Since the stamp is not NaN, the value is also not NaN. |
16763 int64_t local_time_ms = | 16763 int64_t local_time_ms = |
16764 date_cache->ToLocal(static_cast<int64_t>(value()->Number())); | 16764 date_cache->ToLocal(static_cast<int64_t>(value()->Number())); |
16765 SetCachedFields(local_time_ms, date_cache); | 16765 SetCachedFields(local_time_ms, date_cache); |
(...skipping 17 matching lines...) Expand all Loading... |
16783 double time = value()->Number(); | 16783 double time = value()->Number(); |
16784 if (std::isnan(time)) return GetIsolate()->heap()->nan_value(); | 16784 if (std::isnan(time)) return GetIsolate()->heap()->nan_value(); |
16785 | 16785 |
16786 int64_t local_time_ms = date_cache->ToLocal(static_cast<int64_t>(time)); | 16786 int64_t local_time_ms = date_cache->ToLocal(static_cast<int64_t>(time)); |
16787 int days = DateCache::DaysFromTime(local_time_ms); | 16787 int days = DateCache::DaysFromTime(local_time_ms); |
16788 | 16788 |
16789 if (index == kDays) return Smi::FromInt(days); | 16789 if (index == kDays) return Smi::FromInt(days); |
16790 | 16790 |
16791 int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days); | 16791 int time_in_day_ms = DateCache::TimeInDay(local_time_ms, days); |
16792 if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000); | 16792 if (index == kMillisecond) return Smi::FromInt(time_in_day_ms % 1000); |
16793 ASSERT(index == kTimeInDay); | 16793 DCHECK(index == kTimeInDay); |
16794 return Smi::FromInt(time_in_day_ms); | 16794 return Smi::FromInt(time_in_day_ms); |
16795 } | 16795 } |
16796 | 16796 |
16797 | 16797 |
16798 Object* JSDate::GetUTCField(FieldIndex index, | 16798 Object* JSDate::GetUTCField(FieldIndex index, |
16799 double value, | 16799 double value, |
16800 DateCache* date_cache) { | 16800 DateCache* date_cache) { |
16801 ASSERT(index >= kFirstUTCField); | 16801 DCHECK(index >= kFirstUTCField); |
16802 | 16802 |
16803 if (std::isnan(value)) return GetIsolate()->heap()->nan_value(); | 16803 if (std::isnan(value)) return GetIsolate()->heap()->nan_value(); |
16804 | 16804 |
16805 int64_t time_ms = static_cast<int64_t>(value); | 16805 int64_t time_ms = static_cast<int64_t>(value); |
16806 | 16806 |
16807 if (index == kTimezoneOffset) { | 16807 if (index == kTimezoneOffset) { |
16808 return Smi::FromInt(date_cache->TimezoneOffset(time_ms)); | 16808 return Smi::FromInt(date_cache->TimezoneOffset(time_ms)); |
16809 } | 16809 } |
16810 | 16810 |
16811 int days = DateCache::DaysFromTime(time_ms); | 16811 int days = DateCache::DaysFromTime(time_ms); |
16812 | 16812 |
16813 if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days)); | 16813 if (index == kWeekdayUTC) return Smi::FromInt(date_cache->Weekday(days)); |
16814 | 16814 |
16815 if (index <= kDayUTC) { | 16815 if (index <= kDayUTC) { |
16816 int year, month, day; | 16816 int year, month, day; |
16817 date_cache->YearMonthDayFromDays(days, &year, &month, &day); | 16817 date_cache->YearMonthDayFromDays(days, &year, &month, &day); |
16818 if (index == kYearUTC) return Smi::FromInt(year); | 16818 if (index == kYearUTC) return Smi::FromInt(year); |
16819 if (index == kMonthUTC) return Smi::FromInt(month); | 16819 if (index == kMonthUTC) return Smi::FromInt(month); |
16820 ASSERT(index == kDayUTC); | 16820 DCHECK(index == kDayUTC); |
16821 return Smi::FromInt(day); | 16821 return Smi::FromInt(day); |
16822 } | 16822 } |
16823 | 16823 |
16824 int time_in_day_ms = DateCache::TimeInDay(time_ms, days); | 16824 int time_in_day_ms = DateCache::TimeInDay(time_ms, days); |
16825 switch (index) { | 16825 switch (index) { |
16826 case kHourUTC: return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000)); | 16826 case kHourUTC: return Smi::FromInt(time_in_day_ms / (60 * 60 * 1000)); |
16827 case kMinuteUTC: return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60); | 16827 case kMinuteUTC: return Smi::FromInt((time_in_day_ms / (60 * 1000)) % 60); |
16828 case kSecondUTC: return Smi::FromInt((time_in_day_ms / 1000) % 60); | 16828 case kSecondUTC: return Smi::FromInt((time_in_day_ms / 1000) % 60); |
16829 case kMillisecondUTC: return Smi::FromInt(time_in_day_ms % 1000); | 16829 case kMillisecondUTC: return Smi::FromInt(time_in_day_ms % 1000); |
16830 case kDaysUTC: return Smi::FromInt(days); | 16830 case kDaysUTC: return Smi::FromInt(days); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16869 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 16869 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
16870 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 16870 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
16871 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 16871 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
16872 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 16872 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
16873 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 16873 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
16874 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 16874 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
16875 } | 16875 } |
16876 | 16876 |
16877 | 16877 |
16878 void JSArrayBuffer::Neuter() { | 16878 void JSArrayBuffer::Neuter() { |
16879 ASSERT(is_external()); | 16879 DCHECK(is_external()); |
16880 set_backing_store(NULL); | 16880 set_backing_store(NULL); |
16881 set_byte_length(Smi::FromInt(0)); | 16881 set_byte_length(Smi::FromInt(0)); |
16882 } | 16882 } |
16883 | 16883 |
16884 | 16884 |
16885 void JSArrayBufferView::NeuterView() { | 16885 void JSArrayBufferView::NeuterView() { |
16886 set_byte_offset(Smi::FromInt(0)); | 16886 set_byte_offset(Smi::FromInt(0)); |
16887 set_byte_length(Smi::FromInt(0)); | 16887 set_byte_length(Smi::FromInt(0)); |
16888 } | 16888 } |
16889 | 16889 |
(...skipping 24 matching lines...) Expand all Loading... |
16914 } | 16914 } |
16915 } | 16915 } |
16916 | 16916 |
16917 | 16917 |
16918 Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer( | 16918 Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer( |
16919 Handle<JSTypedArray> typed_array) { | 16919 Handle<JSTypedArray> typed_array) { |
16920 | 16920 |
16921 Handle<Map> map(typed_array->map()); | 16921 Handle<Map> map(typed_array->map()); |
16922 Isolate* isolate = typed_array->GetIsolate(); | 16922 Isolate* isolate = typed_array->GetIsolate(); |
16923 | 16923 |
16924 ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind())); | 16924 DCHECK(IsFixedTypedArrayElementsKind(map->elements_kind())); |
16925 | 16925 |
16926 Handle<Map> new_map = Map::TransitionElementsTo( | 16926 Handle<Map> new_map = Map::TransitionElementsTo( |
16927 map, | 16927 map, |
16928 FixedToExternalElementsKind(map->elements_kind())); | 16928 FixedToExternalElementsKind(map->elements_kind())); |
16929 | 16929 |
16930 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); | 16930 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer(); |
16931 Handle<FixedTypedArrayBase> fixed_typed_array( | 16931 Handle<FixedTypedArrayBase> fixed_typed_array( |
16932 FixedTypedArrayBase::cast(typed_array->elements())); | 16932 FixedTypedArrayBase::cast(typed_array->elements())); |
16933 Runtime::SetupArrayBufferAllocatingData(isolate, buffer, | 16933 Runtime::SetupArrayBufferAllocatingData(isolate, buffer, |
16934 fixed_typed_array->DataSize(), false); | 16934 fixed_typed_array->DataSize(), false); |
16935 memcpy(buffer->backing_store(), | 16935 memcpy(buffer->backing_store(), |
16936 fixed_typed_array->DataPtr(), | 16936 fixed_typed_array->DataPtr(), |
16937 fixed_typed_array->DataSize()); | 16937 fixed_typed_array->DataSize()); |
16938 Handle<ExternalArray> new_elements = | 16938 Handle<ExternalArray> new_elements = |
16939 isolate->factory()->NewExternalArray( | 16939 isolate->factory()->NewExternalArray( |
16940 fixed_typed_array->length(), typed_array->type(), | 16940 fixed_typed_array->length(), typed_array->type(), |
16941 static_cast<uint8_t*>(buffer->backing_store())); | 16941 static_cast<uint8_t*>(buffer->backing_store())); |
16942 | 16942 |
16943 buffer->set_weak_first_view(*typed_array); | 16943 buffer->set_weak_first_view(*typed_array); |
16944 ASSERT(typed_array->weak_next() == isolate->heap()->undefined_value()); | 16944 DCHECK(typed_array->weak_next() == isolate->heap()->undefined_value()); |
16945 typed_array->set_buffer(*buffer); | 16945 typed_array->set_buffer(*buffer); |
16946 JSObject::SetMapAndElements(typed_array, new_map, new_elements); | 16946 JSObject::SetMapAndElements(typed_array, new_map, new_elements); |
16947 | 16947 |
16948 return buffer; | 16948 return buffer; |
16949 } | 16949 } |
16950 | 16950 |
16951 | 16951 |
16952 Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { | 16952 Handle<JSArrayBuffer> JSTypedArray::GetBuffer() { |
16953 Handle<Object> result(buffer(), GetIsolate()); | 16953 Handle<Object> result(buffer(), GetIsolate()); |
16954 if (*result != Smi::FromInt(0)) { | 16954 if (*result != Smi::FromInt(0)) { |
16955 ASSERT(IsExternalArrayElementsKind(map()->elements_kind())); | 16955 DCHECK(IsExternalArrayElementsKind(map()->elements_kind())); |
16956 return Handle<JSArrayBuffer>::cast(result); | 16956 return Handle<JSArrayBuffer>::cast(result); |
16957 } | 16957 } |
16958 Handle<JSTypedArray> self(this); | 16958 Handle<JSTypedArray> self(this); |
16959 return MaterializeArrayBuffer(self); | 16959 return MaterializeArrayBuffer(self); |
16960 } | 16960 } |
16961 | 16961 |
16962 | 16962 |
16963 HeapType* PropertyCell::type() { | 16963 HeapType* PropertyCell::type() { |
16964 return static_cast<HeapType*>(type_raw()); | 16964 return static_cast<HeapType*>(type_raw()); |
16965 } | 16965 } |
16966 | 16966 |
16967 | 16967 |
16968 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { | 16968 void PropertyCell::set_type(HeapType* type, WriteBarrierMode ignored) { |
16969 ASSERT(IsPropertyCell()); | 16969 DCHECK(IsPropertyCell()); |
16970 set_type_raw(type, ignored); | 16970 set_type_raw(type, ignored); |
16971 } | 16971 } |
16972 | 16972 |
16973 | 16973 |
16974 Handle<HeapType> PropertyCell::UpdatedType(Handle<PropertyCell> cell, | 16974 Handle<HeapType> PropertyCell::UpdatedType(Handle<PropertyCell> cell, |
16975 Handle<Object> value) { | 16975 Handle<Object> value) { |
16976 Isolate* isolate = cell->GetIsolate(); | 16976 Isolate* isolate = cell->GetIsolate(); |
16977 Handle<HeapType> old_type(cell->type(), isolate); | 16977 Handle<HeapType> old_type(cell->type(), isolate); |
16978 Handle<HeapType> new_type = HeapType::Constant(value, isolate); | 16978 Handle<HeapType> new_type = HeapType::Constant(value, isolate); |
16979 | 16979 |
(...skipping 27 matching lines...) Expand all Loading... |
17007 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), | 17007 DependentCode::Insert(handle(cell->dependent_code(), info->isolate()), |
17008 DependentCode::kPropertyCellChangedGroup, | 17008 DependentCode::kPropertyCellChangedGroup, |
17009 info->object_wrapper()); | 17009 info->object_wrapper()); |
17010 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); | 17010 if (*codes != cell->dependent_code()) cell->set_dependent_code(*codes); |
17011 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( | 17011 info->dependencies(DependentCode::kPropertyCellChangedGroup)->Add( |
17012 cell, info->zone()); | 17012 cell, info->zone()); |
17013 } | 17013 } |
17014 | 17014 |
17015 | 17015 |
17016 const char* GetBailoutReason(BailoutReason reason) { | 17016 const char* GetBailoutReason(BailoutReason reason) { |
17017 ASSERT(reason < kLastErrorMessage); | 17017 DCHECK(reason < kLastErrorMessage); |
17018 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17018 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17019 static const char* error_messages_[] = { | 17019 static const char* error_messages_[] = { |
17020 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17020 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17021 }; | 17021 }; |
17022 #undef ERROR_MESSAGES_TEXTS | 17022 #undef ERROR_MESSAGES_TEXTS |
17023 return error_messages_[reason]; | 17023 return error_messages_[reason]; |
17024 } | 17024 } |
17025 | 17025 |
17026 | 17026 |
17027 } } // namespace v8::internal | 17027 } } // namespace v8::internal |
OLD | NEW |