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

Unified Diff: src/elements.cc

Issue 1612323003: Introduce {FAST,SLOW}_STRING_WRAPPER_ELEMENTS (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: one more DCHECK fix Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/elements.h ('k') | src/elements-kind.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/elements.cc
diff --git a/src/elements.cc b/src/elements.cc
index 16e8b067cf9273b15fc0dd291b4ad0471d47a721..45556d42c10152693be3a38d4e82ce58c4439d4f 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -40,7 +40,9 @@
// - SloppyArgumentsElementsAccessor
// - FastSloppyArgumentsElementsAccessor
// - SlowSloppyArgumentsElementsAccessor
-
+// - StringWrapperElementsAccessor
+// - FastStringWrapperElementsAccessor
+// - SlowStringWrapperElementsAccessor
namespace v8 {
namespace internal {
@@ -72,6 +74,10 @@ enum Where { AT_START, AT_END };
FixedArray) \
V(SlowSloppyArgumentsElementsAccessor, SLOW_SLOPPY_ARGUMENTS_ELEMENTS, \
FixedArray) \
+ V(FastStringWrapperElementsAccessor, FAST_STRING_WRAPPER_ELEMENTS, \
+ FixedArray) \
+ V(SlowStringWrapperElementsAccessor, SLOW_STRING_WRAPPER_ELEMENTS, \
+ FixedArray) \
V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \
V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \
V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \
@@ -83,7 +89,6 @@ enum Where { AT_START, AT_END };
V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
FixedUint8ClampedArray)
-
template<ElementsKind Kind> class ElementsKindTraits {
public:
typedef FixedArrayBase BackingStore;
@@ -230,15 +235,16 @@ static void CopyDoubleToObjectElements(FixedArrayBase* from_base,
Handle<FixedDoubleArray> from(FixedDoubleArray::cast(from_base), isolate);
Handle<FixedArray> to(FixedArray::cast(to_base), isolate);
- // create an outer loop to not waste too much time on creating HandleScopes
- // on the other hand we might overflow a single handle scope depending on
- // the copy_size
+ // Use an outer loop to not waste too much time on creating HandleScopes.
+ // On the other hand we might overflow a single handle scope depending on
+ // the copy_size.
int offset = 0;
while (offset < copy_size) {
HandleScope scope(isolate);
offset += 100;
for (int i = offset - 100; i < offset && i < copy_size; ++i) {
- Handle<Object> value = FixedDoubleArray::get(from, i + from_start);
+ Handle<Object> value =
+ FixedDoubleArray::get(*from, i + from_start, isolate);
to->set(i + to_start, *value, UPDATE_WRITE_BARRIER);
}
}
@@ -545,30 +551,22 @@ class ElementsAccessorBase : public ElementsAccessor {
*holder, *backing_store, index, filter) != kMaxUInt32;
}
- Handle<Object> Get(Handle<FixedArrayBase> backing_store,
- uint32_t entry) final {
- return ElementsAccessorSubclass::GetImpl(backing_store, entry);
+ Handle<Object> Get(Handle<JSObject> holder, uint32_t entry) final {
+ return ElementsAccessorSubclass::GetImpl(holder, entry);
}
- static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store,
- uint32_t entry) {
- uint32_t index = GetIndexForEntryImpl(*backing_store, entry);
- return BackingStore::get(Handle<BackingStore>::cast(backing_store), index);
+ static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
+ return ElementsAccessorSubclass::GetImpl(holder->elements(), entry);
}
- void Set(FixedArrayBase* backing_store, uint32_t entry, Object* value) final {
- ElementsAccessorSubclass::SetImpl(backing_store, entry, value);
+ static Handle<Object> GetImpl(FixedArrayBase* backing_store, uint32_t entry) {
+ Isolate* isolate = backing_store->GetIsolate();
+ uint32_t index = GetIndexForEntryImpl(backing_store, entry);
+ return handle(BackingStore::cast(backing_store)->get(index), isolate);
}
- static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
- Object* value) {
- UNREACHABLE();
- }
-
-
- static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
- Object* value, WriteBarrierMode mode) {
- UNREACHABLE();
+ void Set(Handle<JSObject> holder, uint32_t entry, Object* value) final {
+ ElementsAccessorSubclass::SetImpl(holder, entry, value);
}
void Reconfigure(Handle<JSObject> object, Handle<FixedArrayBase> store,
@@ -780,6 +778,7 @@ class ElementsAccessorBase : public ElementsAccessor {
DCHECK(IsFastDoubleElementsKind(from_kind) !=
IsFastDoubleElementsKind(kind()) ||
IsDictionaryElementsKind(from_kind) ||
+ from_kind == SLOW_STRING_WRAPPER_ELEMENTS ||
static_cast<uint32_t>(old_elements->length()) < capacity);
Handle<FixedArrayBase> elements =
ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
@@ -814,21 +813,6 @@ class ElementsAccessorBase : public ElementsAccessor {
UNREACHABLE();
}
- void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start,
- ElementsKind from_kind, Handle<FixedArrayBase> to,
- uint32_t to_start, int copy_size) final {
- DCHECK(!from.is_null());
- // NOTE: the ElementsAccessorSubclass::CopyElementsImpl() methods
- // violate the handlified function signature convention:
- // raw pointer parameters in the function that allocates. This is done
- // intentionally to avoid ArrayConcat() builtin performance degradation.
- // See the comment in another ElementsAccessorBase::CopyElements() for
- // details.
- ElementsAccessorSubclass::CopyElementsImpl(*from, from_start, *to,
- from_kind, to_start,
- kPackedSizeNotKnown, copy_size);
- }
-
void CopyElements(JSObject* from_holder, uint32_t from_start,
ElementsKind from_kind, Handle<FixedArrayBase> to,
uint32_t to_start, int copy_size) final {
@@ -861,6 +845,7 @@ class ElementsAccessorBase : public ElementsAccessor {
KeyAccumulator* keys, uint32_t range,
PropertyFilter filter,
uint32_t offset) {
+ DCHECK_NE(DICTIONARY_ELEMENTS, kind());
if (filter & ONLY_ALL_CAN_READ) {
// Non-dictionary elements can't have all-can-read accessors.
return;
@@ -875,8 +860,9 @@ class ElementsAccessorBase : public ElementsAccessor {
if (range < length) length = range;
for (uint32_t i = offset; i < length; i++) {
if (!ElementsAccessorSubclass::HasElementImpl(object, i, backing_store,
- filter))
+ filter)) {
continue;
+ }
keys->AddKey(i);
}
}
@@ -892,19 +878,8 @@ class ElementsAccessorBase : public ElementsAccessor {
void AddElementsToKeyAccumulator(Handle<JSObject> receiver,
KeyAccumulator* accumulator,
AddKeyConversion convert) final {
- Handle<FixedArrayBase> from(receiver->elements());
- uint32_t add_length =
- ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from);
- if (add_length == 0) return;
-
- for (uint32_t i = 0; i < add_length; i++) {
- if (!ElementsAccessorSubclass::HasEntryImpl(*from, i)) continue;
- Handle<Object> value = ElementsAccessorSubclass::GetImpl(from, i);
- DCHECK(!value->IsTheHole());
- DCHECK(!value->IsAccessorPair());
- DCHECK(!value->IsAccessorInfo());
- accumulator->AddKey(value, convert);
- }
+ ElementsAccessorSubclass::AddElementsToKeyAccumulatorImpl(
+ receiver, accumulator, convert);
}
static uint32_t GetCapacityImpl(JSObject* holder,
@@ -916,10 +891,6 @@ class ElementsAccessorBase : public ElementsAccessor {
return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store);
}
- static bool HasEntryImpl(FixedArrayBase* backing_store, uint32_t entry) {
- return true;
- }
-
static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store,
uint32_t entry) {
return entry;
@@ -956,9 +927,12 @@ class ElementsAccessorBase : public ElementsAccessor {
return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
}
- PropertyDetails GetDetails(FixedArrayBase* backing_store,
- uint32_t entry) final {
- return ElementsAccessorSubclass::GetDetailsImpl(backing_store, entry);
+ static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
+ return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
+ }
+
+ PropertyDetails GetDetails(JSObject* holder, uint32_t entry) final {
+ return ElementsAccessorSubclass::GetDetailsImpl(holder, entry);
}
private:
@@ -1053,15 +1027,22 @@ class DictionaryElementsAccessor
return backing_store->ValueAt(entry);
}
- static Handle<Object> GetImpl(Handle<FixedArrayBase> store, uint32_t entry) {
- Isolate* isolate = store->GetIsolate();
- return handle(GetRaw(*store, entry), isolate);
+ static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
+ return GetImpl(holder->elements(), entry);
}
- static inline void SetImpl(FixedArrayBase* store, uint32_t entry,
+ static Handle<Object> GetImpl(FixedArrayBase* backing_store, uint32_t entry) {
+ return handle(GetRaw(backing_store, entry), backing_store->GetIsolate());
+ }
+
+ static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
Object* value) {
- SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
- dictionary->ValueAtPut(entry, value);
+ SetImpl(holder->elements(), entry, value);
+ }
+
+ static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
+ Object* value) {
+ SeededNumberDictionary::cast(backing_store)->ValueAtPut(entry, value);
}
static void ReconfigureImpl(Handle<JSObject> object,
@@ -1082,7 +1063,7 @@ class DictionaryElementsAccessor
uint32_t new_capacity) {
PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
Handle<SeededNumberDictionary> dictionary =
- object->HasFastElements()
+ object->HasFastElements() || object->HasFastStringWrapperElements()
? JSObject::NormalizeElements(object)
: handle(SeededNumberDictionary::cast(object->elements()));
Handle<SeededNumberDictionary> new_dictionary =
@@ -1123,6 +1104,10 @@ class DictionaryElementsAccessor
return static_cast<uint32_t>(entry);
}
+ static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
+ return GetDetailsImpl(holder->elements(), entry);
+ }
+
static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
uint32_t entry) {
return SeededNumberDictionary::cast(backing_store)->DetailsAt(entry);
@@ -1159,6 +1144,24 @@ class DictionaryElementsAccessor
keys->SortCurrentElementsList();
}
+
+ static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
+ KeyAccumulator* accumulator,
+ AddKeyConversion convert) {
+ SeededNumberDictionary* dictionary =
+ SeededNumberDictionary::cast(receiver->elements());
+ int capacity = dictionary->Capacity();
+ for (int i = 0; i < capacity; i++) {
+ Object* k = dictionary->KeyAt(i);
+ if (!dictionary->IsKey(k)) continue;
+ if (dictionary->IsDeleted(i)) continue;
+ Object* value = dictionary->ValueAt(i);
+ DCHECK(!value->IsTheHole());
+ DCHECK(!value->IsAccessorPair());
+ DCHECK(!value->IsAccessorInfo());
+ accumulator->AddKey(value, convert);
+ }
+ }
};
@@ -1197,9 +1200,9 @@ class FastElementsAccessor
static void DeleteCommon(Handle<JSObject> obj, uint32_t entry,
Handle<FixedArrayBase> store) {
- DCHECK(obj->HasFastSmiOrObjectElements() ||
- obj->HasFastDoubleElements() ||
- obj->HasFastArgumentsElements());
+ DCHECK(obj->HasFastSmiOrObjectElements() || obj->HasFastDoubleElements() ||
+ obj->HasFastArgumentsElements() ||
+ obj->HasFastStringWrapperElements());
Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store);
if (!obj->IsJSArray() &&
entry == static_cast<uint32_t>(store->length()) - 1) {
@@ -1277,7 +1280,7 @@ class FastElementsAccessor
FastElementsAccessorSubclass::GrowCapacityAndConvertImpl(object,
new_capacity);
} else {
- if (from_kind != to_kind) {
+ if (IsFastElementsKind(from_kind) && from_kind != to_kind) {
JSObject::TransitionElementsKind(object, to_kind);
}
if (IsFastSmiOrObjectElementsKind(from_kind)) {
@@ -1285,7 +1288,7 @@ class FastElementsAccessor
JSObject::EnsureWritableFastElements(object);
}
}
- FastElementsAccessorSubclass::SetImpl(object->elements(), index, *value);
+ FastElementsAccessorSubclass::SetImpl(object, index, *value);
}
static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) {
@@ -1303,6 +1306,27 @@ class FastElementsAccessor
return !BackingStore::cast(backing_store)->is_the_hole(entry);
}
+ static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
+ KeyAccumulator* accumulator,
+ AddKeyConversion convert) {
+ uint32_t length = 0;
+ Handle<FixedArrayBase> elements(receiver->elements(),
+ receiver->GetIsolate());
+ if (receiver->IsJSArray()) {
+ length = Smi::cast(JSArray::cast(*receiver)->length())->value();
+ } else {
+ length =
+ FastElementsAccessorSubclass::GetCapacityImpl(*receiver, *elements);
+ }
+ for (uint32_t i = 0; i < length; i++) {
+ if (IsFastPackedElementsKind(KindTraits::Kind) ||
+ HasEntryImpl(*elements, i)) {
+ accumulator->AddKey(FastElementsAccessorSubclass::GetImpl(*elements, i),
+ convert);
+ }
+ }
+ }
+
static void ValidateContents(Handle<JSObject> holder, int length) {
#if DEBUG
Isolate* isolate = holder->GetIsolate();
@@ -1320,7 +1344,7 @@ class FastElementsAccessor
Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements);
if (IsFastSmiElementsKind(KindTraits::Kind)) {
for (int i = 0; i < length; i++) {
- DCHECK(BackingStore::get(backing_store, i)->IsSmi() ||
+ DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() ||
(IsFastHoleyElementsKind(KindTraits::Kind) &&
backing_store->is_the_hole(i)));
}
@@ -1480,7 +1504,7 @@ class FastElementsAccessor
int new_length = length - 1;
int remove_index = remove_position == AT_START ? 0 : new_length;
Handle<Object> result =
- FastElementsAccessorSubclass::GetImpl(backing_store, remove_index);
+ FastElementsAccessorSubclass::GetImpl(*backing_store, remove_index);
if (remove_position == AT_START) {
FastElementsAccessorSubclass::MoveElements(
isolate, receiver, backing_store, 0, 1, new_length, 0, 0);
@@ -1557,6 +1581,11 @@ class FastSmiOrObjectElementsAccessor
: FastElementsAccessor<FastElementsAccessorSubclass,
KindTraits>(name) {}
+ static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
+ Object* value) {
+ SetImpl(holder->elements(), entry, value);
+ }
+
static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
Object* value) {
FixedArray::cast(backing_store)->set(entry, value);
@@ -1613,6 +1642,7 @@ class FastSmiOrObjectElementsAccessor
case FAST_HOLEY_SMI_ELEMENTS:
case FAST_ELEMENTS:
case FAST_HOLEY_ELEMENTS:
+ case FAST_STRING_WRAPPER_ELEMENTS:
CopyObjectToObjectElements(from, from_kind, from_start, to, to_kind,
to_start, copy_size);
break;
@@ -1624,17 +1654,21 @@ class FastSmiOrObjectElementsAccessor
break;
}
case DICTIONARY_ELEMENTS:
+ case SLOW_STRING_WRAPPER_ELEMENTS:
CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start,
copy_size);
break;
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
- UNREACHABLE();
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
- case TYPE##_ELEMENTS: \
- UNREACHABLE();
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS:
TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
+ // This function is currently only used for JSArrays with non-zero
+ // length.
+ UNREACHABLE();
+ break;
+ case NO_ELEMENTS:
+ break; // Nothing to do.
}
}
};
@@ -1697,6 +1731,21 @@ class FastDoubleElementsAccessor
: FastElementsAccessor<FastElementsAccessorSubclass,
KindTraits>(name) {}
+ static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
+ return GetImpl(holder->elements(), entry);
+ }
+
+ static Handle<Object> GetImpl(FixedArrayBase* backing_store, uint32_t entry) {
+ Isolate* isolate = backing_store->GetIsolate();
+ return FixedDoubleArray::get(FixedDoubleArray::cast(backing_store), entry,
+ isolate);
+ }
+
+ static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
+ Object* value) {
+ SetImpl(holder->elements(), entry, value);
+ }
+
static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
Object* value) {
FixedDoubleArray::cast(backing_store)->set(entry, value->Number());
@@ -1759,13 +1808,16 @@ class FastDoubleElementsAccessor
break;
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
- UNREACHABLE();
-
-#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
- case TYPE##_ELEMENTS: \
- UNREACHABLE();
+ case FAST_STRING_WRAPPER_ELEMENTS:
+ case SLOW_STRING_WRAPPER_ELEMENTS:
+ case NO_ELEMENTS:
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) case TYPE##_ELEMENTS:
TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
+ // This function is currently only used for JSArrays with non-zero
+ // length.
+ UNREACHABLE();
+ break;
}
}
};
@@ -1808,6 +1860,11 @@ class TypedElementsAccessor
typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
typedef TypedElementsAccessor<Kind> AccessorClass;
+ static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
+ Object* value) {
+ SetImpl(holder->elements(), entry, value);
+ }
+
static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
Object* value) {
BackingStore::cast(backing_store)->SetValue(entry, value);
@@ -1818,10 +1875,16 @@ class TypedElementsAccessor
BackingStore::cast(backing_store)->SetValue(entry, value);
}
- static Handle<Object> GetImpl(Handle<FixedArrayBase> backing_store,
- uint32_t entry) {
- uint32_t index = GetIndexForEntryImpl(*backing_store, entry);
- return BackingStore::get(Handle<BackingStore>::cast(backing_store), index);
+ static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
+ return GetImpl(holder->elements(), entry);
+ }
+
+ static Handle<Object> GetImpl(FixedArrayBase* backing_store, uint32_t entry) {
+ return BackingStore::get(BackingStore::cast(backing_store), entry);
+ }
+
+ static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
+ return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
}
static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
@@ -1829,6 +1892,12 @@ class TypedElementsAccessor
return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
}
+ static bool HasElementImpl(Handle<JSObject> holder, uint32_t index,
+ Handle<FixedArrayBase> backing_store,
+ PropertyFilter filter) {
+ return index < AccessorClass::GetCapacityImpl(*holder, *backing_store);
+ }
+
static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array,
uint32_t length,
Handle<FixedArrayBase> backing_store) {
@@ -1859,6 +1928,18 @@ class TypedElementsAccessor
if (view->WasNeutered()) return 0;
return backing_store->length();
}
+
+ static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
+ KeyAccumulator* accumulator,
+ AddKeyConversion convert) {
+ Handle<FixedArrayBase> elements(receiver->elements(),
+ receiver->GetIsolate());
+ uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements);
+ for (uint32_t i = 0; i < length; i++) {
+ Handle<Object> value = AccessorClass::GetImpl(*elements, i);
+ accumulator->AddKey(value, convert);
+ }
+ }
};
@@ -1883,10 +1964,13 @@ class SloppyArgumentsElementsAccessor
USE(KindTraits::Kind);
}
- static Handle<Object> GetImpl(Handle<FixedArrayBase> parameters,
- uint32_t entry) {
+ static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
+ return GetImpl(holder->elements(), entry);
+ }
+
+ static Handle<Object> GetImpl(FixedArrayBase* parameters, uint32_t entry) {
Isolate* isolate = parameters->GetIsolate();
- Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
+ Handle<FixedArray> parameter_map(FixedArray::cast(parameters), isolate);
uint32_t length = parameter_map->length() - 2;
if (entry < length) {
DisallowHeapAllocation no_gc;
@@ -1897,10 +1981,8 @@ class SloppyArgumentsElementsAccessor
return handle(context->get(context_entry), isolate);
} else {
// Object is not mapped, defer to the arguments.
- Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
- isolate);
- Handle<Object> result =
- ArgumentsAccessor::GetImpl(arguments, entry - length);
+ Handle<Object> result = ArgumentsAccessor::GetImpl(
+ FixedArray::cast(parameter_map->get(1)), entry - length);
// Elements of the arguments object in slow mode might be slow aliases.
if (result->IsAliasedArgumentsEntry()) {
DisallowHeapAllocation no_gc;
@@ -1919,6 +2001,11 @@ class SloppyArgumentsElementsAccessor
UNREACHABLE();
}
+ static inline void SetImpl(Handle<JSObject> holder, uint32_t entry,
+ Object* value) {
+ SetImpl(holder->elements(), entry, value);
+ }
+
static inline void SetImpl(FixedArrayBase* store, uint32_t entry,
Object* value) {
FixedArray* parameter_map = FixedArray::cast(store);
@@ -1959,6 +2046,18 @@ class SloppyArgumentsElementsAccessor
ArgumentsAccessor::GetCapacityImpl(holder, arguments);
}
+ static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
+ KeyAccumulator* accumulator,
+ AddKeyConversion convert) {
+ FixedArrayBase* elements = receiver->elements();
+ uint32_t length = GetCapacityImpl(*receiver, elements);
+ for (uint32_t entry = 0; entry < length; entry++) {
+ if (!HasEntryImpl(elements, entry)) continue;
+ Handle<Object> value = GetImpl(elements, entry);
+ accumulator->AddKey(value, convert);
+ }
+ }
+
static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) {
FixedArray* parameter_map = FixedArray::cast(parameters);
uint32_t length = parameter_map->length() - 2;
@@ -1994,9 +2093,8 @@ class SloppyArgumentsElementsAccessor
return (parameter_map->length() - 2) + entry;
}
- static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
- uint32_t entry) {
- FixedArray* parameter_map = FixedArray::cast(parameters);
+ static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
+ FixedArray* parameter_map = FixedArray::cast(holder->elements());
uint32_t length = parameter_map->length() - 2;
if (entry < length) {
return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
@@ -2201,6 +2299,165 @@ class FastSloppyArgumentsElementsAccessor
}
};
+template <typename StringWrapperElementsAccessorSubclass,
+ typename BackingStoreAccessor, typename KindTraits>
+class StringWrapperElementsAccessor
+ : public ElementsAccessorBase<StringWrapperElementsAccessorSubclass,
+ KindTraits> {
+ public:
+ explicit StringWrapperElementsAccessor(const char* name)
+ : ElementsAccessorBase<StringWrapperElementsAccessorSubclass, KindTraits>(
+ name) {
+ USE(KindTraits::Kind);
+ }
+
+ static Handle<Object> GetImpl(Handle<JSObject> holder, uint32_t entry) {
+ Isolate* isolate = holder->GetIsolate();
+ Handle<String> string(GetString(*holder), isolate);
+ uint32_t length = static_cast<uint32_t>(string->length());
+ if (entry < length) {
+ return isolate->factory()->LookupSingleCharacterStringFromCode(
+ String::Flatten(string)->Get(entry));
+ }
+ return BackingStoreAccessor::GetImpl(holder, entry - length);
+ }
+
+ static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) {
+ uint32_t length = static_cast<uint32_t>(GetString(holder)->length());
+ if (entry < length) {
+ PropertyAttributes attributes =
+ static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
+ return PropertyDetails(attributes, v8::internal::DATA, 0,
+ PropertyCellType::kNoCell);
+ }
+ return BackingStoreAccessor::GetDetailsImpl(holder, entry - length);
+ }
+
+ static uint32_t GetEntryForIndexImpl(JSObject* holder,
+ FixedArrayBase* backing_store,
+ uint32_t index, PropertyFilter filter) {
+ uint32_t length = static_cast<uint32_t>(GetString(holder)->length());
+ if (index < length) return index;
+ uint32_t backing_store_entry = BackingStoreAccessor::GetEntryForIndexImpl(
+ holder, backing_store, index, filter);
+ if (backing_store_entry == kMaxUInt32) return kMaxUInt32;
+ DCHECK(backing_store_entry < kMaxUInt32 - length);
+ return backing_store_entry + length;
+ }
+
+ static void DeleteImpl(Handle<JSObject> holder, uint32_t entry) {
+ uint32_t length = static_cast<uint32_t>(GetString(*holder)->length());
+ if (entry < length) {
+ return; // String contents can't be deleted.
+ }
+ BackingStoreAccessor::DeleteImpl(holder, entry - length);
+ }
+
+ static void SetImpl(Handle<JSObject> holder, uint32_t entry, Object* value) {
+ uint32_t length = static_cast<uint32_t>(GetString(*holder)->length());
+ if (entry < length) {
+ return; // String contents are read-only.
+ }
+ BackingStoreAccessor::SetImpl(holder->elements(), entry - length, value);
+ }
+
+ static void AddImpl(Handle<JSObject> object, uint32_t index,
+ Handle<Object> value, PropertyAttributes attributes,
+ uint32_t new_capacity) {
+ DCHECK(index >= static_cast<uint32_t>(GetString(*object)->length()));
+ if ((KindTraits::Kind == FAST_STRING_WRAPPER_ELEMENTS &&
+ object->GetElementsKind() == SLOW_STRING_WRAPPER_ELEMENTS) ||
+ BackingStoreAccessor::GetCapacityImpl(*object, object->elements()) !=
+ new_capacity) {
+ StringWrapperElementsAccessorSubclass::GrowCapacityAndConvertImpl(
+ object, new_capacity);
+ }
+ BackingStoreAccessor::AddImpl(object, index, value, attributes,
+ new_capacity);
+ }
+
+ static void ReconfigureImpl(Handle<JSObject> object,
+ Handle<FixedArrayBase> store, uint32_t entry,
+ Handle<Object> value,
+ PropertyAttributes attributes) {
+ uint32_t length = static_cast<uint32_t>(GetString(*object)->length());
+ if (entry < length) {
+ return; // String contents can't be reconfigured.
+ }
+ BackingStoreAccessor::ReconfigureImpl(object, store, entry - length, value,
+ attributes);
+ }
+
+ static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
+ KeyAccumulator* accumulator,
+ AddKeyConversion convert) {
+ Isolate* isolate = receiver->GetIsolate();
+ Handle<String> string(GetString(*receiver), isolate);
+ string = String::Flatten(string);
+ uint32_t length = static_cast<uint32_t>(string->length());
+ for (uint32_t i = 0; i < length; i++) {
+ accumulator->AddKey(
+ isolate->factory()->LookupSingleCharacterStringFromCode(
+ string->Get(i)),
+ convert);
+ }
+ BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator,
+ convert);
+ }
+
+ static void CollectElementIndicesImpl(Handle<JSObject> object,
+ Handle<FixedArrayBase> backing_store,
+ KeyAccumulator* keys, uint32_t range,
+ PropertyFilter filter,
+ uint32_t offset) {
+ if ((filter & ONLY_ALL_CAN_READ) == 0) {
+ uint32_t length = GetString(*object)->length();
+ for (uint32_t i = 0; i < length; i++) {
+ keys->AddKey(i);
+ }
+ }
+ BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store, keys,
+ range, filter, offset);
+ }
+
+ static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
+ FixedArrayBase* to, ElementsKind from_kind,
+ uint32_t to_start, int packed_size,
+ int copy_size) {
+ BackingStoreAccessor::CopyElementsImpl(from, from_start, to, from_kind,
+ to_start, packed_size, copy_size);
+ }
+
+ private:
+ static String* GetString(JSObject* holder) {
+ DCHECK(holder->IsJSValue());
+ JSValue* js_value = JSValue::cast(holder);
+ DCHECK(js_value->value()->IsString());
+ return String::cast(js_value->value());
+ }
+};
+
+class FastStringWrapperElementsAccessor
+ : public StringWrapperElementsAccessor<
+ FastStringWrapperElementsAccessor, FastHoleyObjectElementsAccessor,
+ ElementsKindTraits<FAST_STRING_WRAPPER_ELEMENTS>> {
+ public:
+ explicit FastStringWrapperElementsAccessor(const char* name)
+ : StringWrapperElementsAccessor<
+ FastStringWrapperElementsAccessor, FastHoleyObjectElementsAccessor,
+ ElementsKindTraits<FAST_STRING_WRAPPER_ELEMENTS>>(name) {}
+};
+
+class SlowStringWrapperElementsAccessor
+ : public StringWrapperElementsAccessor<
+ SlowStringWrapperElementsAccessor, DictionaryElementsAccessor,
+ ElementsKindTraits<SLOW_STRING_WRAPPER_ELEMENTS>> {
+ public:
+ explicit SlowStringWrapperElementsAccessor(const char* name)
+ : StringWrapperElementsAccessor<
+ SlowStringWrapperElementsAccessor, DictionaryElementsAccessor,
+ ElementsKindTraits<SLOW_STRING_WRAPPER_ELEMENTS>>(name) {}
+};
} // namespace
« no previous file with comments | « src/elements.h ('k') | src/elements-kind.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698