Builtin helper function EnsureJSArrayWithWritableFastElements() handlified.

R=yangguo@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20180 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
ishell@chromium.org 2014-03-24 08:48:36 +00:00
parent 62f65d8697
commit 89732db69e

View File

@ -300,33 +300,35 @@ static bool ArrayPrototypeHasNoElements(Heap* heap,
} }
// Returns empty handle if not applicable.
MUST_USE_RESULT MUST_USE_RESULT
static inline MaybeObject* EnsureJSArrayWithWritableFastElements( static inline Handle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
Heap* heap, Object* receiver, Arguments* args, int first_added_arg) { Isolate* isolate,
if (!receiver->IsJSArray()) return NULL; Handle<Object> receiver,
JSArray* array = JSArray::cast(receiver); Arguments* args,
if (array->map()->is_observed()) return NULL; int first_added_arg) {
if (!array->map()->is_extensible()) return NULL; if (!receiver->IsJSArray()) return Handle<FixedArrayBase>::null();
HeapObject* elms = array->elements(); Handle<JSArray> array = Handle<JSArray>::cast(receiver);
if (array->map()->is_observed()) return Handle<FixedArrayBase>::null();
if (!array->map()->is_extensible()) return Handle<FixedArrayBase>::null();
Handle<FixedArrayBase> elms(array->elements());
Heap* heap = isolate->heap();
Map* map = elms->map(); Map* map = elms->map();
if (map == heap->fixed_array_map()) { if (map == heap->fixed_array_map()) {
if (args == NULL || array->HasFastObjectElements()) return elms; if (args == NULL || array->HasFastObjectElements()) return elms;
} else if (map == heap->fixed_cow_array_map()) { } else if (map == heap->fixed_cow_array_map()) {
MaybeObject* maybe_writable_result = array->EnsureWritableFastElements(); elms = JSObject::EnsureWritableFastElements(array);
if (args == NULL || array->HasFastObjectElements() || if (args == NULL || array->HasFastObjectElements()) return elms;
!maybe_writable_result->To(&elms)) {
return maybe_writable_result;
}
} else if (map == heap->fixed_double_array_map()) { } else if (map == heap->fixed_double_array_map()) {
if (args == NULL) return elms; if (args == NULL) return elms;
} else { } else {
return NULL; return Handle<FixedArrayBase>::null();
} }
// Need to ensure that the arguments passed in args can be contained in // Need to ensure that the arguments passed in args can be contained in
// the array. // the array.
int args_length = args->length(); int args_length = args->length();
if (first_added_arg >= args_length) return array->elements(); if (first_added_arg >= args_length) return handle(array->elements());
ElementsKind origin_kind = array->map()->elements_kind(); ElementsKind origin_kind = array->map()->elements_kind();
ASSERT(!IsFastObjectElementsKind(origin_kind)); ASSERT(!IsFastObjectElementsKind(origin_kind));
@ -345,28 +347,13 @@ static inline MaybeObject* EnsureJSArrayWithWritableFastElements(
} }
} }
if (target_kind != origin_kind) { if (target_kind != origin_kind) {
MaybeObject* maybe_failure = array->TransitionElementsKind(target_kind); JSObject::TransitionElementsKind(array, target_kind);
if (maybe_failure->IsFailure()) return maybe_failure; return handle(array->elements());
return array->elements();
} }
return elms; return elms;
} }
// TODO(ishell): Temporary wrapper until handlified.
MUST_USE_RESULT
static inline Handle<Object> EnsureJSArrayWithWritableFastElementsWrapper(
Isolate* isolate,
Handle<Object> receiver,
Arguments* args,
int first_added_arg) {
CALL_HEAP_FUNCTION(isolate,
EnsureJSArrayWithWritableFastElements(
isolate->heap(), *receiver, args, first_added_arg),
Object);
}
// TODO(ishell): Handlify when all Array* builtins are handlified. // TODO(ishell): Handlify when all Array* builtins are handlified.
static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap, static inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
JSArray* receiver) { JSArray* receiver) {
@ -409,12 +396,10 @@ MUST_USE_RESULT static MaybeObject* CallJsBuiltin(
BUILTIN(ArrayPush) { BUILTIN(ArrayPush) {
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> receiver = args.receiver(); Handle<Object> receiver = args.receiver();
Handle<Object> elms_or_null = Handle<FixedArrayBase> elms_obj =
EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, &args, 1); EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); if (elms_obj.is_null()) return CallJsBuiltin(isolate, "ArrayPush", args);
if (*elms_or_null == NULL) return CallJsBuiltin(isolate, "ArrayPush", args);
Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
Handle<JSArray> array = Handle<JSArray>::cast(receiver); Handle<JSArray> array = Handle<JSArray>::cast(receiver);
ASSERT(!array->map()->is_observed()); ASSERT(!array->map()->is_observed());
@ -544,12 +529,10 @@ static Handle<Object> ElementsAccessorGetWrapper(
BUILTIN(ArrayPop) { BUILTIN(ArrayPop) {
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> receiver = args.receiver(); Handle<Object> receiver = args.receiver();
Handle<Object> elms_or_null = Handle<FixedArrayBase> elms_obj =
EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, NULL, 0); EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); if (elms_obj.is_null()) return CallJsBuiltin(isolate, "ArrayPop", args);
if (*elms_or_null == NULL) return CallJsBuiltin(isolate, "ArrayPop", args);
Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
Handle<JSArray> array = Handle<JSArray>::cast(receiver); Handle<JSArray> array = Handle<JSArray>::cast(receiver);
ASSERT(!array->map()->is_observed()); ASSERT(!array->map()->is_observed());
@ -579,15 +562,13 @@ BUILTIN(ArrayShift) {
HandleScope scope(isolate); HandleScope scope(isolate);
Heap* heap = isolate->heap(); Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver(); Handle<Object> receiver = args.receiver();
Handle<Object> elms_or_null = Handle<FixedArrayBase> elms_obj =
EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, NULL, 0); EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); if (elms_obj.is_null() ||
if ((*elms_or_null == NULL) ||
!IsJSArrayFastElementMovingAllowed(heap, !IsJSArrayFastElementMovingAllowed(heap,
*Handle<JSArray>::cast(receiver))) { *Handle<JSArray>::cast(receiver))) {
return CallJsBuiltin(isolate, "ArrayShift", args); return CallJsBuiltin(isolate, "ArrayShift", args);
} }
Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
Handle<JSArray> array = Handle<JSArray>::cast(receiver); Handle<JSArray> array = Handle<JSArray>::cast(receiver);
ASSERT(!array->map()->is_observed()); ASSERT(!array->map()->is_observed());
@ -628,15 +609,13 @@ BUILTIN(ArrayUnshift) {
HandleScope scope(isolate); HandleScope scope(isolate);
Heap* heap = isolate->heap(); Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver(); Handle<Object> receiver = args.receiver();
Handle<Object> elms_or_null = Handle<FixedArrayBase> elms_obj =
EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, NULL, 0); EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); if (elms_obj.is_null() ||
if ((*elms_or_null == NULL) ||
!IsJSArrayFastElementMovingAllowed(heap, !IsJSArrayFastElementMovingAllowed(heap,
*Handle<JSArray>::cast(receiver))) { *Handle<JSArray>::cast(receiver))) {
return CallJsBuiltin(isolate, "ArrayUnshift", args); return CallJsBuiltin(isolate, "ArrayUnshift", args);
} }
Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
Handle<JSArray> array = Handle<JSArray>::cast(receiver); Handle<JSArray> array = Handle<JSArray>::cast(receiver);
ASSERT(!array->map()->is_observed()); ASSERT(!array->map()->is_observed());
if (!array->HasFastSmiOrObjectElements()) { if (!array->HasFastSmiOrObjectElements()) {
@ -823,16 +802,13 @@ BUILTIN(ArraySplice) {
HandleScope scope(isolate); HandleScope scope(isolate);
Heap* heap = isolate->heap(); Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver(); Handle<Object> receiver = args.receiver();
Handle<Object> elms_or_null = Handle<FixedArrayBase> elms_obj =
EnsureJSArrayWithWritableFastElementsWrapper(isolate, receiver, &args, 3); EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
RETURN_IF_EMPTY_HANDLE(isolate, elms_or_null); if (elms_obj.is_null() ||
if ((*elms_or_null == NULL) ||
!IsJSArrayFastElementMovingAllowed(heap, !IsJSArrayFastElementMovingAllowed(heap,
*Handle<JSArray>::cast(receiver))) { *Handle<JSArray>::cast(receiver))) {
return CallJsBuiltin(isolate, "ArraySplice", args); return CallJsBuiltin(isolate, "ArraySplice", args);
} }
Handle<FixedArrayBase> elms_obj = Handle<FixedArrayBase>::cast(elms_or_null);
Handle<JSArray> array = Handle<JSArray>::cast(receiver); Handle<JSArray> array = Handle<JSArray>::cast(receiver);
ASSERT(!array->map()->is_observed()); ASSERT(!array->map()->is_observed());