Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Unified Diff: src/builtins.cc

Issue 660298: Always invoke C++ ArrayPush builtin. (Closed)
Patch Set: Next round Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/bootstrapper.cc ('k') | src/contexts.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index d14953028e693c9a22ca4299fc0169ff2d9501bd..70edff136683d6b477bdf0be15d2cafba47fc39c 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -319,6 +319,24 @@ static bool ArrayPrototypeHasNoElements() {
}
+static bool IsJSArrayWithFastElements(Object* receiver,
+ FixedArray** elements) {
+ if (!receiver->IsJSArray()) {
+ return false;
+ }
+
+ JSArray* array = JSArray::cast(receiver);
+
+ HeapObject* elms = HeapObject::cast(array->elements());
+ if (elms->map() != Heap::fixed_array_map()) {
+ return false;
+ }
+
+ *elements = FixedArray::cast(elms);
+ return true;
+}
+
+
static Object* CallJsBuiltin(const char* name,
BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
HandleScope handleScope;
@@ -345,8 +363,12 @@ static Object* CallJsBuiltin(const char* name,
BUILTIN(ArrayPush) {
- JSArray* array = JSArray::cast(*args.receiver());
- ASSERT(array->HasFastElements());
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)) {
+ return CallJsBuiltin("ArrayPush", args);
+ }
+ JSArray* array = JSArray::cast(receiver);
int len = Smi::cast(array->length())->value();
int to_add = args.length() - 1;
@@ -358,7 +380,6 @@ BUILTIN(ArrayPush) {
ASSERT(to_add <= (Smi::kMaxValue - len));
int new_length = len + to_add;
- FixedArray* elms = FixedArray::cast(array->elements());
if (new_length > elms->length()) {
// New backing storage is needed.
@@ -389,14 +410,17 @@ BUILTIN(ArrayPush) {
BUILTIN(ArrayPop) {
- JSArray* array = JSArray::cast(*args.receiver());
- ASSERT(array->HasFastElements());
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)) {
+ return CallJsBuiltin("ArrayPop", args);
+ }
+ JSArray* array = JSArray::cast(receiver);
int len = Smi::cast(array->length())->value();
if (len == 0) return Heap::undefined_value();
// Get top element
- FixedArray* elms = FixedArray::cast(array->elements());
Object* top = elms->get(len - 1);
// Set the length.
@@ -419,18 +443,18 @@ BUILTIN(ArrayPop) {
BUILTIN(ArrayShift) {
- if (!ArrayPrototypeHasNoElements()) {
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)
+ || !ArrayPrototypeHasNoElements()) {
return CallJsBuiltin("ArrayShift", args);
}
-
- JSArray* array = JSArray::cast(*args.receiver());
+ JSArray* array = JSArray::cast(receiver);
ASSERT(array->HasFastElements());
int len = Smi::cast(array->length())->value();
if (len == 0) return Heap::undefined_value();
- FixedArray* elms = FixedArray::cast(array->elements());
-
// Get first element
Object* first = elms->get(0);
if (first->IsTheHole()) {
@@ -450,11 +474,13 @@ BUILTIN(ArrayShift) {
BUILTIN(ArrayUnshift) {
- if (!ArrayPrototypeHasNoElements()) {
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)
+ || !ArrayPrototypeHasNoElements()) {
return CallJsBuiltin("ArrayUnshift", args);
}
-
- JSArray* array = JSArray::cast(*args.receiver());
+ JSArray* array = JSArray::cast(receiver);
ASSERT(array->HasFastElements());
int len = Smi::cast(array->length())->value();
@@ -468,8 +494,6 @@ BUILTIN(ArrayUnshift) {
// we should never hit this case.
ASSERT(to_add <= (Smi::kMaxValue - len));
- FixedArray* elms = FixedArray::cast(array->elements());
-
if (new_length > elms->length()) {
// New backing storage is needed.
int capacity = new_length + (new_length >> 1) + 16;
@@ -502,11 +526,13 @@ BUILTIN(ArrayUnshift) {
BUILTIN(ArraySlice) {
- if (!ArrayPrototypeHasNoElements()) {
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)
+ || !ArrayPrototypeHasNoElements()) {
return CallJsBuiltin("ArraySlice", args);
}
-
- JSArray* array = JSArray::cast(*args.receiver());
+ JSArray* array = JSArray::cast(receiver);
ASSERT(array->HasFastElements());
int len = Smi::cast(array->length())->value();
@@ -557,8 +583,6 @@ BUILTIN(ArraySlice) {
if (result->IsFailure()) return result;
FixedArray* result_elms = FixedArray::cast(result);
- FixedArray* elms = FixedArray::cast(array->elements());
-
AssertNoAllocation no_gc;
CopyElements(&no_gc, result_elms, 0, elms, k, result_len);
@@ -572,11 +596,13 @@ BUILTIN(ArraySlice) {
BUILTIN(ArraySplice) {
- if (!ArrayPrototypeHasNoElements()) {
+ Object* receiver = *args.receiver();
+ FixedArray* elms = NULL;
+ if (!IsJSArrayWithFastElements(receiver, &elms)
+ || !ArrayPrototypeHasNoElements()) {
return CallJsBuiltin("ArraySplice", args);
}
-
- JSArray* array = JSArray::cast(*args.receiver());
+ JSArray* array = JSArray::cast(receiver);
ASSERT(array->HasFastElements());
int len = Smi::cast(array->length())->value();
@@ -626,8 +652,6 @@ BUILTIN(ArraySplice) {
if (result->IsFailure()) return result;
FixedArray* result_elms = FixedArray::cast(result);
- FixedArray* elms = FixedArray::cast(array->elements());
-
AssertNoAllocation no_gc;
// Fill newly created array.
CopyElements(&no_gc, result_elms, 0, elms, actualStart, actualDeleteCount);
« no previous file with comments | « src/bootstrapper.cc ('k') | src/contexts.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698