Commit 8e10eea9 authored by ishell@chromium.org's avatar ishell@chromium.org

ArrayPush builtin handlified.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/206183006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20122 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 1088fbd1
......@@ -406,23 +406,21 @@ MUST_USE_RESULT static MaybeObject* CallJsBuiltin(
BUILTIN(ArrayPush) {
Heap* heap = isolate->heap();
Object* receiver = *args.receiver();
FixedArrayBase* elms_obj;
MaybeObject* maybe_elms_obj =
EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 1);
if (maybe_elms_obj == NULL) {
return CallJsBuiltin(isolate, "ArrayPush", args);
}
if (!maybe_elms_obj->To(&elms_obj)) return maybe_elms_obj;
HandleScope scope(isolate);
Handle<Object> receiver = args.receiver();
Handle<Object> elms_or_null =
EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, &args, 1);
RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null);
if (*elms_or_null == NULL) return CallJsBuiltin(isolate, "ArrayPush", args);
JSArray* array = JSArray::cast(receiver);
Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
ASSERT(!array->map()->is_observed());
ElementsKind kind = array->GetElementsKind();
if (IsFastSmiOrObjectElementsKind(kind)) {
FixedArray* elms = FixedArray::cast(elms_obj);
Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
int len = Smi::cast(array->length())->value();
int to_add = args.length() - 1;
......@@ -438,16 +436,13 @@ BUILTIN(ArrayPush) {
if (new_length > elms->length()) {
// New backing storage is needed.
int capacity = new_length + (new_length >> 1) + 16;
FixedArray* new_elms;
MaybeObject* maybe_obj = heap->AllocateUninitializedFixedArray(capacity);
if (!maybe_obj->To(&new_elms)) return maybe_obj;
Handle<FixedArray> new_elms =
isolate->factory()->NewUninitializedFixedArray(capacity);
ElementsAccessor* accessor = array->GetElementsAccessor();
MaybeObject* maybe_failure = accessor->CopyElements(
NULL, 0, kind, new_elms, 0,
ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
ASSERT(!maybe_failure->IsFailure());
USE(maybe_failure);
accessor->CopyElements(
Handle<JSObject>::null(), 0, kind, new_elms, 0,
ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
elms = new_elms;
}
......@@ -459,8 +454,8 @@ BUILTIN(ArrayPush) {
elms->set(index + len, args[index + 1], mode);
}
if (elms != array->elements()) {
array->set_elements(elms);
if (*elms != array->elements()) {
array->set_elements(*elms);
}
// Set the length.
......@@ -480,25 +475,22 @@ BUILTIN(ArrayPush) {
int new_length = len + to_add;
FixedDoubleArray* new_elms;
Handle<FixedDoubleArray> new_elms;
if (new_length > elms_len) {
// New backing storage is needed.
int capacity = new_length + (new_length >> 1) + 16;
MaybeObject* maybe_obj =
heap->AllocateUninitializedFixedDoubleArray(capacity);
if (!maybe_obj->To(&new_elms)) return maybe_obj;
new_elms = isolate->factory()->NewFixedDoubleArray(capacity);
ElementsAccessor* accessor = array->GetElementsAccessor();
MaybeObject* maybe_failure = accessor->CopyElements(
NULL, 0, kind, new_elms, 0,
ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
ASSERT(!maybe_failure->IsFailure());
USE(maybe_failure);
accessor->CopyElements(
Handle<JSObject>::null(), 0, kind, new_elms, 0,
ElementsAccessor::kCopyToEndAndInitializeToHole, elms_obj);
} else {
// to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the
// empty_fixed_array.
new_elms = FixedDoubleArray::cast(elms_obj);
new_elms = Handle<FixedDoubleArray>::cast(elms_obj);
}
// Add the provided values.
......@@ -509,8 +501,8 @@ BUILTIN(ArrayPush) {
new_elms->set(index + len, arg->Number());
}
if (new_elms != array->elements()) {
array->set_elements(new_elms);
if (*new_elms != array->elements()) {
array->set_elements(*new_elms);
}
// Set the length.
......
......@@ -784,6 +784,21 @@ class ElementsAccessorBase : public ElementsAccessor {
return NULL;
}
virtual void CopyElements(
Handle<JSObject> from_holder,
uint32_t from_start,
ElementsKind from_kind,
Handle<FixedArrayBase> to,
uint32_t to_start,
int copy_size,
Handle<FixedArrayBase> from) {
CALL_HEAP_FUNCTION_VOID(from_holder->GetIsolate(),
CopyElements(
from_holder.is_null() ? NULL : *from_holder,
from_start, from_kind, *to, to_start, copy_size,
from.is_null() ? NULL : *from));
}
MUST_USE_RESULT virtual MaybeObject* CopyElements(JSObject* from_holder,
uint32_t from_start,
ElementsKind from_kind,
......
......@@ -142,6 +142,14 @@ class ElementsAccessor {
// the source JSObject or JSArray in source_holder. If the holder's backing
// store is available, it can be passed in source and source_holder is
// ignored.
virtual void CopyElements(
Handle<JSObject> source_holder,
uint32_t source_start,
ElementsKind source_kind,
Handle<FixedArrayBase> destination,
uint32_t destination_start,
int copy_size,
Handle<FixedArrayBase> source = Handle<FixedArrayBase>::null()) = 0;
MUST_USE_RESULT virtual MaybeObject* CopyElements(
JSObject* source_holder,
uint32_t source_start,
......
......@@ -69,6 +69,14 @@ Handle<FixedArray> Factory::NewFixedArrayWithHoles(int size,
}
Handle<FixedArray> Factory::NewUninitializedFixedArray(int size) {
CALL_HEAP_FUNCTION(
isolate(),
isolate()->heap()->AllocateUninitializedFixedArray(size),
FixedArray);
}
Handle<FixedDoubleArray> Factory::NewFixedDoubleArray(int size,
PretenureFlag pretenure) {
ASSERT(0 <= size);
......
......@@ -44,7 +44,7 @@ class Factory {
Handle<Object> value,
PretenureFlag pretenure = NOT_TENURED);
// Allocate a new uninitialized fixed array.
// Allocates a fixed array initialized with undefined values.
Handle<FixedArray> NewFixedArray(
int size,
PretenureFlag pretenure = NOT_TENURED);
......@@ -54,6 +54,9 @@ class Factory {
int size,
PretenureFlag pretenure = NOT_TENURED);
// Allocates an uninitialized fixed array. It must be filled by the caller.
Handle<FixedArray> NewUninitializedFixedArray(int size);
// Allocate a new uninitialized fixed double array.
Handle<FixedDoubleArray> NewFixedDoubleArray(
int size,
......
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