| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 304 if (copy_size == 0) return; | 304 if (copy_size == 0) return; |
| 305 Isolate* isolate = from_base->GetIsolate(); | 305 Isolate* isolate = from_base->GetIsolate(); |
| 306 Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base); | 306 Handle<FixedDoubleArray> from = Handle<FixedDoubleArray>::cast(from_base); |
| 307 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); | 307 Handle<FixedArray> to = Handle<FixedArray>::cast(to_base); |
| 308 for (int i = 0; i < copy_size; ++i) { | 308 for (int i = 0; i < copy_size; ++i) { |
| 309 HandleScope scope(isolate); | 309 HandleScope scope(isolate); |
| 310 if (IsFastSmiElementsKind(to_kind)) { | 310 if (IsFastSmiElementsKind(to_kind)) { |
| 311 UNIMPLEMENTED(); | 311 UNIMPLEMENTED(); |
| 312 } else { | 312 } else { |
| 313 ASSERT(IsFastObjectElementsKind(to_kind)); | 313 ASSERT(IsFastObjectElementsKind(to_kind)); |
| 314 Handle<Object> value = from->get_as_handle(i + from_start); | 314 Handle<Object> value = FixedDoubleArray::get(from, i + from_start); |
| 315 to->set(i + to_start, *value, UPDATE_WRITE_BARRIER); | 315 to->set(i + to_start, *value, UPDATE_WRITE_BARRIER); |
| 316 } | 316 } |
| 317 } | 317 } |
| 318 } | 318 } |
| 319 | 319 |
| 320 | 320 |
| 321 static void CopyDoubleToDoubleElements(Handle<FixedArrayBase> from_base, | 321 static void CopyDoubleToDoubleElements(Handle<FixedArrayBase> from_base, |
| 322 uint32_t from_start, | 322 uint32_t from_start, |
| 323 Handle<FixedArrayBase> to_base, | 323 Handle<FixedArrayBase> to_base, |
| 324 uint32_t to_start, | 324 uint32_t to_start, |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 if (raw_frame->unchecked_code() == apply_builtin) { | 511 if (raw_frame->unchecked_code() == apply_builtin) { |
| 512 PrintF("apply from "); | 512 PrintF("apply from "); |
| 513 it.Advance(); | 513 it.Advance(); |
| 514 raw_frame = it.frame(); | 514 raw_frame = it.frame(); |
| 515 } | 515 } |
| 516 } | 516 } |
| 517 JavaScriptFrame::PrintTop(isolate, stdout, false, true); | 517 JavaScriptFrame::PrintTop(isolate, stdout, false, true); |
| 518 } | 518 } |
| 519 | 519 |
| 520 | 520 |
| 521 void CheckArrayAbuse(JSObject* obj, const char* op, uint32_t key, | 521 void CheckArrayAbuse(Handle<JSObject> obj, const char* op, uint32_t key, |
| 522 bool allow_appending) { | 522 bool allow_appending) { |
| 523 DisallowHeapAllocation no_allocation; |
| 523 Object* raw_length = NULL; | 524 Object* raw_length = NULL; |
| 524 const char* elements_type = "array"; | 525 const char* elements_type = "array"; |
| 525 if (obj->IsJSArray()) { | 526 if (obj->IsJSArray()) { |
| 526 JSArray* array = JSArray::cast(obj); | 527 JSArray* array = JSArray::cast(*obj); |
| 527 raw_length = array->length(); | 528 raw_length = array->length(); |
| 528 } else { | 529 } else { |
| 529 raw_length = Smi::FromInt(obj->elements()->length()); | 530 raw_length = Smi::FromInt(obj->elements()->length()); |
| 530 elements_type = "object"; | 531 elements_type = "object"; |
| 531 } | 532 } |
| 532 | 533 |
| 533 if (raw_length->IsNumber()) { | 534 if (raw_length->IsNumber()) { |
| 534 double n = raw_length->Number(); | 535 double n = raw_length->Number(); |
| 535 if (FastI2D(FastD2UI(n)) == n) { | 536 if (FastI2D(FastD2UI(n)) == n) { |
| 536 int32_t int32_length = DoubleToInt32(n); | 537 int32_t int32_length = DoubleToInt32(n); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 608 length = fixed_array_base->length(); | 609 length = fixed_array_base->length(); |
| 609 } | 610 } |
| 610 ElementsAccessorSubclass::ValidateContents(holder, length); | 611 ElementsAccessorSubclass::ValidateContents(holder, length); |
| 611 } | 612 } |
| 612 | 613 |
| 613 virtual void Validate(Handle<JSObject> holder) V8_FINAL V8_OVERRIDE { | 614 virtual void Validate(Handle<JSObject> holder) V8_FINAL V8_OVERRIDE { |
| 614 DisallowHeapAllocation no_gc; | 615 DisallowHeapAllocation no_gc; |
| 615 ElementsAccessorSubclass::ValidateImpl(*holder); | 616 ElementsAccessorSubclass::ValidateImpl(*holder); |
| 616 } | 617 } |
| 617 | 618 |
| 618 static bool HasElementImpl(Object* receiver, | 619 static bool HasElementImpl(Handle<Object> receiver, |
| 619 JSObject* holder, | 620 Handle<JSObject> holder, |
| 620 uint32_t key, | 621 uint32_t key, |
| 621 FixedArrayBase* backing_store) { | 622 Handle<FixedArrayBase> backing_store) { |
| 622 return ElementsAccessorSubclass::GetAttributesImpl( | 623 return ElementsAccessorSubclass::GetAttributesImpl( |
| 623 receiver, holder, key, backing_store) != ABSENT; | 624 *receiver, *holder, key, *backing_store) != ABSENT; |
| 624 } | 625 } |
| 625 | 626 |
| 626 virtual bool HasElement( | 627 virtual bool HasElement( |
| 627 Handle<Object> receiver, | 628 Handle<Object> receiver, |
| 628 Handle<JSObject> holder, | 629 Handle<JSObject> holder, |
| 629 uint32_t key, | 630 uint32_t key, |
| 630 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 631 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
| 631 // TODO(ishell): Handlify HasElementImpl(). | |
| 632 return ElementsAccessorSubclass::HasElementImpl( | 632 return ElementsAccessorSubclass::HasElementImpl( |
| 633 *receiver, *holder, key, *backing_store); | 633 receiver, holder, key, backing_store); |
| 634 } | 634 } |
| 635 | 635 |
| 636 // TODO(ishell): Temporary wrapper until handlified. | 636 // TODO(ishell): Temporary wrapper until handlified. |
| 637 MUST_USE_RESULT virtual Handle<Object> Get( | 637 MUST_USE_RESULT virtual Handle<Object> Get( |
| 638 Handle<Object> receiver, | 638 Handle<Object> receiver, |
| 639 Handle<JSObject> holder, | 639 Handle<JSObject> holder, |
| 640 uint32_t key, | 640 uint32_t key, |
| 641 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 641 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
| 642 CALL_HEAP_FUNCTION(holder->GetIsolate(), | |
| 643 Get(*receiver, *holder, key, *backing_store), | |
| 644 Object); | |
| 645 } | |
| 646 | |
| 647 MUST_USE_RESULT virtual MaybeObject* Get( | |
| 648 Object* receiver, | |
| 649 JSObject* holder, | |
| 650 uint32_t key, | |
| 651 FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE { | |
| 652 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && | 642 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && |
| 653 FLAG_trace_js_array_abuse) { | 643 FLAG_trace_js_array_abuse) { |
| 654 CheckArrayAbuse(holder, "elements read", key); | 644 CheckArrayAbuse(holder, "elements read", key); |
| 655 } | 645 } |
| 656 | 646 |
| 657 if (IsExternalArrayElementsKind(ElementsTraits::Kind) && | 647 if (IsExternalArrayElementsKind(ElementsTraits::Kind) && |
| 658 FLAG_trace_external_array_abuse) { | 648 FLAG_trace_external_array_abuse) { |
| 659 CheckArrayAbuse(holder, "external elements read", key); | 649 CheckArrayAbuse(holder, "external elements read", key); |
| 660 } | 650 } |
| 661 | 651 |
| 662 return ElementsAccessorSubclass::GetImpl( | 652 return ElementsAccessorSubclass::GetImpl( |
| 663 receiver, holder, key, backing_store); | 653 receiver, holder, key, backing_store); |
| 664 } | 654 } |
| 665 | 655 |
| 666 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, | 656 static Handle<Object> GetImpl(Handle<Object> receiver, |
| 667 JSObject* obj, | 657 Handle<JSObject> obj, |
| 668 uint32_t key, | 658 uint32_t key, |
| 669 FixedArrayBase* backing_store) { | 659 Handle<FixedArrayBase> backing_store) { |
| 670 return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) | 660 if (key < ElementsAccessorSubclass::GetCapacityImpl(*backing_store)) { |
| 671 ? BackingStore::cast(backing_store)->get(key) | 661 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
| 672 : backing_store->GetHeap()->the_hole_value(); | 662 } else { |
| 663 return backing_store->GetIsolate()->factory()->the_hole_value(); |
| 664 } |
| 673 } | 665 } |
| 674 | 666 |
| 675 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( | 667 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( |
| 676 Handle<Object> receiver, | 668 Handle<Object> receiver, |
| 677 Handle<JSObject> holder, | 669 Handle<JSObject> holder, |
| 678 uint32_t key, | 670 uint32_t key, |
| 679 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 671 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
| 680 return ElementsAccessorSubclass::GetAttributesImpl( | 672 return ElementsAccessorSubclass::GetAttributesImpl( |
| 681 *receiver, *holder, key, *backing_store); | 673 *receiver, *holder, key, *backing_store); |
| 682 } | 674 } |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 Handle<FixedArrayBase> from(from_holder->elements()); | 817 Handle<FixedArrayBase> from(from_holder->elements()); |
| 826 ElementsAccessorSubclass::CopyElementsImpl( | 818 ElementsAccessorSubclass::CopyElementsImpl( |
| 827 from, from_start, to, from_kind, to_start, packed_size, copy_size); | 819 from, from_start, to, from_kind, to_start, packed_size, copy_size); |
| 828 } | 820 } |
| 829 | 821 |
| 830 virtual Handle<FixedArray> AddElementsToFixedArray( | 822 virtual Handle<FixedArray> AddElementsToFixedArray( |
| 831 Handle<Object> receiver, | 823 Handle<Object> receiver, |
| 832 Handle<JSObject> holder, | 824 Handle<JSObject> holder, |
| 833 Handle<FixedArray> to, | 825 Handle<FixedArray> to, |
| 834 Handle<FixedArrayBase> from) V8_FINAL V8_OVERRIDE { | 826 Handle<FixedArrayBase> from) V8_FINAL V8_OVERRIDE { |
| 835 CALL_HEAP_FUNCTION(to->GetIsolate(), | |
| 836 AddElementsToFixedArray( | |
| 837 receiver.is_null() ? NULL : *receiver, | |
| 838 holder.is_null() ? NULL : *holder, | |
| 839 *to, | |
| 840 *from), | |
| 841 FixedArray); | |
| 842 } | |
| 843 | |
| 844 static MUST_USE_RESULT MaybeObject* AddElementsToFixedArray( | |
| 845 Object* receiver, | |
| 846 JSObject* holder, | |
| 847 FixedArray* to, | |
| 848 FixedArrayBase* from) { | |
| 849 int len0 = to->length(); | 827 int len0 = to->length(); |
| 850 #ifdef ENABLE_SLOW_ASSERTS | 828 #ifdef ENABLE_SLOW_ASSERTS |
| 851 if (FLAG_enable_slow_asserts) { | 829 if (FLAG_enable_slow_asserts) { |
| 852 for (int i = 0; i < len0; i++) { | 830 for (int i = 0; i < len0; i++) { |
| 853 ASSERT(!to->get(i)->IsTheHole()); | 831 ASSERT(!to->get(i)->IsTheHole()); |
| 854 } | 832 } |
| 855 } | 833 } |
| 856 #endif | 834 #endif |
| 857 | 835 |
| 858 // Optimize if 'other' is empty. | 836 // Optimize if 'other' is empty. |
| 859 // We cannot optimize if 'this' is empty, as other may have holes. | 837 // We cannot optimize if 'this' is empty, as other may have holes. |
| 860 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from); | 838 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*from); |
| 861 if (len1 == 0) return to; | 839 if (len1 == 0) return to; |
| 862 | 840 |
| 863 // Compute how many elements are not in other. | 841 // Compute how many elements are not in other. |
| 864 uint32_t extra = 0; | 842 uint32_t extra = 0; |
| 865 for (uint32_t y = 0; y < len1; y++) { | 843 for (uint32_t y = 0; y < len1; y++) { |
| 866 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); | 844 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
| 867 if (ElementsAccessorSubclass::HasElementImpl( | 845 if (ElementsAccessorSubclass::HasElementImpl( |
| 868 receiver, holder, key, from)) { | 846 receiver, holder, key, from)) { |
| 869 MaybeObject* maybe_value = | 847 Handle<Object> value = |
| 870 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); | 848 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
| 871 Object* value; | 849 |
| 872 if (!maybe_value->To(&value)) return maybe_value; | |
| 873 ASSERT(!value->IsTheHole()); | 850 ASSERT(!value->IsTheHole()); |
| 874 if (!HasKey(to, value)) { | 851 if (!HasKey(*to, *value)) { |
| 875 extra++; | 852 extra++; |
| 876 } | 853 } |
| 877 } | 854 } |
| 878 } | 855 } |
| 879 | 856 |
| 880 if (extra == 0) return to; | 857 if (extra == 0) return to; |
| 881 | 858 |
| 882 // Allocate the result | 859 // Allocate the result |
| 883 FixedArray* result; | 860 Isolate* isolate = from->GetIsolate(); |
| 884 MaybeObject* maybe_obj = from->GetHeap()->AllocateFixedArray(len0 + extra); | 861 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); |
| 885 if (!maybe_obj->To(&result)) return maybe_obj; | |
| 886 | 862 |
| 887 // Fill in the content | 863 // Fill in the content |
| 888 { | 864 { |
| 889 DisallowHeapAllocation no_gc; | 865 DisallowHeapAllocation no_gc; |
| 890 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 866 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 891 for (int i = 0; i < len0; i++) { | 867 for (int i = 0; i < len0; i++) { |
| 892 Object* e = to->get(i); | 868 Object* e = to->get(i); |
| 893 ASSERT(e->IsString() || e->IsNumber()); | 869 ASSERT(e->IsString() || e->IsNumber()); |
| 894 result->set(i, e, mode); | 870 result->set(i, e, mode); |
| 895 } | 871 } |
| 896 } | 872 } |
| 897 // Fill in the extra values. | 873 // Fill in the extra values. |
| 898 uint32_t index = 0; | 874 uint32_t index = 0; |
| 899 for (uint32_t y = 0; y < len1; y++) { | 875 for (uint32_t y = 0; y < len1; y++) { |
| 900 uint32_t key = | 876 uint32_t key = |
| 901 ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); | 877 ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
| 902 if (ElementsAccessorSubclass::HasElementImpl( | 878 if (ElementsAccessorSubclass::HasElementImpl( |
| 903 receiver, holder, key, from)) { | 879 receiver, holder, key, from)) { |
| 904 MaybeObject* maybe_value = | 880 Handle<Object> value = |
| 905 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); | 881 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
| 906 Object* value; | 882 if (!value->IsTheHole() && !HasKey(*to, *value)) { |
| 907 if (!maybe_value->To(&value)) return maybe_value; | 883 result->set(len0 + index, *value); |
| 908 if (!value->IsTheHole() && !HasKey(to, value)) { | |
| 909 result->set(len0 + index, value); | |
| 910 index++; | 884 index++; |
| 911 } | 885 } |
| 912 } | 886 } |
| 913 } | 887 } |
| 914 ASSERT(extra == index); | 888 ASSERT(extra == index); |
| 915 return result; | 889 return result; |
| 916 } | 890 } |
| 917 | 891 |
| 918 protected: | 892 protected: |
| 919 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { | 893 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1030 Heap* heap = obj->GetHeap(); | 1004 Heap* heap = obj->GetHeap(); |
| 1031 Handle<FixedArrayBase> elements(obj->elements()); | 1005 Handle<FixedArrayBase> elements(obj->elements()); |
| 1032 if (*elements == heap->empty_fixed_array()) { | 1006 if (*elements == heap->empty_fixed_array()) { |
| 1033 return isolate->factory()->true_value(); | 1007 return isolate->factory()->true_value(); |
| 1034 } | 1008 } |
| 1035 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); | 1009 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); |
| 1036 bool is_sloppy_arguments_elements_map = | 1010 bool is_sloppy_arguments_elements_map = |
| 1037 backing_store->map() == heap->sloppy_arguments_elements_map(); | 1011 backing_store->map() == heap->sloppy_arguments_elements_map(); |
| 1038 if (is_sloppy_arguments_elements_map) { | 1012 if (is_sloppy_arguments_elements_map) { |
| 1039 backing_store = handle( | 1013 backing_store = handle( |
| 1040 BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1))); | 1014 BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1)), |
| 1015 isolate); |
| 1041 } | 1016 } |
| 1042 uint32_t length = static_cast<uint32_t>( | 1017 uint32_t length = static_cast<uint32_t>( |
| 1043 obj->IsJSArray() | 1018 obj->IsJSArray() |
| 1044 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() | 1019 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() |
| 1045 : backing_store->length()); | 1020 : backing_store->length()); |
| 1046 if (key < length) { | 1021 if (key < length) { |
| 1047 if (!is_sloppy_arguments_elements_map) { | 1022 if (!is_sloppy_arguments_elements_map) { |
| 1048 ElementsKind kind = KindTraits::Kind; | 1023 ElementsKind kind = KindTraits::Kind; |
| 1049 if (IsFastPackedElementsKind(kind)) { | 1024 if (IsFastPackedElementsKind(kind)) { |
| 1050 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); | 1025 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1079 } | 1054 } |
| 1080 | 1055 |
| 1081 virtual Handle<Object> Delete( | 1056 virtual Handle<Object> Delete( |
| 1082 Handle<JSObject> obj, | 1057 Handle<JSObject> obj, |
| 1083 uint32_t key, | 1058 uint32_t key, |
| 1084 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { | 1059 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { |
| 1085 return DeleteCommon(obj, key, mode); | 1060 return DeleteCommon(obj, key, mode); |
| 1086 } | 1061 } |
| 1087 | 1062 |
| 1088 static bool HasElementImpl( | 1063 static bool HasElementImpl( |
| 1089 Object* receiver, | 1064 Handle<Object> receiver, |
| 1090 JSObject* holder, | 1065 Handle<JSObject> holder, |
| 1091 uint32_t key, | 1066 uint32_t key, |
| 1092 FixedArrayBase* backing_store) { | 1067 Handle<FixedArrayBase> backing_store) { |
| 1093 if (key >= static_cast<uint32_t>(backing_store->length())) { | 1068 if (key >= static_cast<uint32_t>(backing_store->length())) { |
| 1094 return false; | 1069 return false; |
| 1095 } | 1070 } |
| 1096 return !BackingStore::cast(backing_store)->is_the_hole(key); | 1071 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key); |
| 1097 } | 1072 } |
| 1098 | 1073 |
| 1099 static void ValidateContents(JSObject* holder, int length) { | 1074 static void ValidateContents(JSObject* holder, int length) { |
| 1100 #if DEBUG | 1075 #if DEBUG |
| 1101 FixedArrayBase* elements = holder->elements(); | 1076 FixedArrayBase* elements = holder->elements(); |
| 1102 Heap* heap = elements->GetHeap(); | 1077 Heap* heap = elements->GetHeap(); |
| 1103 Map* map = elements->map(); | 1078 Map* map = elements->map(); |
| 1104 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && | 1079 ASSERT((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && |
| 1105 (map == heap->fixed_array_map() || | 1080 (map == heap->fixed_array_map() || |
| 1106 map == heap->fixed_cow_array_map())) || | 1081 map == heap->fixed_cow_array_map())) || |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1366 : ElementsAccessorBase<AccessorClass, | 1341 : ElementsAccessorBase<AccessorClass, |
| 1367 ElementsKindTraits<Kind> >(name) {} | 1342 ElementsKindTraits<Kind> >(name) {} |
| 1368 | 1343 |
| 1369 protected: | 1344 protected: |
| 1370 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; | 1345 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; |
| 1371 typedef TypedElementsAccessor<Kind> AccessorClass; | 1346 typedef TypedElementsAccessor<Kind> AccessorClass; |
| 1372 | 1347 |
| 1373 friend class ElementsAccessorBase<AccessorClass, | 1348 friend class ElementsAccessorBase<AccessorClass, |
| 1374 ElementsKindTraits<Kind> >; | 1349 ElementsKindTraits<Kind> >; |
| 1375 | 1350 |
| 1376 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, | 1351 static Handle<Object> GetImpl(Handle<Object> receiver, |
| 1377 JSObject* obj, | 1352 Handle<JSObject> obj, |
| 1378 uint32_t key, | 1353 uint32_t key, |
| 1379 FixedArrayBase* backing_store) { | 1354 Handle<FixedArrayBase> backing_store) { |
| 1380 return | 1355 if (key < AccessorClass::GetCapacityImpl(*backing_store)) { |
| 1381 key < AccessorClass::GetCapacityImpl(backing_store) | 1356 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
| 1382 ? BackingStore::cast(backing_store)->get(key) | 1357 } else { |
| 1383 : backing_store->GetHeap()->undefined_value(); | 1358 return backing_store->GetIsolate()->factory()->undefined_value(); |
| 1359 } |
| 1384 } | 1360 } |
| 1385 | 1361 |
| 1386 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1362 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
| 1387 Object* receiver, | 1363 Object* receiver, |
| 1388 JSObject* obj, | 1364 JSObject* obj, |
| 1389 uint32_t key, | 1365 uint32_t key, |
| 1390 FixedArrayBase* backing_store) { | 1366 FixedArrayBase* backing_store) { |
| 1391 return | 1367 return |
| 1392 key < AccessorClass::GetCapacityImpl(backing_store) | 1368 key < AccessorClass::GetCapacityImpl(backing_store) |
| 1393 ? NONE : ABSENT; | 1369 ? NONE : ABSENT; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1413 } | 1389 } |
| 1414 | 1390 |
| 1415 MUST_USE_RESULT virtual Handle<Object> Delete( | 1391 MUST_USE_RESULT virtual Handle<Object> Delete( |
| 1416 Handle<JSObject> obj, | 1392 Handle<JSObject> obj, |
| 1417 uint32_t key, | 1393 uint32_t key, |
| 1418 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { | 1394 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { |
| 1419 // External arrays always ignore deletes. | 1395 // External arrays always ignore deletes. |
| 1420 return obj->GetIsolate()->factory()->true_value(); | 1396 return obj->GetIsolate()->factory()->true_value(); |
| 1421 } | 1397 } |
| 1422 | 1398 |
| 1423 static bool HasElementImpl(Object* receiver, | 1399 static bool HasElementImpl(Handle<Object> receiver, |
| 1424 JSObject* holder, | 1400 Handle<JSObject> holder, |
| 1425 uint32_t key, | 1401 uint32_t key, |
| 1426 FixedArrayBase* backing_store) { | 1402 Handle<FixedArrayBase> backing_store) { |
| 1427 uint32_t capacity = | 1403 uint32_t capacity = |
| 1428 AccessorClass::GetCapacityImpl(backing_store); | 1404 AccessorClass::GetCapacityImpl(*backing_store); |
| 1429 return key < capacity; | 1405 return key < capacity; |
| 1430 } | 1406 } |
| 1431 }; | 1407 }; |
| 1432 | 1408 |
| 1433 | 1409 |
| 1434 | 1410 |
| 1435 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 1411 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
| 1436 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ | 1412 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ |
| 1437 External##Type##ElementsAccessor; | 1413 External##Type##ElementsAccessor; |
| 1438 | 1414 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1597 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 1573 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
| 1598 ElementsKindTraits<DICTIONARY_ELEMENTS> >; | 1574 ElementsKindTraits<DICTIONARY_ELEMENTS> >; |
| 1599 | 1575 |
| 1600 MUST_USE_RESULT virtual Handle<Object> Delete( | 1576 MUST_USE_RESULT virtual Handle<Object> Delete( |
| 1601 Handle<JSObject> obj, | 1577 Handle<JSObject> obj, |
| 1602 uint32_t key, | 1578 uint32_t key, |
| 1603 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { | 1579 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { |
| 1604 return DeleteCommon(obj, key, mode); | 1580 return DeleteCommon(obj, key, mode); |
| 1605 } | 1581 } |
| 1606 | 1582 |
| 1607 MUST_USE_RESULT static MaybeObject* GetImpl( | 1583 static Handle<Object> GetImpl( |
| 1608 Object* receiver, | 1584 Handle<Object> receiver, |
| 1609 JSObject* obj, | 1585 Handle<JSObject> obj, |
| 1610 uint32_t key, | 1586 uint32_t key, |
| 1611 FixedArrayBase* store) { | 1587 Handle<FixedArrayBase> store) { |
| 1612 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); | 1588 Handle<SeededNumberDictionary> backing_store = |
| 1589 Handle<SeededNumberDictionary>::cast(store); |
| 1590 Isolate* isolate = backing_store->GetIsolate(); |
| 1613 int entry = backing_store->FindEntry(key); | 1591 int entry = backing_store->FindEntry(key); |
| 1614 if (entry != SeededNumberDictionary::kNotFound) { | 1592 if (entry != SeededNumberDictionary::kNotFound) { |
| 1615 Object* element = backing_store->ValueAt(entry); | 1593 Handle<Object> element(backing_store->ValueAt(entry), isolate); |
| 1616 PropertyDetails details = backing_store->DetailsAt(entry); | 1594 PropertyDetails details = backing_store->DetailsAt(entry); |
| 1617 if (details.type() == CALLBACKS) { | 1595 if (details.type() == CALLBACKS) { |
| 1618 return obj->GetElementWithCallback(receiver, | 1596 return JSObject::GetElementWithCallback( |
| 1619 element, | 1597 obj, receiver, element, key, obj); |
| 1620 key, | |
| 1621 obj); | |
| 1622 } else { | 1598 } else { |
| 1623 return element; | 1599 return element; |
| 1624 } | 1600 } |
| 1625 } | 1601 } |
| 1626 return obj->GetHeap()->the_hole_value(); | 1602 return isolate->factory()->the_hole_value(); |
| 1627 } | 1603 } |
| 1628 | 1604 |
| 1629 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1605 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
| 1630 Object* receiver, | 1606 Object* receiver, |
| 1631 JSObject* obj, | 1607 JSObject* obj, |
| 1632 uint32_t key, | 1608 uint32_t key, |
| 1633 FixedArrayBase* backing_store) { | 1609 FixedArrayBase* backing_store) { |
| 1634 SeededNumberDictionary* dictionary = | 1610 SeededNumberDictionary* dictionary = |
| 1635 SeededNumberDictionary::cast(backing_store); | 1611 SeededNumberDictionary::cast(backing_store); |
| 1636 int entry = dictionary->FindEntry(key); | 1612 int entry = dictionary->FindEntry(key); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1662 Handle<SeededNumberDictionary>::cast(store); | 1638 Handle<SeededNumberDictionary>::cast(store); |
| 1663 int entry = backing_store->FindEntry(key); | 1639 int entry = backing_store->FindEntry(key); |
| 1664 if (entry != SeededNumberDictionary::kNotFound && | 1640 if (entry != SeededNumberDictionary::kNotFound && |
| 1665 backing_store->DetailsAt(entry).type() == CALLBACKS && | 1641 backing_store->DetailsAt(entry).type() == CALLBACKS && |
| 1666 backing_store->ValueAt(entry)->IsAccessorPair()) { | 1642 backing_store->ValueAt(entry)->IsAccessorPair()) { |
| 1667 return handle(AccessorPair::cast(backing_store->ValueAt(entry))); | 1643 return handle(AccessorPair::cast(backing_store->ValueAt(entry))); |
| 1668 } | 1644 } |
| 1669 return MaybeHandle<AccessorPair>(); | 1645 return MaybeHandle<AccessorPair>(); |
| 1670 } | 1646 } |
| 1671 | 1647 |
| 1672 static bool HasElementImpl(Object* receiver, | 1648 static bool HasElementImpl(Handle<Object> receiver, |
| 1673 JSObject* holder, | 1649 Handle<JSObject> holder, |
| 1674 uint32_t key, | 1650 uint32_t key, |
| 1675 FixedArrayBase* backing_store) { | 1651 Handle<FixedArrayBase> store) { |
| 1676 return SeededNumberDictionary::cast(backing_store)->FindEntry(key) != | 1652 Handle<SeededNumberDictionary> backing_store = |
| 1677 SeededNumberDictionary::kNotFound; | 1653 Handle<SeededNumberDictionary>::cast(store); |
| 1654 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; |
| 1678 } | 1655 } |
| 1679 | 1656 |
| 1680 // TODO(ishell): Handlify when all callers are handlified. | 1657 // TODO(ishell): Handlify when all callers are handlified. |
| 1681 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, | 1658 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, |
| 1682 uint32_t index) { | 1659 uint32_t index) { |
| 1683 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1660 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
| 1684 Object* key = dict->KeyAt(index); | 1661 Object* key = dict->KeyAt(index); |
| 1685 return Smi::cast(key)->value(); | 1662 return Smi::cast(key)->value(); |
| 1686 } | 1663 } |
| 1687 }; | 1664 }; |
| 1688 | 1665 |
| 1689 | 1666 |
| 1690 class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< | 1667 class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
| 1691 SloppyArgumentsElementsAccessor, | 1668 SloppyArgumentsElementsAccessor, |
| 1692 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > { | 1669 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > { |
| 1693 public: | 1670 public: |
| 1694 explicit SloppyArgumentsElementsAccessor(const char* name) | 1671 explicit SloppyArgumentsElementsAccessor(const char* name) |
| 1695 : ElementsAccessorBase< | 1672 : ElementsAccessorBase< |
| 1696 SloppyArgumentsElementsAccessor, | 1673 SloppyArgumentsElementsAccessor, |
| 1697 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} | 1674 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} |
| 1698 protected: | 1675 protected: |
| 1699 friend class ElementsAccessorBase< | 1676 friend class ElementsAccessorBase< |
| 1700 SloppyArgumentsElementsAccessor, | 1677 SloppyArgumentsElementsAccessor, |
| 1701 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >; | 1678 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >; |
| 1702 | 1679 |
| 1703 MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, | 1680 MUST_USE_RESULT static Handle<Object> GetImpl( |
| 1704 JSObject* obj, | 1681 Handle<Object> receiver, |
| 1705 uint32_t key, | 1682 Handle<JSObject> obj, |
| 1706 FixedArrayBase* parameters) { | 1683 uint32_t key, |
| 1707 FixedArray* parameter_map = FixedArray::cast(parameters); | 1684 Handle<FixedArrayBase> parameters) { |
| 1708 Object* probe = GetParameterMapArg(obj, parameter_map, key); | 1685 Isolate* isolate = obj->GetIsolate(); |
| 1686 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
| 1687 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); |
| 1709 if (!probe->IsTheHole()) { | 1688 if (!probe->IsTheHole()) { |
| 1689 DisallowHeapAllocation no_gc; |
| 1710 Context* context = Context::cast(parameter_map->get(0)); | 1690 Context* context = Context::cast(parameter_map->get(0)); |
| 1711 int context_index = Smi::cast(probe)->value(); | 1691 int context_index = Handle<Smi>::cast(probe)->value(); |
| 1712 ASSERT(!context->get(context_index)->IsTheHole()); | 1692 ASSERT(!context->get(context_index)->IsTheHole()); |
| 1713 return context->get(context_index); | 1693 return handle(context->get(context_index), isolate); |
| 1714 } else { | 1694 } else { |
| 1715 // Object is not mapped, defer to the arguments. | 1695 // Object is not mapped, defer to the arguments. |
| 1716 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1696 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), |
| 1717 MaybeObject* maybe_result = ElementsAccessor::ForArray(arguments)->Get( | 1697 isolate); |
| 1698 Handle<Object> result = ElementsAccessor::ForArray(arguments)->Get( |
| 1718 receiver, obj, key, arguments); | 1699 receiver, obj, key, arguments); |
| 1719 Object* result; | |
| 1720 if (!maybe_result->ToObject(&result)) return maybe_result; | |
| 1721 // Elements of the arguments object in slow mode might be slow aliases. | 1700 // Elements of the arguments object in slow mode might be slow aliases. |
| 1722 if (result->IsAliasedArgumentsEntry()) { | 1701 if (result->IsAliasedArgumentsEntry()) { |
| 1723 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(result); | 1702 DisallowHeapAllocation no_gc; |
| 1703 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); |
| 1724 Context* context = Context::cast(parameter_map->get(0)); | 1704 Context* context = Context::cast(parameter_map->get(0)); |
| 1725 int context_index = entry->aliased_context_slot(); | 1705 int context_index = entry->aliased_context_slot(); |
| 1726 ASSERT(!context->get(context_index)->IsTheHole()); | 1706 ASSERT(!context->get(context_index)->IsTheHole()); |
| 1727 return context->get(context_index); | 1707 return handle(context->get(context_index), isolate); |
| 1728 } else { | 1708 } else { |
| 1729 return result; | 1709 return result; |
| 1730 } | 1710 } |
| 1731 } | 1711 } |
| 1732 } | 1712 } |
| 1733 | 1713 |
| 1734 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1714 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
| 1735 Object* receiver, | 1715 Object* receiver, |
| 1736 JSObject* obj, | 1716 JSObject* obj, |
| 1737 uint32_t key, | 1717 uint32_t key, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1834 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1814 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
| 1835 ForArray(arguments)->GetCapacity(arguments)); | 1815 ForArray(arguments)->GetCapacity(arguments)); |
| 1836 } | 1816 } |
| 1837 | 1817 |
| 1838 // TODO(ishell): Handlify when all callers are handlified. | 1818 // TODO(ishell): Handlify when all callers are handlified. |
| 1839 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, | 1819 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, |
| 1840 uint32_t index) { | 1820 uint32_t index) { |
| 1841 return index; | 1821 return index; |
| 1842 } | 1822 } |
| 1843 | 1823 |
| 1844 static bool HasElementImpl(Object* receiver, | 1824 static bool HasElementImpl(Handle<Object> receiver, |
| 1845 JSObject* holder, | 1825 Handle<JSObject> holder, |
| 1846 uint32_t key, | 1826 uint32_t key, |
| 1847 FixedArrayBase* parameters) { | 1827 Handle<FixedArrayBase> parameters) { |
| 1848 FixedArray* parameter_map = FixedArray::cast(parameters); | 1828 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
| 1849 Object* probe = GetParameterMapArg(holder, parameter_map, key); | 1829 Handle<Object> probe = GetParameterMapArg(holder, parameter_map, key); |
| 1850 if (!probe->IsTheHole()) { | 1830 if (!probe->IsTheHole()) { |
| 1851 return true; | 1831 return true; |
| 1852 } else { | 1832 } else { |
| 1853 FixedArrayBase* arguments = | 1833 Handle<FixedArrayBase> arguments(FixedArrayBase::cast( |
| 1854 FixedArrayBase::cast(FixedArray::cast(parameter_map)->get(1)); | 1834 Handle<FixedArray>::cast(parameter_map)->get(1))); |
| 1855 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); | 1835 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
| 1856 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); | 1836 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); |
| 1857 } | 1837 } |
| 1858 } | 1838 } |
| 1859 | 1839 |
| 1860 private: | 1840 private: |
| 1861 // TODO(ishell): remove when all usages are handlified. | 1841 // TODO(ishell): remove when all usages are handlified. |
| 1862 static Object* GetParameterMapArg(JSObject* holder, | 1842 static Object* GetParameterMapArg(JSObject* holder, |
| 1863 FixedArray* parameter_map, | 1843 FixedArray* parameter_map, |
| 1864 uint32_t key) { | 1844 uint32_t key) { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2064 UNREACHABLE(); | 2044 UNREACHABLE(); |
| 2065 break; | 2045 break; |
| 2066 } | 2046 } |
| 2067 | 2047 |
| 2068 array->set_elements(*elms); | 2048 array->set_elements(*elms); |
| 2069 array->set_length(Smi::FromInt(number_of_elements)); | 2049 array->set_length(Smi::FromInt(number_of_elements)); |
| 2070 return array; | 2050 return array; |
| 2071 } | 2051 } |
| 2072 | 2052 |
| 2073 } } // namespace v8::internal | 2053 } } // namespace v8::internal |
| OLD | NEW |