|
@ -146,36 +146,33 @@ static Failure* ThrowArrayLengthRangeError(Heap* heap) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void CopyObjectToObjectElements(FixedArrayBase* from_base, |
|
|
void CopyObjectToObjectElements(FixedArray* from, |
|
|
ElementsKind from_kind, |
|
|
ElementsKind from_kind, |
|
|
uint32_t from_start, |
|
|
uint32_t from_start, |
|
|
FixedArrayBase* to_base, |
|
|
FixedArray* to, |
|
|
ElementsKind to_kind, |
|
|
ElementsKind to_kind, |
|
|
uint32_t to_start, |
|
|
uint32_t to_start, |
|
|
int raw_copy_size) { |
|
|
int raw_copy_size) { |
|
|
ASSERT(to_base->map() != HEAP->fixed_cow_array_map()); |
|
|
ASSERT(to->map() != HEAP->fixed_cow_array_map()); |
|
|
AssertNoAllocation no_allocation; |
|
|
|
|
|
int copy_size = raw_copy_size; |
|
|
int copy_size = raw_copy_size; |
|
|
if (raw_copy_size < 0) { |
|
|
if (raw_copy_size < 0) { |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
copy_size = Min(from_base->length() - from_start, |
|
|
copy_size = Min(from->length() - from_start, |
|
|
to_base->length() - to_start); |
|
|
to->length() - to_start); |
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
// FAST_*_ELEMENTS arrays cannot be uninitialized. Ensure they are already
|
|
|
|
|
|
// marked with the hole.
|
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
int start = to_start + copy_size; |
|
|
for (int i = to_start + copy_size; i < to->length(); ++i) { |
|
|
int length = to_base->length() - start; |
|
|
ASSERT(to->get(i)->IsTheHole()); |
|
|
if (length > 0) { |
|
|
|
|
|
Heap* heap = from_base->GetHeap(); |
|
|
|
|
|
MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
|
|
|
|
|
heap->the_hole_value(), length); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
#endif |
|
|
} |
|
|
} |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
|
|
(copy_size + static_cast<int>(from_start)) <= from_base->length()); |
|
|
(copy_size + static_cast<int>(from_start)) <= from->length()); |
|
|
if (copy_size == 0) return; |
|
|
if (copy_size == 0) return; |
|
|
FixedArray* from = FixedArray::cast(from_base); |
|
|
|
|
|
FixedArray* to = FixedArray::cast(to_base); |
|
|
|
|
|
ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); |
|
|
ASSERT(IsFastSmiOrObjectElementsKind(from_kind)); |
|
|
ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
|
|
ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
|
|
Address to_address = to->address() + FixedArray::kHeaderSize; |
|
|
Address to_address = to->address() + FixedArray::kHeaderSize; |
|
@ -196,34 +193,31 @@ static void CopyObjectToObjectElements(FixedArrayBase* from_base, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void CopyDictionaryToObjectElements(FixedArrayBase* from_base, |
|
|
static void CopyDictionaryToObjectElements(SeededNumberDictionary* from, |
|
|
uint32_t from_start, |
|
|
uint32_t from_start, |
|
|
FixedArrayBase* to_base, |
|
|
FixedArray* to, |
|
|
ElementsKind to_kind, |
|
|
ElementsKind to_kind, |
|
|
uint32_t to_start, |
|
|
uint32_t to_start, |
|
|
int raw_copy_size) { |
|
|
int raw_copy_size) { |
|
|
SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); |
|
|
|
|
|
AssertNoAllocation no_allocation; |
|
|
|
|
|
int copy_size = raw_copy_size; |
|
|
int copy_size = raw_copy_size; |
|
|
Heap* heap = from->GetHeap(); |
|
|
Heap* heap = from->GetHeap(); |
|
|
if (raw_copy_size < 0) { |
|
|
if (raw_copy_size < 0) { |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
copy_size = from->max_number_key() + 1 - from_start; |
|
|
copy_size = from->max_number_key() + 1 - from_start; |
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
// Fast object arrays cannot be uninitialized. Ensure they are already
|
|
|
|
|
|
// marked with the hole.
|
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
int start = to_start + copy_size; |
|
|
for (int i = to_start + copy_size; i < to->length(); ++i) { |
|
|
int length = to_base->length() - start; |
|
|
ASSERT(to->get(i)->IsTheHole()); |
|
|
if (length > 0) { |
|
|
|
|
|
Heap* heap = from->GetHeap(); |
|
|
|
|
|
MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
|
|
|
|
|
heap->the_hole_value(), length); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
#endif |
|
|
} |
|
|
} |
|
|
ASSERT(to_base != from_base); |
|
|
ASSERT(to != from); |
|
|
ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
|
|
ASSERT(IsFastSmiOrObjectElementsKind(to_kind)); |
|
|
if (copy_size == 0) return; |
|
|
if (copy_size == 0) return; |
|
|
FixedArray* to = FixedArray::cast(to_base); |
|
|
|
|
|
uint32_t to_length = to->length(); |
|
|
uint32_t to_length = to->length(); |
|
|
if (to_start + copy_size > to_length) { |
|
|
if (to_start + copy_size > to_length) { |
|
|
copy_size = to_length - to_start; |
|
|
copy_size = to_length - to_start; |
|
@ -250,9 +244,9 @@ static void CopyDictionaryToObjectElements(FixedArrayBase* from_base, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( |
|
|
MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( |
|
|
FixedArrayBase* from_base, |
|
|
FixedDoubleArray* from, |
|
|
uint32_t from_start, |
|
|
uint32_t from_start, |
|
|
FixedArrayBase* to_base, |
|
|
FixedArray* to, |
|
|
ElementsKind to_kind, |
|
|
ElementsKind to_kind, |
|
|
uint32_t to_start, |
|
|
uint32_t to_start, |
|
|
int raw_copy_size) { |
|
|
int raw_copy_size) { |
|
@ -261,26 +255,21 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( |
|
|
if (raw_copy_size < 0) { |
|
|
if (raw_copy_size < 0) { |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
copy_size = Min(from_base->length() - from_start, |
|
|
copy_size = Min(from->length() - from_start, |
|
|
to_base->length() - to_start); |
|
|
to->length() - to_start); |
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
// FAST_*_ELEMENTS arrays cannot be uninitialized. Ensure they are already
|
|
|
|
|
|
// marked with the hole.
|
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
// Also initialize the area that will be copied over since HeapNumber
|
|
|
for (int i = to_start + copy_size; i < to->length(); ++i) { |
|
|
// allocation below can cause an incremental marking step, requiring all
|
|
|
ASSERT(to->get(i)->IsTheHole()); |
|
|
// existing heap objects to be propertly initialized.
|
|
|
|
|
|
int start = to_start; |
|
|
|
|
|
int length = to_base->length() - start; |
|
|
|
|
|
if (length > 0) { |
|
|
|
|
|
Heap* heap = from_base->GetHeap(); |
|
|
|
|
|
MemsetPointer(FixedArray::cast(to_base)->data_start() + start, |
|
|
|
|
|
heap->the_hole_value(), length); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
#endif |
|
|
} |
|
|
} |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
|
|
(copy_size + static_cast<int>(from_start)) <= from_base->length()); |
|
|
(copy_size + static_cast<int>(from_start)) <= from->length()); |
|
|
if (copy_size == 0) return from_base; |
|
|
if (copy_size == 0) return from; |
|
|
FixedDoubleArray* from = FixedDoubleArray::cast(from_base); |
|
|
|
|
|
FixedArray* to = FixedArray::cast(to_base); |
|
|
|
|
|
for (int i = 0; i < copy_size; ++i) { |
|
|
for (int i = 0; i < copy_size; ++i) { |
|
|
if (IsFastSmiElementsKind(to_kind)) { |
|
|
if (IsFastSmiElementsKind(to_kind)) { |
|
|
UNIMPLEMENTED(); |
|
|
UNIMPLEMENTED(); |
|
@ -309,28 +298,26 @@ MUST_USE_RESULT static MaybeObject* CopyDoubleToObjectElements( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void CopyDoubleToDoubleElements(FixedArrayBase* from_base, |
|
|
static void CopyDoubleToDoubleElements(FixedDoubleArray* from, |
|
|
uint32_t from_start, |
|
|
uint32_t from_start, |
|
|
FixedArrayBase* to_base, |
|
|
FixedDoubleArray* to, |
|
|
uint32_t to_start, |
|
|
uint32_t to_start, |
|
|
int raw_copy_size) { |
|
|
int raw_copy_size) { |
|
|
int copy_size = raw_copy_size; |
|
|
int copy_size = raw_copy_size; |
|
|
if (raw_copy_size < 0) { |
|
|
if (raw_copy_size < 0) { |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
copy_size = Min(from_base->length() - from_start, |
|
|
copy_size = Min(from->length() - from_start, |
|
|
to_base->length() - to_start); |
|
|
to->length() - to_start); |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
|
|
for (int i = to_start + copy_size; i < to->length(); ++i) { |
|
|
FixedDoubleArray::cast(to_base)->set_the_hole(i); |
|
|
to->set_the_hole(i); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
|
|
(copy_size + static_cast<int>(from_start)) <= from_base->length()); |
|
|
(copy_size + static_cast<int>(from_start)) <= from->length()); |
|
|
if (copy_size == 0) return; |
|
|
if (copy_size == 0) return; |
|
|
FixedDoubleArray* from = FixedDoubleArray::cast(from_base); |
|
|
|
|
|
FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
|
|
|
|
|
Address to_address = to->address() + FixedDoubleArray::kHeaderSize; |
|
|
Address to_address = to->address() + FixedDoubleArray::kHeaderSize; |
|
|
Address from_address = from->address() + FixedDoubleArray::kHeaderSize; |
|
|
Address from_address = from->address() + FixedDoubleArray::kHeaderSize; |
|
|
to_address += kDoubleSize * to_start; |
|
|
to_address += kDoubleSize * to_start; |
|
@ -342,27 +329,25 @@ static void CopyDoubleToDoubleElements(FixedArrayBase* from_base, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void CopySmiToDoubleElements(FixedArrayBase* from_base, |
|
|
static void CopySmiToDoubleElements(FixedArray* from, |
|
|
uint32_t from_start, |
|
|
uint32_t from_start, |
|
|
FixedArrayBase* to_base, |
|
|
FixedDoubleArray* to, |
|
|
uint32_t to_start, |
|
|
uint32_t to_start, |
|
|
int raw_copy_size) { |
|
|
int raw_copy_size) { |
|
|
int copy_size = raw_copy_size; |
|
|
int copy_size = raw_copy_size; |
|
|
if (raw_copy_size < 0) { |
|
|
if (raw_copy_size < 0) { |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
copy_size = from_base->length() - from_start; |
|
|
copy_size = from->length() - from_start; |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
|
|
for (int i = to_start + copy_size; i < to->length(); ++i) { |
|
|
FixedDoubleArray::cast(to_base)->set_the_hole(i); |
|
|
to->set_the_hole(i); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
|
|
(copy_size + static_cast<int>(from_start)) <= from_base->length()); |
|
|
(copy_size + static_cast<int>(from_start)) <= from->length()); |
|
|
if (copy_size == 0) return; |
|
|
if (copy_size == 0) return; |
|
|
FixedArray* from = FixedArray::cast(from_base); |
|
|
|
|
|
FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
|
|
|
|
|
Object* the_hole = from->GetHeap()->the_hole_value(); |
|
|
Object* the_hole = from->GetHeap()->the_hole_value(); |
|
|
for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); |
|
|
for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size); |
|
|
from_start < from_end; from_start++, to_start++) { |
|
|
from_start < from_end; from_start++, to_start++) { |
|
@ -376,9 +361,9 @@ static void CopySmiToDoubleElements(FixedArrayBase* from_base, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void CopyPackedSmiToDoubleElements(FixedArrayBase* from_base, |
|
|
static void CopyPackedSmiToDoubleElements(FixedArray* from, |
|
|
uint32_t from_start, |
|
|
uint32_t from_start, |
|
|
FixedArrayBase* to_base, |
|
|
FixedDoubleArray* to, |
|
|
uint32_t to_start, |
|
|
uint32_t to_start, |
|
|
int packed_size, |
|
|
int packed_size, |
|
|
int raw_copy_size) { |
|
|
int raw_copy_size) { |
|
@ -387,55 +372,52 @@ static void CopyPackedSmiToDoubleElements(FixedArrayBase* from_base, |
|
|
if (raw_copy_size < 0) { |
|
|
if (raw_copy_size < 0) { |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
copy_size = packed_size - from_start; |
|
|
copy_size = from->length() - from_start; |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
to_end = to_base->length(); |
|
|
to_end = to->length(); |
|
|
for (uint32_t i = to_start + copy_size; i < to_end; ++i) { |
|
|
|
|
|
FixedDoubleArray::cast(to_base)->set_the_hole(i); |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
} else { |
|
|
to_end = to_start + static_cast<uint32_t>(copy_size); |
|
|
to_end = to_start + static_cast<uint32_t>(copy_size); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
to_end = to_start + static_cast<uint32_t>(copy_size); |
|
|
to_end = to_start + static_cast<uint32_t>(copy_size); |
|
|
} |
|
|
} |
|
|
ASSERT(static_cast<int>(to_end) <= to_base->length()); |
|
|
ASSERT(static_cast<int>(to_end) <= to->length()); |
|
|
ASSERT(packed_size >= 0 && packed_size <= copy_size); |
|
|
ASSERT(packed_size >= 0 && packed_size <= copy_size); |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
|
|
(copy_size + static_cast<int>(from_start)) <= from_base->length()); |
|
|
(copy_size + static_cast<int>(from_start)) <= from->length()); |
|
|
if (copy_size == 0) return; |
|
|
if (copy_size == 0) return; |
|
|
FixedArray* from = FixedArray::cast(from_base); |
|
|
|
|
|
FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
|
|
|
|
|
for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); |
|
|
for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); |
|
|
from_start < from_end; from_start++, to_start++) { |
|
|
from_start < from_end; from_start++, to_start++) { |
|
|
Object* smi = from->get(from_start); |
|
|
Object* smi = from->get(from_start); |
|
|
ASSERT(!smi->IsTheHole()); |
|
|
ASSERT(!smi->IsTheHole()); |
|
|
to->set(to_start, Smi::cast(smi)->value()); |
|
|
to->set(to_start, Smi::cast(smi)->value()); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
while (to_start < to_end) { |
|
|
|
|
|
to->set_the_hole(to_start++); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void CopyObjectToDoubleElements(FixedArrayBase* from_base, |
|
|
static void CopyObjectToDoubleElements(FixedArray* from, |
|
|
uint32_t from_start, |
|
|
uint32_t from_start, |
|
|
FixedArrayBase* to_base, |
|
|
FixedDoubleArray* to, |
|
|
uint32_t to_start, |
|
|
uint32_t to_start, |
|
|
int raw_copy_size) { |
|
|
int raw_copy_size) { |
|
|
int copy_size = raw_copy_size; |
|
|
int copy_size = raw_copy_size; |
|
|
if (raw_copy_size < 0) { |
|
|
if (raw_copy_size < 0) { |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd || |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
copy_size = from_base->length() - from_start; |
|
|
copy_size = from->length() - from_start; |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
|
|
for (int i = to_start + copy_size; i < to->length(); ++i) { |
|
|
FixedDoubleArray::cast(to_base)->set_the_hole(i); |
|
|
to->set_the_hole(i); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
|
|
ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && |
|
|
(copy_size + static_cast<int>(from_start)) <= from_base->length()); |
|
|
(copy_size + static_cast<int>(from_start)) <= from->length()); |
|
|
if (copy_size == 0) return; |
|
|
if (copy_size == 0) return; |
|
|
FixedArray* from = FixedArray::cast(from_base); |
|
|
|
|
|
FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
|
|
|
|
|
Object* the_hole = from->GetHeap()->the_hole_value(); |
|
|
Object* the_hole = from->GetHeap()->the_hole_value(); |
|
|
for (uint32_t from_end = from_start + copy_size; |
|
|
for (uint32_t from_end = from_start + copy_size; |
|
|
from_start < from_end; from_start++, to_start++) { |
|
|
from_start < from_end; from_start++, to_start++) { |
|
@ -449,25 +431,23 @@ static void CopyObjectToDoubleElements(FixedArrayBase* from_base, |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void CopyDictionaryToDoubleElements(FixedArrayBase* from_base, |
|
|
static void CopyDictionaryToDoubleElements(SeededNumberDictionary* from, |
|
|
uint32_t from_start, |
|
|
uint32_t from_start, |
|
|
FixedArrayBase* to_base, |
|
|
FixedDoubleArray* to, |
|
|
uint32_t to_start, |
|
|
uint32_t to_start, |
|
|
int raw_copy_size) { |
|
|
int raw_copy_size) { |
|
|
SeededNumberDictionary* from = SeededNumberDictionary::cast(from_base); |
|
|
|
|
|
int copy_size = raw_copy_size; |
|
|
int copy_size = raw_copy_size; |
|
|
if (copy_size < 0) { |
|
|
if (copy_size < 0) { |
|
|
ASSERT(copy_size == ElementsAccessor::kCopyToEnd || |
|
|
ASSERT(copy_size == ElementsAccessor::kCopyToEnd || |
|
|
copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole); |
|
|
copy_size = from->max_number_key() + 1 - from_start; |
|
|
copy_size = from->max_number_key() + 1 - from_start; |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) { |
|
|
for (int i = to_start + copy_size; i < to_base->length(); ++i) { |
|
|
for (int i = to_start + copy_size; i < to->length(); ++i) { |
|
|
FixedDoubleArray::cast(to_base)->set_the_hole(i); |
|
|
to->set_the_hole(i); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
if (copy_size == 0) return; |
|
|
if (copy_size == 0) return; |
|
|
FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
|
|
|
|
|
uint32_t to_length = to->length(); |
|
|
uint32_t to_length = to->length(); |
|
|
if (to_start + copy_size > to_length) { |
|
|
if (to_start + copy_size > to_length) { |
|
|
copy_size = to_length - to_start; |
|
|
copy_size = to_length - to_start; |
|
@ -523,8 +503,8 @@ class ElementsAccessorBase : public ElementsAccessor { |
|
|
Map* map = fixed_array_base->map(); |
|
|
Map* map = fixed_array_base->map(); |
|
|
// Arrays that have been shifted in place can't be verified.
|
|
|
// Arrays that have been shifted in place can't be verified.
|
|
|
Heap* heap = holder->GetHeap(); |
|
|
Heap* heap = holder->GetHeap(); |
|
|
if (map == heap->one_pointer_filler_map() || |
|
|
if (map == heap->raw_unchecked_one_pointer_filler_map() || |
|
|
map == heap->two_pointer_filler_map() || |
|
|
map == heap->raw_unchecked_two_pointer_filler_map() || |
|
|
map == heap->free_space_map()) { |
|
|
map == heap->free_space_map()) { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
@ -547,9 +527,10 @@ class ElementsAccessorBase : public ElementsAccessor { |
|
|
static bool HasElementImpl(Object* receiver, |
|
|
static bool HasElementImpl(Object* receiver, |
|
|
JSObject* holder, |
|
|
JSObject* holder, |
|
|
uint32_t key, |
|
|
uint32_t key, |
|
|
FixedArrayBase* backing_store) { |
|
|
BackingStore* backing_store) { |
|
|
return ElementsAccessorSubclass::GetAttributesImpl( |
|
|
MaybeObject* element = |
|
|
receiver, holder, key, backing_store) != ABSENT; |
|
|
ElementsAccessorSubclass::GetImpl(receiver, holder, key, backing_store); |
|
|
|
|
|
return !element->IsTheHole(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
virtual bool HasElement(Object* receiver, |
|
|
virtual bool HasElement(Object* receiver, |
|
@ -560,7 +541,7 @@ class ElementsAccessorBase : public ElementsAccessor { |
|
|
backing_store = holder->elements(); |
|
|
backing_store = holder->elements(); |
|
|
} |
|
|
} |
|
|
return ElementsAccessorSubclass::HasElementImpl( |
|
|
return ElementsAccessorSubclass::HasElementImpl( |
|
|
receiver, holder, key, backing_store); |
|
|
receiver, holder, key, BackingStore::cast(backing_store)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver, |
|
|
MUST_USE_RESULT virtual MaybeObject* Get(Object* receiver, |
|
@ -571,95 +552,28 @@ class ElementsAccessorBase : public ElementsAccessor { |
|
|
backing_store = holder->elements(); |
|
|
backing_store = holder->elements(); |
|
|
} |
|
|
} |
|
|
return ElementsAccessorSubclass::GetImpl( |
|
|
return ElementsAccessorSubclass::GetImpl( |
|
|
receiver, holder, key, backing_store); |
|
|
receiver, holder, key, BackingStore::cast(backing_store)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
|
|
MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
|
|
JSObject* obj, |
|
|
JSObject* obj, |
|
|
uint32_t key, |
|
|
uint32_t key, |
|
|
FixedArrayBase* backing_store) { |
|
|
BackingStore* backing_store) { |
|
|
return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) |
|
|
return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) |
|
|
? BackingStore::cast(backing_store)->get(key) |
|
|
? backing_store->get(key) |
|
|
: backing_store->GetHeap()->the_hole_value(); |
|
|
: backing_store->GetHeap()->the_hole_value(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
MUST_USE_RESULT virtual PropertyAttributes GetAttributes( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* holder, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
if (backing_store == NULL) { |
|
|
|
|
|
backing_store = holder->elements(); |
|
|
|
|
|
} |
|
|
|
|
|
return ElementsAccessorSubclass::GetAttributesImpl( |
|
|
|
|
|
receiver, holder, key, backing_store); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
|
|
|
|
|
return ABSENT; |
|
|
|
|
|
} |
|
|
|
|
|
return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT virtual PropertyType GetType( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* holder, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
if (backing_store == NULL) { |
|
|
|
|
|
backing_store = holder->elements(); |
|
|
|
|
|
} |
|
|
|
|
|
return ElementsAccessorSubclass::GetTypeImpl( |
|
|
|
|
|
receiver, holder, key, backing_store); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static PropertyType GetTypeImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
|
|
|
|
|
return NONEXISTENT; |
|
|
|
|
|
} |
|
|
|
|
|
return BackingStore::cast(backing_store)->is_the_hole(key) |
|
|
|
|
|
? NONEXISTENT : FIELD; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT virtual AccessorPair* GetAccessorPair( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* holder, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
if (backing_store == NULL) { |
|
|
|
|
|
backing_store = holder->elements(); |
|
|
|
|
|
} |
|
|
|
|
|
return ElementsAccessorSubclass::GetAccessorPairImpl( |
|
|
|
|
|
receiver, holder, key, backing_store); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* array, |
|
|
MUST_USE_RESULT virtual MaybeObject* SetLength(JSArray* array, |
|
|
Object* length) { |
|
|
Object* length) { |
|
|
return ElementsAccessorSubclass::SetLengthImpl( |
|
|
return ElementsAccessorSubclass::SetLengthImpl( |
|
|
array, length, array->elements()); |
|
|
array, length, BackingStore::cast(array->elements())); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
MUST_USE_RESULT static MaybeObject* SetLengthImpl( |
|
|
MUST_USE_RESULT static MaybeObject* SetLengthImpl( |
|
|
JSObject* obj, |
|
|
JSObject* obj, |
|
|
Object* length, |
|
|
Object* length, |
|
|
FixedArrayBase* backing_store); |
|
|
BackingStore* backing_store); |
|
|
|
|
|
|
|
|
MUST_USE_RESULT virtual MaybeObject* SetCapacityAndLength( |
|
|
MUST_USE_RESULT virtual MaybeObject* SetCapacityAndLength( |
|
|
JSArray* array, |
|
|
JSArray* array, |
|
@ -717,6 +631,9 @@ class ElementsAccessorBase : public ElementsAccessor { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
if (from->length() == 0) { |
|
|
|
|
|
return from; |
|
|
|
|
|
} |
|
|
return ElementsAccessorSubclass::CopyElementsImpl( |
|
|
return ElementsAccessorSubclass::CopyElementsImpl( |
|
|
from, from_start, to, to_kind, to_start, packed_size, copy_size); |
|
|
from, from_start, to, to_kind, to_start, packed_size, copy_size); |
|
|
} |
|
|
} |
|
@ -737,22 +654,25 @@ class ElementsAccessorBase : public ElementsAccessor { |
|
|
if (from == NULL) { |
|
|
if (from == NULL) { |
|
|
from = holder->elements(); |
|
|
from = holder->elements(); |
|
|
} |
|
|
} |
|
|
|
|
|
BackingStore* backing_store = BackingStore::cast(from); |
|
|
|
|
|
uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
|
|
|
|
|
|
|
|
// Optimize if 'other' is empty.
|
|
|
// Optimize if 'other' is empty.
|
|
|
// We cannot optimize if 'this' is empty, as other may have holes.
|
|
|
// We cannot optimize if 'this' is empty, as other may have holes.
|
|
|
uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from); |
|
|
|
|
|
if (len1 == 0) return to; |
|
|
if (len1 == 0) return to; |
|
|
|
|
|
|
|
|
// Compute how many elements are not in other.
|
|
|
// Compute how many elements are not in other.
|
|
|
uint32_t extra = 0; |
|
|
uint32_t extra = 0; |
|
|
for (uint32_t y = 0; y < len1; y++) { |
|
|
for (uint32_t y = 0; y < len1; y++) { |
|
|
uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
|
|
uint32_t key = |
|
|
|
|
|
ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); |
|
|
if (ElementsAccessorSubclass::HasElementImpl( |
|
|
if (ElementsAccessorSubclass::HasElementImpl( |
|
|
receiver, holder, key, from)) { |
|
|
receiver, holder, key, backing_store)) { |
|
|
MaybeObject* maybe_value = |
|
|
MaybeObject* maybe_value = |
|
|
ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
|
|
ElementsAccessorSubclass::GetImpl(receiver, holder, |
|
|
|
|
|
key, backing_store); |
|
|
Object* value; |
|
|
Object* value; |
|
|
if (!maybe_value->To(&value)) return maybe_value; |
|
|
if (!maybe_value->ToObject(&value)) return maybe_value; |
|
|
ASSERT(!value->IsTheHole()); |
|
|
ASSERT(!value->IsTheHole()); |
|
|
if (!HasKey(to, value)) { |
|
|
if (!HasKey(to, value)) { |
|
|
extra++; |
|
|
extra++; |
|
@ -764,8 +684,9 @@ class ElementsAccessorBase : public ElementsAccessor { |
|
|
|
|
|
|
|
|
// Allocate the result
|
|
|
// Allocate the result
|
|
|
FixedArray* result; |
|
|
FixedArray* result; |
|
|
MaybeObject* maybe_obj = from->GetHeap()->AllocateFixedArray(len0 + extra); |
|
|
MaybeObject* maybe_obj = |
|
|
if (!maybe_obj->To(&result)) return maybe_obj; |
|
|
backing_store->GetHeap()->AllocateFixedArray(len0 + extra); |
|
|
|
|
|
if (!maybe_obj->To<FixedArray>(&result)) return maybe_obj; |
|
|
|
|
|
|
|
|
// Fill in the content
|
|
|
// Fill in the content
|
|
|
{ |
|
|
{ |
|
@ -781,13 +702,14 @@ class ElementsAccessorBase : public ElementsAccessor { |
|
|
uint32_t index = 0; |
|
|
uint32_t index = 0; |
|
|
for (uint32_t y = 0; y < len1; y++) { |
|
|
for (uint32_t y = 0; y < len1; y++) { |
|
|
uint32_t key = |
|
|
uint32_t key = |
|
|
ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); |
|
|
ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); |
|
|
if (ElementsAccessorSubclass::HasElementImpl( |
|
|
if (ElementsAccessorSubclass::HasElementImpl( |
|
|
receiver, holder, key, from)) { |
|
|
receiver, holder, key, backing_store)) { |
|
|
MaybeObject* maybe_value = |
|
|
MaybeObject* maybe_value = |
|
|
ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
|
|
ElementsAccessorSubclass::GetImpl(receiver, holder, |
|
|
|
|
|
key, backing_store); |
|
|
Object* value; |
|
|
Object* value; |
|
|
if (!maybe_value->To(&value)) return maybe_value; |
|
|
if (!maybe_value->ToObject(&value)) return maybe_value; |
|
|
if (!value->IsTheHole() && !HasKey(to, value)) { |
|
|
if (!value->IsTheHole() && !HasKey(to, value)) { |
|
|
result->set(len0 + index, value); |
|
|
result->set(len0 + index, value); |
|
|
index++; |
|
|
index++; |
|
@ -799,22 +721,24 @@ class ElementsAccessorBase : public ElementsAccessor { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
protected: |
|
|
protected: |
|
|
static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
|
|
static uint32_t GetCapacityImpl(BackingStore* backing_store) { |
|
|
return backing_store->length(); |
|
|
return backing_store->length(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { |
|
|
virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { |
|
|
return ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
|
|
return ElementsAccessorSubclass::GetCapacityImpl( |
|
|
|
|
|
BackingStore::cast(backing_store)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store, |
|
|
static uint32_t GetKeyForIndexImpl(BackingStore* backing_store, |
|
|
uint32_t index) { |
|
|
uint32_t index) { |
|
|
return index; |
|
|
return index; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, |
|
|
virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, |
|
|
uint32_t index) { |
|
|
uint32_t index) { |
|
|
return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); |
|
|
return ElementsAccessorSubclass::GetKeyForIndexImpl( |
|
|
|
|
|
BackingStore::cast(backing_store), index); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private: |
|
|
private: |
|
@ -840,17 +764,17 @@ class FastElementsAccessor |
|
|
|
|
|
|
|
|
// Adjusts the length of the fast backing store or returns the new length or
|
|
|
// Adjusts the length of the fast backing store or returns the new length or
|
|
|
// undefined in case conversion to a slow backing store should be performed.
|
|
|
// undefined in case conversion to a slow backing store should be performed.
|
|
|
static MaybeObject* SetLengthWithoutNormalize(FixedArrayBase* backing_store, |
|
|
static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store, |
|
|
JSArray* array, |
|
|
JSArray* array, |
|
|
Object* length_object, |
|
|
Object* length_object, |
|
|
uint32_t length) { |
|
|
uint32_t length) { |
|
|
uint32_t old_capacity = backing_store->length(); |
|
|
uint32_t old_capacity = backing_store->length(); |
|
|
Object* old_length = array->length(); |
|
|
Object* old_length = array->length(); |
|
|
bool same_or_smaller_size = old_length->IsSmi() && |
|
|
bool same_size = old_length->IsSmi() && |
|
|
static_cast<uint32_t>(Smi::cast(old_length)->value()) >= length; |
|
|
static_cast<uint32_t>(Smi::cast(old_length)->value()) == length; |
|
|
ElementsKind kind = array->GetElementsKind(); |
|
|
ElementsKind kind = array->GetElementsKind(); |
|
|
|
|
|
|
|
|
if (!same_or_smaller_size && IsFastElementsKind(kind) && |
|
|
if (!same_size && IsFastElementsKind(kind) && |
|
|
!IsFastHoleyElementsKind(kind)) { |
|
|
!IsFastHoleyElementsKind(kind)) { |
|
|
kind = GetHoleyElementsKind(kind); |
|
|
kind = GetHoleyElementsKind(kind); |
|
|
MaybeObject* maybe_obj = array->TransitionElementsKind(kind); |
|
|
MaybeObject* maybe_obj = array->TransitionElementsKind(kind); |
|
@ -878,7 +802,7 @@ class FastElementsAccessor |
|
|
// Otherwise, fill the unused tail with holes.
|
|
|
// Otherwise, fill the unused tail with holes.
|
|
|
int old_length = FastD2IChecked(array->length()->Number()); |
|
|
int old_length = FastD2IChecked(array->length()->Number()); |
|
|
for (int i = length; i < old_length; i++) { |
|
|
for (int i = length; i < old_length; i++) { |
|
|
BackingStore::cast(backing_store)->set_the_hole(i); |
|
|
backing_store->set_the_hole(i); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return length_object; |
|
|
return length_object; |
|
@ -905,38 +829,32 @@ class FastElementsAccessor |
|
|
ASSERT(obj->HasFastSmiOrObjectElements() || |
|
|
ASSERT(obj->HasFastSmiOrObjectElements() || |
|
|
obj->HasFastDoubleElements() || |
|
|
obj->HasFastDoubleElements() || |
|
|
obj->HasFastArgumentsElements()); |
|
|
obj->HasFastArgumentsElements()); |
|
|
Heap* heap = obj->GetHeap(); |
|
|
|
|
|
Object* elements = obj->elements(); |
|
|
|
|
|
if (elements == heap->empty_fixed_array()) { |
|
|
|
|
|
return heap->true_value(); |
|
|
|
|
|
} |
|
|
|
|
|
typename KindTraits::BackingStore* backing_store = |
|
|
typename KindTraits::BackingStore* backing_store = |
|
|
KindTraits::BackingStore::cast(elements); |
|
|
KindTraits::BackingStore::cast(obj->elements()); |
|
|
bool is_non_strict_arguments_elements_map = |
|
|
Heap* heap = obj->GetHeap(); |
|
|
backing_store->map() == heap->non_strict_arguments_elements_map(); |
|
|
if (backing_store->map() == heap->non_strict_arguments_elements_map()) { |
|
|
if (is_non_strict_arguments_elements_map) { |
|
|
backing_store = |
|
|
backing_store = KindTraits::BackingStore::cast( |
|
|
KindTraits::BackingStore::cast( |
|
|
FixedArray::cast(backing_store)->get(1)); |
|
|
FixedArray::cast(backing_store)->get(1)); |
|
|
|
|
|
} else { |
|
|
|
|
|
ElementsKind kind = KindTraits::Kind; |
|
|
|
|
|
if (IsFastPackedElementsKind(kind)) { |
|
|
|
|
|
MaybeObject* transitioned = |
|
|
|
|
|
obj->TransitionElementsKind(GetHoleyElementsKind(kind)); |
|
|
|
|
|
if (transitioned->IsFailure()) return transitioned; |
|
|
|
|
|
} |
|
|
|
|
|
if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { |
|
|
|
|
|
Object* writable; |
|
|
|
|
|
MaybeObject* maybe = obj->EnsureWritableFastElements(); |
|
|
|
|
|
if (!maybe->ToObject(&writable)) return maybe; |
|
|
|
|
|
backing_store = KindTraits::BackingStore::cast(writable); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
uint32_t length = static_cast<uint32_t>( |
|
|
uint32_t length = static_cast<uint32_t>( |
|
|
obj->IsJSArray() |
|
|
obj->IsJSArray() |
|
|
? Smi::cast(JSArray::cast(obj)->length())->value() |
|
|
? Smi::cast(JSArray::cast(obj)->length())->value() |
|
|
: backing_store->length()); |
|
|
: backing_store->length()); |
|
|
if (key < length) { |
|
|
if (key < length) { |
|
|
if (!is_non_strict_arguments_elements_map) { |
|
|
|
|
|
ElementsKind kind = KindTraits::Kind; |
|
|
|
|
|
if (IsFastPackedElementsKind(kind)) { |
|
|
|
|
|
MaybeObject* transitioned = |
|
|
|
|
|
obj->TransitionElementsKind(GetHoleyElementsKind(kind)); |
|
|
|
|
|
if (transitioned->IsFailure()) return transitioned; |
|
|
|
|
|
} |
|
|
|
|
|
if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { |
|
|
|
|
|
Object* writable; |
|
|
|
|
|
MaybeObject* maybe = obj->EnsureWritableFastElements(); |
|
|
|
|
|
if (!maybe->ToObject(&writable)) return maybe; |
|
|
|
|
|
backing_store = KindTraits::BackingStore::cast(writable); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
backing_store->set_the_hole(key); |
|
|
backing_store->set_the_hole(key); |
|
|
// If an old space backing store is larger than a certain size and
|
|
|
// If an old space backing store is larger than a certain size and
|
|
|
// has too few used values, normalize it.
|
|
|
// has too few used values, normalize it.
|
|
@ -972,11 +890,11 @@ class FastElementsAccessor |
|
|
Object* receiver, |
|
|
Object* receiver, |
|
|
JSObject* holder, |
|
|
JSObject* holder, |
|
|
uint32_t key, |
|
|
uint32_t key, |
|
|
FixedArrayBase* backing_store) { |
|
|
typename KindTraits::BackingStore* backing_store) { |
|
|
if (key >= static_cast<uint32_t>(backing_store->length())) { |
|
|
if (key >= static_cast<uint32_t>(backing_store->length())) { |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
return !BackingStore::cast(backing_store)->is_the_hole(key); |
|
|
return !backing_store->is_the_hole(key); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static void ValidateContents(JSObject* holder, int length) { |
|
|
static void ValidateContents(JSObject* holder, int length) { |
|
@ -1024,18 +942,25 @@ class FastSmiOrObjectElementsAccessor |
|
|
int copy_size) { |
|
|
int copy_size) { |
|
|
if (IsFastSmiOrObjectElementsKind(to_kind)) { |
|
|
if (IsFastSmiOrObjectElementsKind(to_kind)) { |
|
|
CopyObjectToObjectElements( |
|
|
CopyObjectToObjectElements( |
|
|
from, KindTraits::Kind, from_start, to, to_kind, to_start, copy_size); |
|
|
FixedArray::cast(from), KindTraits::Kind, from_start, |
|
|
|
|
|
FixedArray::cast(to), to_kind, to_start, copy_size); |
|
|
} else if (IsFastDoubleElementsKind(to_kind)) { |
|
|
} else if (IsFastDoubleElementsKind(to_kind)) { |
|
|
if (IsFastSmiElementsKind(KindTraits::Kind)) { |
|
|
if (IsFastSmiElementsKind(KindTraits::Kind)) { |
|
|
if (IsFastPackedElementsKind(KindTraits::Kind) && |
|
|
if (IsFastPackedElementsKind(KindTraits::Kind) && |
|
|
packed_size != kPackedSizeNotKnown) { |
|
|
packed_size != kPackedSizeNotKnown) { |
|
|
CopyPackedSmiToDoubleElements( |
|
|
CopyPackedSmiToDoubleElements( |
|
|
from, from_start, to, to_start, packed_size, copy_size); |
|
|
FixedArray::cast(from), from_start, |
|
|
|
|
|
FixedDoubleArray::cast(to), to_start, |
|
|
|
|
|
packed_size, copy_size); |
|
|
} else { |
|
|
} else { |
|
|
CopySmiToDoubleElements(from, from_start, to, to_start, copy_size); |
|
|
CopySmiToDoubleElements( |
|
|
|
|
|
FixedArray::cast(from), from_start, |
|
|
|
|
|
FixedDoubleArray::cast(to), to_start, copy_size); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size); |
|
|
CopyObjectToDoubleElements( |
|
|
|
|
|
FixedArray::cast(from), from_start, |
|
|
|
|
|
FixedDoubleArray::cast(to), to_start, copy_size); |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
UNREACHABLE(); |
|
|
UNREACHABLE(); |
|
@ -1139,10 +1064,13 @@ class FastDoubleElementsAccessor |
|
|
case FAST_HOLEY_SMI_ELEMENTS: |
|
|
case FAST_HOLEY_SMI_ELEMENTS: |
|
|
case FAST_HOLEY_ELEMENTS: |
|
|
case FAST_HOLEY_ELEMENTS: |
|
|
return CopyDoubleToObjectElements( |
|
|
return CopyDoubleToObjectElements( |
|
|
from, from_start, to, to_kind, to_start, copy_size); |
|
|
FixedDoubleArray::cast(from), from_start, FixedArray::cast(to), |
|
|
|
|
|
to_kind, to_start, copy_size); |
|
|
case FAST_DOUBLE_ELEMENTS: |
|
|
case FAST_DOUBLE_ELEMENTS: |
|
|
case FAST_HOLEY_DOUBLE_ELEMENTS: |
|
|
case FAST_HOLEY_DOUBLE_ELEMENTS: |
|
|
CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size); |
|
|
CopyDoubleToDoubleElements(FixedDoubleArray::cast(from), from_start, |
|
|
|
|
|
FixedDoubleArray::cast(to), |
|
|
|
|
|
to_start, copy_size); |
|
|
return from; |
|
|
return from; |
|
|
default: |
|
|
default: |
|
|
UNREACHABLE(); |
|
|
UNREACHABLE(); |
|
@ -1201,37 +1129,17 @@ class ExternalElementsAccessor |
|
|
MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
|
|
MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
|
|
JSObject* obj, |
|
|
JSObject* obj, |
|
|
uint32_t key, |
|
|
uint32_t key, |
|
|
FixedArrayBase* backing_store) { |
|
|
BackingStore* backing_store) { |
|
|
return |
|
|
return |
|
|
key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) |
|
|
key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) |
|
|
? BackingStore::cast(backing_store)->get(key) |
|
|
? backing_store->get(key) |
|
|
: backing_store->GetHeap()->undefined_value(); |
|
|
: backing_store->GetHeap()->undefined_value(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
return |
|
|
|
|
|
key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) |
|
|
|
|
|
? NONE : ABSENT; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static PropertyType GetTypeImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
return |
|
|
|
|
|
key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) |
|
|
|
|
|
? FIELD : NONEXISTENT; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static MaybeObject* SetLengthImpl( |
|
|
MUST_USE_RESULT static MaybeObject* SetLengthImpl( |
|
|
JSObject* obj, |
|
|
JSObject* obj, |
|
|
Object* length, |
|
|
Object* length, |
|
|
FixedArrayBase* backing_store) { |
|
|
BackingStore* backing_store) { |
|
|
// External arrays do not support changing their length.
|
|
|
// External arrays do not support changing their length.
|
|
|
UNREACHABLE(); |
|
|
UNREACHABLE(); |
|
|
return obj; |
|
|
return obj; |
|
@ -1247,7 +1155,7 @@ class ExternalElementsAccessor |
|
|
static bool HasElementImpl(Object* receiver, |
|
|
static bool HasElementImpl(Object* receiver, |
|
|
JSObject* holder, |
|
|
JSObject* holder, |
|
|
uint32_t key, |
|
|
uint32_t key, |
|
|
FixedArrayBase* backing_store) { |
|
|
BackingStore* backing_store) { |
|
|
uint32_t capacity = |
|
|
uint32_t capacity = |
|
|
ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); |
|
|
ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); |
|
|
return key < capacity; |
|
|
return key < capacity; |
|
@ -1356,11 +1264,10 @@ class DictionaryElementsAccessor |
|
|
// Adjusts the length of the dictionary backing store and returns the new
|
|
|
// Adjusts the length of the dictionary backing store and returns the new
|
|
|
// length according to ES5 section 15.4.5.2 behavior.
|
|
|
// length according to ES5 section 15.4.5.2 behavior.
|
|
|
MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize( |
|
|
MUST_USE_RESULT static MaybeObject* SetLengthWithoutNormalize( |
|
|
FixedArrayBase* store, |
|
|
SeededNumberDictionary* dict, |
|
|
JSArray* array, |
|
|
JSArray* array, |
|
|
Object* length_object, |
|
|
Object* length_object, |
|
|
uint32_t length) { |
|
|
uint32_t length) { |
|
|
SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
|
|
|
|
|
Heap* heap = array->GetHeap(); |
|
|
Heap* heap = array->GetHeap(); |
|
|
int capacity = dict->Capacity(); |
|
|
int capacity = dict->Capacity(); |
|
|
uint32_t new_length = length; |
|
|
uint32_t new_length = length; |
|
@ -1470,12 +1377,14 @@ class DictionaryElementsAccessor |
|
|
case FAST_HOLEY_SMI_ELEMENTS: |
|
|
case FAST_HOLEY_SMI_ELEMENTS: |
|
|
case FAST_HOLEY_ELEMENTS: |
|
|
case FAST_HOLEY_ELEMENTS: |
|
|
CopyDictionaryToObjectElements( |
|
|
CopyDictionaryToObjectElements( |
|
|
from, from_start, to, to_kind, to_start, copy_size); |
|
|
SeededNumberDictionary::cast(from), from_start, |
|
|
|
|
|
FixedArray::cast(to), to_kind, to_start, copy_size); |
|
|
return from; |
|
|
return from; |
|
|
case FAST_DOUBLE_ELEMENTS: |
|
|
case FAST_DOUBLE_ELEMENTS: |
|
|
case FAST_HOLEY_DOUBLE_ELEMENTS: |
|
|
case FAST_HOLEY_DOUBLE_ELEMENTS: |
|
|
CopyDictionaryToDoubleElements( |
|
|
CopyDictionaryToDoubleElements( |
|
|
from, from_start, to, to_start, copy_size); |
|
|
SeededNumberDictionary::cast(from), from_start, |
|
|
|
|
|
FixedDoubleArray::cast(to), to_start, copy_size); |
|
|
return from; |
|
|
return from; |
|
|
default: |
|
|
default: |
|
|
UNREACHABLE(); |
|
|
UNREACHABLE(); |
|
@ -1498,8 +1407,7 @@ class DictionaryElementsAccessor |
|
|
Object* receiver, |
|
|
Object* receiver, |
|
|
JSObject* obj, |
|
|
JSObject* obj, |
|
|
uint32_t key, |
|
|
uint32_t key, |
|
|
FixedArrayBase* store) { |
|
|
SeededNumberDictionary* backing_store) { |
|
|
SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
|
|
|
|
|
int entry = backing_store->FindEntry(key); |
|
|
int entry = backing_store->FindEntry(key); |
|
|
if (entry != SeededNumberDictionary::kNotFound) { |
|
|
if (entry != SeededNumberDictionary::kNotFound) { |
|
|
Object* element = backing_store->ValueAt(entry); |
|
|
Object* element = backing_store->ValueAt(entry); |
|
@ -1516,59 +1424,16 @@ class DictionaryElementsAccessor |
|
|
return obj->GetHeap()->the_hole_value(); |
|
|
return obj->GetHeap()->the_hole_value(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
SeededNumberDictionary* dictionary = |
|
|
|
|
|
SeededNumberDictionary::cast(backing_store); |
|
|
|
|
|
int entry = dictionary->FindEntry(key); |
|
|
|
|
|
if (entry != SeededNumberDictionary::kNotFound) { |
|
|
|
|
|
return dictionary->DetailsAt(entry).attributes(); |
|
|
|
|
|
} |
|
|
|
|
|
return ABSENT; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static PropertyType GetTypeImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* store) { |
|
|
|
|
|
SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
|
|
|
|
|
int entry = backing_store->FindEntry(key); |
|
|
|
|
|
if (entry != SeededNumberDictionary::kNotFound) { |
|
|
|
|
|
return backing_store->DetailsAt(entry).type(); |
|
|
|
|
|
} |
|
|
|
|
|
return NONEXISTENT; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* store) { |
|
|
|
|
|
SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
|
|
|
|
|
int entry = backing_store->FindEntry(key); |
|
|
|
|
|
if (entry != SeededNumberDictionary::kNotFound && |
|
|
|
|
|
backing_store->DetailsAt(entry).type() == CALLBACKS && |
|
|
|
|
|
backing_store->ValueAt(entry)->IsAccessorPair()) { |
|
|
|
|
|
return AccessorPair::cast(backing_store->ValueAt(entry)); |
|
|
|
|
|
} |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static bool HasElementImpl(Object* receiver, |
|
|
static bool HasElementImpl(Object* receiver, |
|
|
JSObject* holder, |
|
|
JSObject* holder, |
|
|
uint32_t key, |
|
|
uint32_t key, |
|
|
FixedArrayBase* backing_store) { |
|
|
SeededNumberDictionary* backing_store) { |
|
|
return SeededNumberDictionary::cast(backing_store)->FindEntry(key) != |
|
|
return backing_store->FindEntry(key) != |
|
|
SeededNumberDictionary::kNotFound; |
|
|
SeededNumberDictionary::kNotFound; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, |
|
|
static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict, |
|
|
uint32_t index) { |
|
|
uint32_t index) { |
|
|
SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
|
|
|
|
|
Object* key = dict->KeyAt(index); |
|
|
Object* key = dict->KeyAt(index); |
|
|
return Smi::cast(key)->value(); |
|
|
return Smi::cast(key)->value(); |
|
|
} |
|
|
} |
|
@ -1591,8 +1456,7 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
|
|
MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
|
|
MUST_USE_RESULT static MaybeObject* GetImpl(Object* receiver, |
|
|
JSObject* obj, |
|
|
JSObject* obj, |
|
|
uint32_t key, |
|
|
uint32_t key, |
|
|
FixedArrayBase* parameters) { |
|
|
FixedArray* parameter_map) { |
|
|
FixedArray* parameter_map = FixedArray::cast(parameters); |
|
|
|
|
|
Object* probe = GetParameterMapArg(obj, parameter_map, key); |
|
|
Object* probe = GetParameterMapArg(obj, parameter_map, key); |
|
|
if (!probe->IsTheHole()) { |
|
|
if (!probe->IsTheHole()) { |
|
|
Context* context = Context::cast(parameter_map->get(0)); |
|
|
Context* context = Context::cast(parameter_map->get(0)); |
|
@ -1619,61 +1483,10 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* backing_store) { |
|
|
|
|
|
FixedArray* parameter_map = FixedArray::cast(backing_store); |
|
|
|
|
|
Object* probe = GetParameterMapArg(obj, parameter_map, key); |
|
|
|
|
|
if (!probe->IsTheHole()) { |
|
|
|
|
|
return NONE; |
|
|
|
|
|
} else { |
|
|
|
|
|
// If not aliased, check the arguments.
|
|
|
|
|
|
FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
|
|
|
|
|
return ElementsAccessor::ForArray(arguments)->GetAttributes( |
|
|
|
|
|
receiver, obj, key, arguments); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static PropertyType GetTypeImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* parameters) { |
|
|
|
|
|
FixedArray* parameter_map = FixedArray::cast(parameters); |
|
|
|
|
|
Object* probe = GetParameterMapArg(obj, parameter_map, key); |
|
|
|
|
|
if (!probe->IsTheHole()) { |
|
|
|
|
|
return FIELD; |
|
|
|
|
|
} else { |
|
|
|
|
|
// If not aliased, check the arguments.
|
|
|
|
|
|
FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
|
|
|
|
|
return ElementsAccessor::ForArray(arguments)->GetType( |
|
|
|
|
|
receiver, obj, key, arguments); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static AccessorPair* GetAccessorPairImpl( |
|
|
|
|
|
Object* receiver, |
|
|
|
|
|
JSObject* obj, |
|
|
|
|
|
uint32_t key, |
|
|
|
|
|
FixedArrayBase* parameters) { |
|
|
|
|
|
FixedArray* parameter_map = FixedArray::cast(parameters); |
|
|
|
|
|
Object* probe = GetParameterMapArg(obj, parameter_map, key); |
|
|
|
|
|
if (!probe->IsTheHole()) { |
|
|
|
|
|
return NULL; |
|
|
|
|
|
} else { |
|
|
|
|
|
// If not aliased, check the arguments.
|
|
|
|
|
|
FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
|
|
|
|
|
return ElementsAccessor::ForArray(arguments)->GetAccessorPair( |
|
|
|
|
|
receiver, obj, key, arguments); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
MUST_USE_RESULT static MaybeObject* SetLengthImpl( |
|
|
MUST_USE_RESULT static MaybeObject* SetLengthImpl( |
|
|
JSObject* obj, |
|
|
JSObject* obj, |
|
|
Object* length, |
|
|
Object* length, |
|
|
FixedArrayBase* parameter_map) { |
|
|
FixedArray* parameter_map) { |
|
|
// TODO(mstarzinger): This was never implemented but will be used once we
|
|
|
// TODO(mstarzinger): This was never implemented but will be used once we
|
|
|
// correctly implement [[DefineOwnProperty]] on arrays.
|
|
|
// correctly implement [[DefineOwnProperty]] on arrays.
|
|
|
UNIMPLEMENTED(); |
|
|
UNIMPLEMENTED(); |
|
@ -1712,20 +1525,19 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
|
|
int packed_size, |
|
|
int packed_size, |
|
|
int copy_size) { |
|
|
int copy_size) { |
|
|
FixedArray* parameter_map = FixedArray::cast(from); |
|
|
FixedArray* parameter_map = FixedArray::cast(from); |
|
|
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
|
|
FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
|
|
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
|
|
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
|
|
return accessor->CopyElements(NULL, from_start, to, to_kind, |
|
|
return accessor->CopyElements(NULL, from_start, to, to_kind, |
|
|
to_start, copy_size, arguments); |
|
|
to_start, copy_size, arguments); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
|
|
static uint32_t GetCapacityImpl(FixedArray* parameter_map) { |
|
|
FixedArray* parameter_map = FixedArray::cast(backing_store); |
|
|
|
|
|
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
|
|
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
|
|
return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
|
|
return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
|
|
ForArray(arguments)->GetCapacity(arguments)); |
|
|
ForArray(arguments)->GetCapacity(arguments)); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, |
|
|
static uint32_t GetKeyForIndexImpl(FixedArray* dict, |
|
|
uint32_t index) { |
|
|
uint32_t index) { |
|
|
return index; |
|
|
return index; |
|
|
} |
|
|
} |
|
@ -1733,14 +1545,12 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
|
|
static bool HasElementImpl(Object* receiver, |
|
|
static bool HasElementImpl(Object* receiver, |
|
|
JSObject* holder, |
|
|
JSObject* holder, |
|
|
uint32_t key, |
|
|
uint32_t key, |
|
|
FixedArrayBase* parameters) { |
|
|
FixedArray* parameter_map) { |
|
|
FixedArray* parameter_map = FixedArray::cast(parameters); |
|
|
|
|
|
Object* probe = GetParameterMapArg(holder, parameter_map, key); |
|
|
Object* probe = GetParameterMapArg(holder, parameter_map, key); |
|
|
if (!probe->IsTheHole()) { |
|
|
if (!probe->IsTheHole()) { |
|
|
return true; |
|
|
return true; |
|
|
} else { |
|
|
} else { |
|
|
FixedArrayBase* arguments = |
|
|
FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
|
|
FixedArrayBase::cast(FixedArray::cast(parameter_map)->get(1)); |
|
|
|
|
|
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
|
|
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
|
|
return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); |
|
|
return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); |
|
|
} |
|
|
} |
|
@ -1753,7 +1563,7 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< |
|
|
uint32_t length = holder->IsJSArray() |
|
|
uint32_t length = holder->IsJSArray() |
|
|
? Smi::cast(JSArray::cast(holder)->length())->value() |
|
|
? Smi::cast(JSArray::cast(holder)->length())->value() |
|
|
: parameter_map->length(); |
|
|
: parameter_map->length(); |
|
|
return key < (length - 2) |
|
|
return key < (length - 2 ) |
|
|
? parameter_map->get(key + 2) |
|
|
? parameter_map->get(key + 2) |
|
|
: parameter_map->GetHeap()->the_hole_value(); |
|
|
: parameter_map->GetHeap()->the_hole_value(); |
|
|
} |
|
|
} |
|
@ -1820,7 +1630,7 @@ MUST_USE_RESULT MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, |
|
|
ElementsKindTraits>:: |
|
|
ElementsKindTraits>:: |
|
|
SetLengthImpl(JSObject* obj, |
|
|
SetLengthImpl(JSObject* obj, |
|
|
Object* length, |
|
|
Object* length, |
|
|
FixedArrayBase* backing_store) { |
|
|
typename ElementsKindTraits::BackingStore* backing_store) { |
|
|
JSArray* array = JSArray::cast(obj); |
|
|
JSArray* array = JSArray::cast(obj); |
|
|
|
|
|
|
|
|
// Fast case: The new length fits into a Smi.
|
|
|
// Fast case: The new length fits into a Smi.
|
|
|