Commit 2188bdaf authored by yangguo's avatar yangguo Committed by Commit bot

Install js intrinsic fallbacks for array functions on the native context.

R=cbruni@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#30382}
parent e7cd9d32
......@@ -2,14 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
var $arrayConcat;
var $arrayPush;
var $arrayPop;
var $arrayShift;
var $arraySlice;
var $arraySplice;
var $arrayUnshift;
(function(global, utils) {
"use strict";
......@@ -1695,6 +1687,7 @@ utils.SetUpLockedPrototype(InternalPackedArray, GlobalArray(), [
utils.Export(function(to) {
to.ArrayIndexOf = ArrayIndexOf;
to.ArrayJoin = ArrayJoin;
to.ArrayPush = ArrayPush;
to.ArrayToString = ArrayToString;
to.InnerArrayEvery = InnerArrayEvery;
to.InnerArrayFilter = InnerArrayFilter;
......@@ -1711,12 +1704,14 @@ utils.Export(function(to) {
to.PackedArrayReverse = PackedArrayReverse;
});
$arrayConcat = ArrayConcatJS;
$arrayPush = ArrayPush;
$arrayPop = ArrayPop;
$arrayShift = ArrayShift;
$arraySlice = ArraySlice;
$arraySplice = ArraySplice;
$arrayUnshift = ArrayUnshift;
%InstallToContext([
"array_concat", ArrayConcatJS,
"array_pop", ArrayPop,
"array_push", ArrayPush,
"array_shift", ArrayShift,
"array_splice", ArraySplice,
"array_slice", ArraySlice,
"array_unshift", ArrayUnshift,
]);
});
......@@ -283,17 +283,10 @@ static inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
}
MUST_USE_RESULT static Object* CallJsBuiltin(
Isolate* isolate,
const char* name,
MUST_USE_RESULT static Object* CallJsIntrinsic(
Isolate* isolate, Handle<JSFunction> function,
BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
HandleScope handleScope(isolate);
Handle<Object> js_builtin = Object::GetProperty(
isolate,
handle(isolate->native_context()->builtins(), isolate),
name).ToHandleChecked();
Handle<JSFunction> function = Handle<JSFunction>::cast(js_builtin);
int argc = args.length() - 1;
ScopedVector<Handle<Object> > argv(argc);
for (int i = 0; i < argc; ++i) {
......@@ -318,7 +311,7 @@ BUILTIN(ArrayPush) {
EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj)) {
return CallJsBuiltin(isolate, "$arrayPush", args);
return CallJsIntrinsic(isolate, isolate->array_push(), args);
}
// Fast Elements Path
int push_size = args.length() - 1;
......@@ -329,7 +322,7 @@ BUILTIN(ArrayPush) {
}
if (push_size > 0 &&
JSArray::WouldChangeReadOnlyLength(array, len + push_size)) {
return CallJsBuiltin(isolate, "$arrayPush", args);
return CallJsIntrinsic(isolate, isolate->array_push(), args);
}
DCHECK(!array->map()->is_observed());
ElementsAccessor* accessor = array->GetElementsAccessor();
......@@ -346,7 +339,7 @@ BUILTIN(ArrayPop) {
EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj)) {
return CallJsBuiltin(isolate, "$arrayPop", args);
return CallJsIntrinsic(isolate, isolate->array_pop(), args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
......@@ -356,7 +349,7 @@ BUILTIN(ArrayPop) {
if (len == 0) return isolate->heap()->undefined_value();
if (JSArray::HasReadOnlyLength(array)) {
return CallJsBuiltin(isolate, "$arrayPop", args);
return CallJsIntrinsic(isolate, isolate->array_pop(), args);
}
uint32_t new_length = len - 1;
......@@ -378,7 +371,7 @@ BUILTIN(ArrayShift) {
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj) ||
!IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
return CallJsBuiltin(isolate, "$arrayShift", args);
return CallJsIntrinsic(isolate, isolate->array_shift(), args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
DCHECK(!array->map()->is_observed());
......@@ -387,7 +380,7 @@ BUILTIN(ArrayShift) {
if (len == 0) return heap->undefined_value();
if (JSArray::HasReadOnlyLength(array)) {
return CallJsBuiltin(isolate, "$arrayShift", args);
return CallJsIntrinsic(isolate, isolate->array_shift(), args);
}
// Get first element
......@@ -425,12 +418,12 @@ BUILTIN(ArrayUnshift) {
EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj)) {
return CallJsBuiltin(isolate, "$arrayUnshift", args);
return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
DCHECK(!array->map()->is_observed());
if (!array->HasFastSmiOrObjectElements()) {
return CallJsBuiltin(isolate, "$arrayUnshift", args);
return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
}
int len = Smi::cast(array->length())->value();
int to_add = args.length() - 1;
......@@ -440,7 +433,7 @@ BUILTIN(ArrayUnshift) {
DCHECK(to_add <= (Smi::kMaxValue - len));
if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
return CallJsBuiltin(isolate, "$arrayUnshift", args);
return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
}
Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
......@@ -490,12 +483,12 @@ BUILTIN(ArraySlice) {
JSArray* array = JSArray::cast(*receiver);
if (!IsJSArrayFastElementMovingAllowed(isolate, array)) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
if (!array->HasFastElements()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
len = Smi::cast(array->length())->value();
......@@ -510,24 +503,24 @@ BUILTIN(ArraySlice) {
JSObject::cast(*receiver)->map() == arguments_map;
if (!is_arguments_object_with_fast_elements) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
JSObject* object = JSObject::cast(*receiver);
if (!object->HasFastElements()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
if (!len_obj->IsSmi()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
len = Smi::cast(len_obj)->value();
if (len > object->elements()->length()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
}
......@@ -547,12 +540,12 @@ BUILTIN(ArraySlice) {
double start = HeapNumber::cast(arg1)->value();
if (start < kMinInt || start > kMaxInt) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
} else if (!arg1->IsUndefined()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
if (n_arguments > 1) {
Object* arg2 = args[2];
......@@ -562,12 +555,12 @@ BUILTIN(ArraySlice) {
double end = HeapNumber::cast(arg2)->value();
if (end < kMinInt || end > kMaxInt) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
relative_end = std::isnan(end) ? 0 : static_cast<int>(end);
} else if (!arg2->IsUndefined()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
}
}
......@@ -602,7 +595,7 @@ BUILTIN(ArraySlice) {
kind = GetPackedElementsKind(kind);
} else if (!receiver->IsJSArray()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySlice", args);
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
}
......@@ -627,7 +620,7 @@ BUILTIN(ArraySplice) {
EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
Handle<FixedArrayBase> elms_obj;
if (!maybe_elms_obj.ToHandle(&elms_obj)) {
return CallJsBuiltin(isolate, "$arraySplice", args);
return CallJsIntrinsic(isolate, isolate->array_splice(), args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
DCHECK(!array->map()->is_observed());
......@@ -646,12 +639,12 @@ BUILTIN(ArraySplice) {
double start = HeapNumber::cast(arg1)->value();
if (start < kMinInt || start > kMaxInt) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySplice", args);
return CallJsIntrinsic(isolate, isolate->array_splice(), args);
}
relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
} else if (!arg1->IsUndefined()) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySplice", args);
return CallJsIntrinsic(isolate, isolate->array_splice(), args);
}
}
int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
......@@ -675,7 +668,7 @@ BUILTIN(ArraySplice) {
value = Smi::cast(arg2)->value();
} else {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySplice", args);
return CallJsIntrinsic(isolate, isolate->array_splice(), args);
}
}
actual_delete_count = Min(Max(value, 0), len - actual_start);
......@@ -688,12 +681,12 @@ BUILTIN(ArraySplice) {
// For double mode we do not support changing the length.
if (new_length > len && IsFastDoubleElementsKind(elements_kind)) {
return CallJsBuiltin(isolate, "$arraySplice", args);
return CallJsIntrinsic(isolate, isolate->array_splice(), args);
}
if (new_length != len && JSArray::HasReadOnlyLength(array)) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arraySplice", args);
return CallJsIntrinsic(isolate, isolate->array_splice(), args);
}
if (new_length == 0) {
......@@ -853,7 +846,7 @@ BUILTIN(ArrayConcat) {
PrototypeIterator::START_AT_RECEIVER);
if (!ArrayPrototypeHasNoElements(&iter)) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arrayConcat", args);
return CallJsIntrinsic(isolate, isolate->array_concat(), args);
}
// Iterate through all the arguments performing checks
......@@ -865,7 +858,7 @@ BUILTIN(ArrayConcat) {
if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastElements() ||
iter.GetCurrent() != array_proto) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arrayConcat", args);
return CallJsIntrinsic(isolate, isolate->array_concat(), args);
}
int len = Smi::cast(JSArray::cast(arg)->length())->value();
......@@ -878,7 +871,7 @@ BUILTIN(ArrayConcat) {
if (result_len > FixedDoubleArray::kMaxLength) {
AllowHeapAllocation allow_allocation;
return CallJsBuiltin(isolate, "$arrayConcat", args);
return CallJsIntrinsic(isolate, isolate->array_concat(), args);
}
ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind();
......
......@@ -91,6 +91,13 @@ enum BindingFlags {
V(TO_STRING_FUN_INDEX, JSFunction, to_string_fun)
#define NATIVE_CONTEXT_IMPORTED_FIELDS(V) \
V(ARRAY_CONCAT_INDEX, JSFunction, array_concat) \
V(ARRAY_POP_INDEX, JSFunction, array_pop) \
V(ARRAY_PUSH_INDEX, JSFunction, array_push) \
V(ARRAY_SHIFT_INDEX, JSFunction, array_shift) \
V(ARRAY_SPLICE_INDEX, JSFunction, array_splice) \
V(ARRAY_SLICE_INDEX, JSFunction, array_slice) \
V(ARRAY_UNSHIFT_INDEX, JSFunction, array_unshift) \
V(ARRAY_VALUES_ITERATOR_INDEX, JSFunction, array_values_iterator) \
V(CREATE_DATE_FUN_INDEX, JSFunction, create_date_fun) \
V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \
......
......@@ -19,6 +19,7 @@
var ArrayIndexOf;
var ArrayJoin;
var ArrayPush;
var IsFinite;
var IsNaN;
var GlobalBoolean = global.Boolean;
......@@ -39,6 +40,7 @@ var StringSubstring;
utils.Import(function(from) {
ArrayIndexOf = from.ArrayIndexOf;
ArrayJoin = from.ArrayJoin;
ArrayPush = from.ArrayPush;
IsFinite = from.IsFinite;
IsNaN = from.IsNaN;
MathFloor = from.MathFloor;
......@@ -298,7 +300,7 @@ function lookupSupportedLocalesOf(requestedLocales, availableLocales) {
do {
if (!IS_UNDEFINED(availableLocales[locale])) {
// Push requested locale not the resolved one.
%_CallFunction(matchedLocales, requestedLocales[i], $arrayPush);
%_CallFunction(matchedLocales, requestedLocales[i], ArrayPush);
break;
}
// Truncate locale if possible, if not break.
......@@ -715,7 +717,7 @@ function initializeLocaleList(locales) {
} else {
// We allow single string localeID.
if (typeof locales === 'string') {
%_CallFunction(seen, canonicalizeLanguageTag(locales), $arrayPush);
%_CallFunction(seen, canonicalizeLanguageTag(locales), ArrayPush);
return freezeArray(seen);
}
......@@ -729,7 +731,7 @@ function initializeLocaleList(locales) {
var tag = canonicalizeLanguageTag(value);
if (%_CallFunction(seen, tag, ArrayIndexOf) === -1) {
%_CallFunction(seen, tag, $arrayPush);
%_CallFunction(seen, tag, ArrayPush);
}
}
}
......@@ -775,7 +777,7 @@ function isValidLanguageTag(locale) {
if (%_CallFunction(GetLanguageVariantRE(), value, RegExpTest) &&
extensions.length === 0) {
if (%_CallFunction(variants, value, ArrayIndexOf) === -1) {
%_CallFunction(variants, value, $arrayPush);
%_CallFunction(variants, value, ArrayPush);
} else {
return false;
}
......@@ -783,7 +785,7 @@ function isValidLanguageTag(locale) {
if (%_CallFunction(GetLanguageSingletonRE(), value, RegExpTest)) {
if (%_CallFunction(extensions, value, ArrayIndexOf) === -1) {
%_CallFunction(extensions, value, $arrayPush);
%_CallFunction(extensions, value, ArrayPush);
} else {
return false;
}
......
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