Revision: 4129
Author: [email protected]
Date: Mon Mar 15 03:52:38 2010
Log: Add Array.concat builtin for the most common case.

Review URL: http://codereview.chromium.org/954001
http://code.google.com/p/v8/source/detail?r=4129

Modified:
 /branches/bleeding_edge/src/array.js
 /branches/bleeding_edge/src/builtins.cc
 /branches/bleeding_edge/src/builtins.h
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/v8-counters.h

=======================================
--- /branches/bleeding_edge/src/array.js        Mon Mar 15 03:14:59 2010
+++ /branches/bleeding_edge/src/array.js        Mon Mar 15 03:52:38 2010
@@ -1133,7 +1133,7 @@
     "join", getFunction("join", ArrayJoin),
     "pop", getFunction("pop", ArrayPop),
     "push", getFunction("push", ArrayPush, 1),
-    "concat", getFunction("concat", ArrayConcat),
+    "concat", getFunction("concat", ArrayConcat, 1),
     "reverse", getFunction("reverse", ArrayReverse),
     "shift", getFunction("shift", ArrayShift),
     "unshift", getFunction("unshift", ArrayUnshift, 1),
=======================================
--- /branches/bleeding_edge/src/builtins.cc     Fri Mar 12 08:54:35 2010
+++ /branches/bleeding_edge/src/builtins.cc     Mon Mar 15 03:52:38 2010
@@ -725,6 +725,63 @@

   return result_array;
 }
+
+
+BUILTIN(ArrayConcat) {
+  Counters::array_concat_builtin_total.Increment();
+  if (args.length() != 2) {
+    // Fast case only for concating two arrays.
+    return CallJsBuiltin("ArrayConcat", args);
+  }
+  Counters::array_concat_builtin_two_args.Increment();
+
+  Object* receiver_obj = *args.receiver();
+  FixedArray* receiver_elms = NULL;
+  Object* arg_obj = args[1];
+  FixedArray* arg_elms = NULL;
+  if (!IsJSArrayWithFastElements(receiver_obj, &receiver_elms)
+      || !IsJSArrayWithFastElements(arg_obj, &arg_elms)
+      || !ArrayPrototypeHasNoElements()) {
+    return CallJsBuiltin("ArrayConcat", args);
+  }
+
+  JSArray* receiver_array = JSArray::cast(receiver_obj);
+  ASSERT(receiver_array->HasFastElements());
+  JSArray* arg_array = JSArray::cast(arg_obj);
+  ASSERT(arg_array->HasFastElements());
+
+  int receiver_len = Smi::cast(receiver_array->length())->value();
+  int arg_len = Smi::cast(arg_array->length())->value();
+  ASSERT(receiver_len <= (Smi::kMaxValue - arg_len));
+
+  int result_len = receiver_len + arg_len;
+  if (result_len > FixedArray::kMaxSize) {
+    return CallJsBuiltin("ArrayConcat", args);
+  }
+  if (result_len == 0) {
+    return AllocateEmptyJSArray();
+  }
+
+  // Allocate result.
+  Object* result = AllocateJSArray();
+  if (result->IsFailure()) return result;
+  JSArray* result_array = JSArray::cast(result);
+
+  result = Heap::AllocateUninitializedFixedArray(result_len);
+  if (result->IsFailure()) return result;
+  FixedArray* result_elms = FixedArray::cast(result);
+
+  // Copy data.
+  AssertNoAllocation no_gc;
+  CopyElements(&no_gc, result_elms, 0, receiver_elms, 0, receiver_len);
+  CopyElements(&no_gc, result_elms, receiver_len, arg_elms, 0, arg_len);
+
+  // Set the length and elements.
+  result_array->set_length(Smi::FromInt(result_len));
+  result_array->set_elements(result_elms);
+
+  return result_array;
+}


// -----------------------------------------------------------------------------
=======================================
--- /branches/bleeding_edge/src/builtins.h      Thu Feb 18 09:30:32 2010
+++ /branches/bleeding_edge/src/builtins.h      Mon Mar 15 03:52:38 2010
@@ -52,6 +52,7 @@
   V(ArrayUnshift, NO_EXTRA_ARGUMENTS)                               \
   V(ArraySlice, NO_EXTRA_ARGUMENTS)                                 \
   V(ArraySplice, NO_EXTRA_ARGUMENTS)                                \
+  V(ArrayConcat, NO_EXTRA_ARGUMENTS)                                \
                                                                     \
   V(HandleApiCall, NEEDS_CALLED_FUNCTION)                           \
   V(FastHandleApiCall, NO_EXTRA_ARGUMENTS)                          \
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Fri Mar 12 05:45:31 2010
+++ /branches/bleeding_edge/src/runtime.cc      Mon Mar 15 03:52:38 2010
@@ -1297,6 +1297,7 @@
   InstallBuiltin(holder, "unshift", Builtins::ArrayUnshift);
   InstallBuiltin(holder, "slice", Builtins::ArraySlice);
   InstallBuiltin(holder, "splice", Builtins::ArraySplice);
+  InstallBuiltin(holder, "concat", Builtins::ArrayConcat);

   return *holder;
 }
=======================================
--- /branches/bleeding_edge/src/v8-counters.h   Thu Mar 11 00:31:15 2010
+++ /branches/bleeding_edge/src/v8-counters.h   Mon Mar 15 03:52:38 2010
@@ -151,6 +151,8 @@
   SC(constructed_objects_stub, V8.ConstructedObjectsStub)             \
   SC(array_function_runtime, V8.ArrayFunctionRuntime)                 \
   SC(array_function_native, V8.ArrayFunctionNative)                   \
+  SC(array_concat_builtin_total, V8.ArrayConcatTotal)                 \
+  SC(array_concat_builtin_two_args, V8.ArrayConcatTwoArgs)            \
   SC(for_in, V8.ForIn)                                                \
   SC(enum_cache_hits, V8.EnumCacheHits)                               \
   SC(enum_cache_misses, V8.EnumCacheMisses)                           \

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to