Commit 92716a15 authored by danno@chromium.org's avatar danno@chromium.org

Optimization of some packed array cases.

R=jkummerow@chromium.org
TEST=slight improvement in 3d-morph

Review URL: https://chromiumcodereview.appspot.com/10538104

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11777 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a41d79a1
...@@ -65,6 +65,9 @@ namespace v8 { ...@@ -65,6 +65,9 @@ namespace v8 {
namespace internal { namespace internal {
static const int kPackedSizeNotKnown = -1;
// First argument in list is the accessor class, the second argument is the // First argument in list is the accessor class, the second argument is the
// accessor ElementsKind, and the third is the backing store class. Use the // accessor ElementsKind, and the third is the backing store class. Use the
// fast element handler for smi-only arrays. The implementation is currently // fast element handler for smi-only arrays. The implementation is currently
...@@ -326,6 +329,76 @@ static void CopyDoubleToDoubleElements(FixedDoubleArray* from, ...@@ -326,6 +329,76 @@ static void CopyDoubleToDoubleElements(FixedDoubleArray* from,
} }
static void CopySmiToDoubleElements(FixedArray* from,
uint32_t from_start,
FixedDoubleArray* to,
uint32_t to_start,
int raw_copy_size) {
int copy_size = raw_copy_size;
if (raw_copy_size < 0) {
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
copy_size = from->length() - from_start;
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
for (int i = to_start + copy_size; i < to->length(); ++i) {
to->set_the_hole(i);
}
}
}
ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
(copy_size + static_cast<int>(from_start)) <= from->length());
if (copy_size == 0) return;
Object* the_hole = from->GetHeap()->the_hole_value();
for (uint32_t from_end = from_start + static_cast<uint32_t>(copy_size);
from_start < from_end; from_start++, to_start++) {
Object* hole_or_smi = from->get(from_start);
if (hole_or_smi == the_hole) {
to->set_the_hole(to_start);
} else {
to->set(to_start, Smi::cast(hole_or_smi)->value());
}
}
}
static void CopyPackedSmiToDoubleElements(FixedArray* from,
uint32_t from_start,
FixedDoubleArray* to,
uint32_t to_start,
int packed_size,
int raw_copy_size) {
int copy_size = raw_copy_size;
uint32_t to_end;
if (raw_copy_size < 0) {
ASSERT(raw_copy_size == ElementsAccessor::kCopyToEnd ||
raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole);
copy_size = from->length() - from_start;
if (raw_copy_size == ElementsAccessor::kCopyToEndAndInitializeToHole) {
to_end = to->length();
} else {
to_end = to_start + static_cast<uint32_t>(copy_size);
}
} else {
to_end = to_start + static_cast<uint32_t>(copy_size);
}
ASSERT(static_cast<int>(to_end) <= to->length());
ASSERT(packed_size >= 0 && packed_size <= copy_size);
ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
(copy_size + static_cast<int>(from_start)) <= from->length());
if (copy_size == 0) return;
for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size);
from_start < from_end; from_start++, to_start++) {
Object* smi = from->get(from_start);
ASSERT(!smi->IsTheHole());
to->set(to_start, Smi::cast(smi)->value());
}
while (to_start < to_end) {
to->set_the_hole(to_start++);
}
}
static void CopyObjectToDoubleElements(FixedArray* from, static void CopyObjectToDoubleElements(FixedArray* from,
uint32_t from_start, uint32_t from_start,
FixedDoubleArray* to, FixedDoubleArray* to,
...@@ -345,12 +418,14 @@ static void CopyObjectToDoubleElements(FixedArray* from, ...@@ -345,12 +418,14 @@ static void CopyObjectToDoubleElements(FixedArray* from,
ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() && ASSERT((copy_size + static_cast<int>(to_start)) <= to->length() &&
(copy_size + static_cast<int>(from_start)) <= from->length()); (copy_size + static_cast<int>(from_start)) <= from->length());
if (copy_size == 0) return; if (copy_size == 0) return;
for (int i = 0; i < copy_size; i++) { Object* the_hole = from->GetHeap()->the_hole_value();
Object* hole_or_object = from->get(i + from_start); for (uint32_t from_end = from_start + copy_size;
if (hole_or_object->IsTheHole()) { from_start < from_end; from_start++, to_start++) {
to->set_the_hole(i + to_start); Object* hole_or_object = from->get(from_start);
if (hole_or_object == the_hole) {
to->set_the_hole(to_start);
} else { } else {
to->set(i + to_start, hole_or_object->Number()); to->set(to_start, hole_or_object->Number());
} }
} }
} }
...@@ -527,6 +602,7 @@ class ElementsAccessorBase : public ElementsAccessor { ...@@ -527,6 +602,7 @@ class ElementsAccessorBase : public ElementsAccessor {
FixedArrayBase* to, FixedArrayBase* to,
ElementsKind to_kind, ElementsKind to_kind,
uint32_t to_start, uint32_t to_start,
int packed_size,
int copy_size) { int copy_size) {
UNREACHABLE(); UNREACHABLE();
return NULL; return NULL;
...@@ -539,14 +615,27 @@ class ElementsAccessorBase : public ElementsAccessor { ...@@ -539,14 +615,27 @@ class ElementsAccessorBase : public ElementsAccessor {
uint32_t to_start, uint32_t to_start,
int copy_size, int copy_size,
FixedArrayBase* from) { FixedArrayBase* from) {
int packed_size = kPackedSizeNotKnown;
if (from == NULL) { if (from == NULL) {
from = from_holder->elements(); from = from_holder->elements();
} }
if (from_holder) {
ElementsKind elements_kind = from_holder->GetElementsKind();
bool is_packed = IsFastPackedElementsKind(elements_kind) &&
from_holder->IsJSArray();
if (is_packed) {
packed_size = Smi::cast(JSArray::cast(from_holder)->length())->value();
if (copy_size >= 0 && packed_size > copy_size) {
packed_size = copy_size;
}
}
}
if (from->length() == 0) { if (from->length() == 0) {
return from; return from;
} }
return ElementsAccessorSubclass::CopyElementsImpl( return ElementsAccessorSubclass::CopyElementsImpl(
from, from_start, to, to_kind, to_start, copy_size); from, from_start, to, to_kind, to_start, packed_size, copy_size);
} }
MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray( MUST_USE_RESULT virtual MaybeObject* AddElementsToFixedArray(
...@@ -849,15 +938,30 @@ class FastSmiOrObjectElementsAccessor ...@@ -849,15 +938,30 @@ class FastSmiOrObjectElementsAccessor
FixedArrayBase* to, FixedArrayBase* to,
ElementsKind to_kind, ElementsKind to_kind,
uint32_t to_start, uint32_t to_start,
int packed_size,
int copy_size) { int copy_size) {
if (IsFastSmiOrObjectElementsKind(to_kind)) { if (IsFastSmiOrObjectElementsKind(to_kind)) {
CopyObjectToObjectElements( CopyObjectToObjectElements(
FixedArray::cast(from), KindTraits::Kind, from_start, FixedArray::cast(from), KindTraits::Kind, from_start,
FixedArray::cast(to), to_kind, to_start, copy_size); FixedArray::cast(to), to_kind, to_start, copy_size);
} else if (IsFastDoubleElementsKind(to_kind)) { } else if (IsFastDoubleElementsKind(to_kind)) {
if (IsFastSmiElementsKind(KindTraits::Kind)) {
if (IsFastPackedElementsKind(KindTraits::Kind) &&
packed_size != kPackedSizeNotKnown) {
CopyPackedSmiToDoubleElements(
FixedArray::cast(from), from_start,
FixedDoubleArray::cast(to), to_start,
packed_size, copy_size);
} else {
CopySmiToDoubleElements(
FixedArray::cast(from), from_start,
FixedDoubleArray::cast(to), to_start, copy_size);
}
} else {
CopyObjectToDoubleElements( CopyObjectToDoubleElements(
FixedArray::cast(from), from_start, FixedArray::cast(from), from_start,
FixedDoubleArray::cast(to), to_start, copy_size); FixedDoubleArray::cast(to), to_start, copy_size);
}
} else { } else {
UNREACHABLE(); UNREACHABLE();
} }
...@@ -952,6 +1056,7 @@ class FastDoubleElementsAccessor ...@@ -952,6 +1056,7 @@ class FastDoubleElementsAccessor
FixedArrayBase* to, FixedArrayBase* to,
ElementsKind to_kind, ElementsKind to_kind,
uint32_t to_start, uint32_t to_start,
int packed_size,
int copy_size) { int copy_size) {
switch (to_kind) { switch (to_kind) {
case FAST_SMI_ELEMENTS: case FAST_SMI_ELEMENTS:
...@@ -1265,6 +1370,7 @@ class DictionaryElementsAccessor ...@@ -1265,6 +1370,7 @@ class DictionaryElementsAccessor
FixedArrayBase* to, FixedArrayBase* to,
ElementsKind to_kind, ElementsKind to_kind,
uint32_t to_start, uint32_t to_start,
int packed_size,
int copy_size) { int copy_size) {
switch (to_kind) { switch (to_kind) {
case FAST_SMI_ELEMENTS: case FAST_SMI_ELEMENTS:
...@@ -1417,6 +1523,7 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase< ...@@ -1417,6 +1523,7 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
FixedArrayBase* to, FixedArrayBase* to,
ElementsKind to_kind, ElementsKind to_kind,
uint32_t to_start, uint32_t to_start,
int packed_size,
int copy_size) { int copy_size) {
FixedArray* parameter_map = FixedArray::cast(from); FixedArray* parameter_map = FixedArray::cast(from);
FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
......
...@@ -10023,6 +10023,12 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { ...@@ -10023,6 +10023,12 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
// Fall through. // Fall through.
case FAST_SMI_ELEMENTS: case FAST_SMI_ELEMENTS:
case FAST_ELEMENTS: case FAST_ELEMENTS:
if (IsJSArray()) {
*capacity = backing_store_base->length();
*used = Smi::cast(JSArray::cast(this)->length())->value();
break;
}
// Fall through if packing is not guaranteed.
case FAST_HOLEY_SMI_ELEMENTS: case FAST_HOLEY_SMI_ELEMENTS:
case FAST_HOLEY_ELEMENTS: case FAST_HOLEY_ELEMENTS:
backing_store = FixedArray::cast(backing_store_base); backing_store = FixedArray::cast(backing_store_base);
...@@ -10039,6 +10045,12 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { ...@@ -10039,6 +10045,12 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) {
break; break;
} }
case FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
if (IsJSArray()) {
*capacity = backing_store_base->length();
*used = Smi::cast(JSArray::cast(this)->length())->value();
break;
}
// Fall through if packing is not guaranteed.
case FAST_HOLEY_DOUBLE_ELEMENTS: { case FAST_HOLEY_DOUBLE_ELEMENTS: {
FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); FixedDoubleArray* elms = FixedDoubleArray::cast(elements());
*capacity = elms->length(); *capacity = elms->length();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment