1fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/api.h"
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arguments.h"
91e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org#include "src/base/once.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/bootstrapper.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/builtins.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/cpu-profiler.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/gdb-jit.h"
143e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org#include "src/heap/mark-compact.h"
15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/heap-profiler.h"
166474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org#include "src/ic/handler-compiler.h"
17a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org#include "src/ic/ic.h"
189bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org#include "src/prototype.h"
19196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/vm-state-inl.h"
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
2271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
24b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgnamespace {
25b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
26b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Arguments object passed to C++ builtins.
27b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgtemplate <BuiltinExtraArguments extra_args>
28b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgclass BuiltinArguments : public Arguments {
29b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org public:
30b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  BuiltinArguments(int length, Object** arguments)
31b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      : Arguments(length, arguments) { }
32b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
33b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Object*& operator[] (int index) {
34e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index < length());
35b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return Arguments::operator[](index);
36b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
37b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
38b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  template <class S> Handle<S> at(int index) {
39e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(index < length());
40b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return Arguments::at<S>(index);
41b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
42b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
43b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Handle<Object> receiver() {
44b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return Arguments::at<Object>(0);
45b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
46b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
47b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Handle<JSFunction> called_function() {
48b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    STATIC_ASSERT(extra_args == NEEDS_CALLED_FUNCTION);
49b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return Arguments::at<JSFunction>(Arguments::length() - 1);
50b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
51b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
52b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Gets the total number of arguments including the receiver (but
53b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // excluding extra arguments).
54b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  int length() const {
55b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    STATIC_ASSERT(extra_args == NO_EXTRA_ARGUMENTS);
56b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    return Arguments::length();
57b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
58b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
59b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef DEBUG
60b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  void Verify() {
61b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    // Check we have at least the receiver.
62e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(Arguments::length() >= 1);
63b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  }
64b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif
65b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org};
66b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
67b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
68b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Specialize BuiltinArguments for the called function extra argument.
69b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
70b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgtemplate <>
71b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgint BuiltinArguments<NEEDS_CALLED_FUNCTION>::length() const {
72b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return Arguments::length() - 1;
73b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
74b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
75b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef DEBUG
76b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgtemplate <>
77b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgvoid BuiltinArguments<NEEDS_CALLED_FUNCTION>::Verify() {
78b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Check we have at least the receiver and the called function.
79e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(Arguments::length() >= 2);
80b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // Make sure cast to JSFunction succeeds.
81b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  called_function();
82b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
83b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif
84b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
85b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
86b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#define DEF_ARG_TYPE(name, spec)                      \
87b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  typedef BuiltinArguments<spec> name##ArgumentsType;
88b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgBUILTIN_LIST_C(DEF_ARG_TYPE)
89b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#undef DEF_ARG_TYPE
90b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
91b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}  // namespace
92b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
9343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
94b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// Support macro for defining builtins in C++.
9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A builtin function is defined by writing:
9843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
99b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org//   BUILTIN(name) {
10043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//     ...
10143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//   }
10243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
103b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// In the body of the builtin function the arguments can be accessed
104b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org// through the BuiltinArguments object args.
10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
106b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#ifdef DEBUG
10743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
108f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org#define BUILTIN(name)                                            \
109a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  MUST_USE_RESULT static Object* Builtin_Impl_##name(            \
110f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      name##ArgumentsType args, Isolate* isolate);               \
111a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  MUST_USE_RESULT static Object* Builtin_##name(                 \
112f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      int args_length, Object** args_object, Isolate* isolate) { \
113f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    name##ArgumentsType args(args_length, args_object);          \
114f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    args.Verify();                                               \
115f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    return Builtin_Impl_##name(args, isolate);                   \
116f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }                                                              \
117a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  MUST_USE_RESULT static Object* Builtin_Impl_##name(            \
118ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      name##ArgumentsType args, Isolate* isolate)
11943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#else  // For release mode.
12143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
122f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org#define BUILTIN(name)                                            \
123a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  static Object* Builtin_impl##name(                             \
124f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      name##ArgumentsType args, Isolate* isolate);               \
125a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  static Object* Builtin_##name(                                 \
126f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      int args_length, Object** args_object, Isolate* isolate) { \
127f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    name##ArgumentsType args(args_length, args_object);          \
128f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org    return Builtin_impl##name(args, isolate);                    \
129f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  }                                                              \
130a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.org  static Object* Builtin_impl##name(                             \
131f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org      name##ArgumentsType args, Isolate* isolate)
132b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#endif
13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1350b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org#ifdef DEBUG
136afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.orgstatic inline bool CalledAsConstructor(Isolate* isolate) {
1370b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Calculate the result using a full stack frame iterator and check
1380b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // that the state of the stack is as we assume it to be in the
1390b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // code below.
140c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  StackFrameIterator it(isolate);
141e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(it.frame()->is_exit());
142b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  it.Advance();
143b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  StackFrame* frame = it.frame();
1440b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  bool reference_result = frame->is_construct();
145ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Address fp = Isolate::c_entry_fp(isolate->thread_local_top());
1460b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // Because we know fp points to an exit frame we can use the relevant
1470b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // part of ExitFrame::ComputeCallerState directly.
1480b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  const int kCallerOffset = ExitFrameConstants::kCallerFPOffset;
1490b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  Address caller_fp = Memory::Address_at(fp + kCallerOffset);
1500b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // This inlines the part of StackFrame::ComputeType that grabs the
1510b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // type of the current frame.  Note that StackFrame::ComputeType
1520b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // has been specialized for each architecture so if any one of them
1530b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  // changes this code has to be changed as well.
1540b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  const int kMarkerOffset = StandardFrameConstants::kMarkerOffset;
1550b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  const Smi* kConstructMarker = Smi::FromInt(StackFrame::CONSTRUCT);
1560b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  Object* marker = Memory::Object_at(caller_fp + kMarkerOffset);
1570b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  bool result = (marker == kConstructMarker);
158e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(result, reference_result);
1590b6db5975a9d1ebcf3de7b18603380d99f789e66sgjesse@chromium.org  return result;
160b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org}
161afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#endif
162b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
163e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
16443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// ----------------------------------------------------------------------------
16543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
166b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgBUILTIN(Illegal) {
16743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  UNREACHABLE();
168ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();  // Make compiler happy.
16943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
17043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
172b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgBUILTIN(EmptyFunction) {
173ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return isolate->heap()->undefined_value();
17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
17643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
177d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgstatic void MoveDoubleElements(FixedDoubleArray* dst, int dst_index,
178d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org                               FixedDoubleArray* src, int src_index, int len) {
179fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (len == 0) return;
180d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  MemMove(dst->data_start() + dst_index, src->data_start() + src_index,
181d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org          len * kDoubleSize);
182fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org}
183fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
184fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
185ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic bool ArrayPrototypeHasNoElements(Heap* heap,
18646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org                                        Context* native_context,
187dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org                                        JSObject* array_proto) {
188255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  DisallowHeapAllocation no_gc;
189ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // This method depends on non writability of Object and Array prototype
190ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // fields.
191ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (array_proto->elements() != heap->empty_fixed_array()) return false;
192ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Object.prototype
19393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  PrototypeIterator iter(heap->isolate(), array_proto);
19493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  if (iter.IsAtEnd()) {
19593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org    return false;
19693720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  }
19793720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  array_proto = JSObject::cast(iter.GetCurrent());
19846839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  if (array_proto != native_context->initial_object_prototype()) return false;
199ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (array_proto->elements() != heap->empty_fixed_array()) return false;
20093720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  iter.Advance();
20193720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  return iter.IsAtEnd();
202ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
203ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
204ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
205a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org// Returns empty handle if not applicable.
206303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.orgMUST_USE_RESULT
2078f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.orgstatic inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
208a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    Isolate* isolate,
209a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    Handle<Object> receiver,
210a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    Arguments* args,
211a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    int first_added_arg) {
2128f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>();
213a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  Handle<JSArray> array = Handle<JSArray>::cast(receiver);
214202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  // If there may be elements accessors in the prototype chain, the fast path
2153484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  // cannot be used if there arguments to add to the array.
2163484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (args != NULL && array->map()->DictionaryElementsInPrototypeChainOnly()) {
217202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org    return MaybeHandle<FixedArrayBase>();
218202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org  }
2198f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>();
2208f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (!array->map()->is_extensible()) return MaybeHandle<FixedArrayBase>();
221255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<FixedArrayBase> elms(array->elements(), isolate);
222a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org  Heap* heap = isolate->heap();
223a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Map* map = elms->map();
224a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  if (map == heap->fixed_array_map()) {
225830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    if (args == NULL || array->HasFastObjectElements()) return elms;
226a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  } else if (map == heap->fixed_cow_array_map()) {
227a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    elms = JSObject::EnsureWritableFastElements(array);
228a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    if (args == NULL || array->HasFastObjectElements()) return elms;
229fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  } else if (map == heap->fixed_double_array_map()) {
230fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (args == NULL) return elms;
231a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  } else {
2328f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return MaybeHandle<FixedArrayBase>();
233f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org  }
234a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
235a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // Need to ensure that the arguments passed in args can be contained in
236a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // the array.
237a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  int args_length = args->length();
238255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  if (first_added_arg >= args_length) return handle(array->elements(), isolate);
239a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
240fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ElementsKind origin_kind = array->map()->elements_kind();
241e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!IsFastObjectElementsKind(origin_kind));
242fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ElementsKind target_kind = origin_kind;
243255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  {
244255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    DisallowHeapAllocation no_gc;
245255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    int arg_count = args->length() - first_added_arg;
246255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    Object** arguments = args->arguments() - first_added_arg - (arg_count - 1);
247255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    for (int i = 0; i < arg_count; i++) {
248255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      Object* arg = arguments[i];
249255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (arg->IsHeapObject()) {
250255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        if (arg->IsHeapNumber()) {
251255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          target_kind = FAST_DOUBLE_ELEMENTS;
252255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        } else {
253255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          target_kind = FAST_ELEMENTS;
254255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          break;
255255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        }
256fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
257fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
258fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
259fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (target_kind != origin_kind) {
260a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org    JSObject::TransitionElementsKind(array, target_kind);
261255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    return handle(array->elements(), isolate);
262fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
263fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  return elms;
264f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org}
265f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
266f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org
267ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic inline bool IsJSArrayFastElementMovingAllowed(Heap* heap,
268ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                                     JSArray* receiver) {
269b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  if (!FLAG_clever_optimizations) return false;
270255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  DisallowHeapAllocation no_gc;
27146839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  Context* native_context = heap->isolate()->context()->native_context();
272dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org  JSObject* array_proto =
27346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org      JSObject::cast(native_context->array_function()->prototype());
27493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  PrototypeIterator iter(heap->isolate(), receiver);
27593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org  return iter.GetCurrent() == array_proto &&
27646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org         ArrayPrototypeHasNoElements(heap, native_context, array_proto);
277dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org}
278dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org
279dff694e8cc18aa9640e92962de2699b9d07a7690vegorov@chromium.org
280a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* CallJsBuiltin(
281ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
282303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    const char* name,
283303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
284ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope handleScope(isolate);
285ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
2869fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org  Handle<Object> js_builtin = Object::GetProperty(
2879fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      isolate,
2889fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      handle(isolate->native_context()->builtins(), isolate),
2899fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      name).ToHandleChecked();
290a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  Handle<JSFunction> function = Handle<JSFunction>::cast(js_builtin);
291a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  int argc = args.length() - 1;
292a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  ScopedVector<Handle<Object> > argv(argc);
293a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  for (int i = 0; i < argc; ++i) {
294a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org    argv[i] = args.at<Object>(i + 1);
295ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
2962ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<Object> result;
2972ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2982ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      isolate, result,
2992ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      Execution::Call(isolate,
3002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                      function,
3012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                      args.receiver(),
3022ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                      argc,
3032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org                      argv.start()));
304ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  return *result;
305ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org}
306ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
307ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
308b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgBUILTIN(ArrayPush) {
3097010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  HandleScope scope(isolate);
3107010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<Object> receiver = args.receiver();
3118f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  MaybeHandle<FixedArrayBase> maybe_elms_obj =
312a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
3138f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<FixedArrayBase> elms_obj;
3148f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (!maybe_elms_obj.ToHandle(&elms_obj)) {
3158f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return CallJsBuiltin(isolate, "ArrayPush", args);
3168f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  }
31743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
3187010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<JSArray> array = Handle<JSArray>::cast(receiver);
319fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  int len = Smi::cast(array->length())->value();
320fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  int to_add = args.length() - 1;
321fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
322fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    return CallJsBuiltin(isolate, "ArrayPush", args);
323fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  }
324e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!array->map()->is_observed());
3257c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org
326fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ElementsKind kind = array->GetElementsKind();
32743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
328fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (IsFastSmiOrObjectElementsKind(kind)) {
3297010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
330fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (to_add == 0) {
331fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      return Smi::FromInt(len);
332303ada708275d2d425b846fb237f1ba7598ee239lrn@chromium.org    }
333fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Currently fixed arrays cannot grow too big, so
334fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // we should never hit this case.
335e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(to_add <= (Smi::kMaxValue - len));
336b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
337fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    int new_length = len + to_add;
338ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
339fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (new_length > elms->length()) {
340fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // New backing storage is needed.
341fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      int capacity = new_length + (new_length >> 1) + 16;
3427010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      Handle<FixedArray> new_elms =
3437010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org          isolate->factory()->NewUninitializedFixedArray(capacity);
344fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
34583130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      ElementsAccessor* accessor = array->GetElementsAccessor();
3467010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      accessor->CopyElements(
347255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          elms_obj, 0, kind, new_elms, 0,
348255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          ElementsAccessor::kCopyToEndAndInitializeToHole);
3495c838251403b0be9a882540f1922577abba4c872ager@chromium.org
350fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      elms = new_elms;
351fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
3525c838251403b0be9a882540f1922577abba4c872ager@chromium.org
353fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Add the provided values.
35479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
355fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
356fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    for (int index = 0; index < to_add; index++) {
357fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      elms->set(index + len, args[index + 1], mode);
358fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
3607010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    if (*elms != array->elements()) {
3617010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      array->set_elements(*elms);
362fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
363fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
364fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Set the length.
365fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    array->set_length(Smi::FromInt(new_length));
366fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    return Smi::FromInt(new_length);
367fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  } else {
368fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    int elms_len = elms_obj->length();
369fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (to_add == 0) {
370fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      return Smi::FromInt(len);
371fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
372fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Currently fixed arrays cannot grow too big, so
373fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // we should never hit this case.
374e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(to_add <= (Smi::kMaxValue - len));
375fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
376fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    int new_length = len + to_add;
377fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
3787010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    Handle<FixedDoubleArray> new_elms;
379fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
380fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (new_length > elms_len) {
381fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // New backing storage is needed.
382fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      int capacity = new_length + (new_length >> 1) + 16;
383f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      // Create new backing store; since capacity > 0, we can
384f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      // safely cast to FixedDoubleArray.
385f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org      new_elms = Handle<FixedDoubleArray>::cast(
386f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org          isolate->factory()->NewFixedDoubleArray(capacity));
387fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
38883130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org      ElementsAccessor* accessor = array->GetElementsAccessor();
3897010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      accessor->CopyElements(
390255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          elms_obj, 0, kind, new_elms, 0,
391255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          ElementsAccessor::kCopyToEndAndInitializeToHole);
3927010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org
393fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else {
394fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // to_add is > 0 and new_length <= elms_len, so elms_obj cannot be the
395fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      // empty_fixed_array.
3967010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      new_elms = Handle<FixedDoubleArray>::cast(elms_obj);
397fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
398fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
399fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Add the provided values.
40079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
401fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    int index;
402fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    for (index = 0; index < to_add; index++) {
403fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Object* arg = args[index + 1];
404fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      new_elms->set(index + len, arg->Number());
405fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
406fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
4077010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org    if (*new_elms != array->elements()) {
4087010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      array->set_elements(*new_elms);
409fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
410fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
411fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    // Set the length.
412fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    array->set_length(Smi::FromInt(new_length));
413fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    return Smi::FromInt(new_length);
414fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
41543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
41643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
41743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
418b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgBUILTIN(ArrayPop) {
41969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  HandleScope scope(isolate);
42069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  Handle<Object> receiver = args.receiver();
4218f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  MaybeHandle<FixedArrayBase> maybe_elms_obj =
422a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
4238f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<FixedArrayBase> elms_obj;
4248f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (!maybe_elms_obj.ToHandle(&elms_obj)) {
4258f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org    return CallJsBuiltin(isolate, "ArrayPop", args);
4268f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  }
42769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
42869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  Handle<JSArray> array = Handle<JSArray>::cast(receiver);
429e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!array->map()->is_observed());
430e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
43143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int len = Smi::cast(array->length())->value();
43269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  if (len == 0) return isolate->heap()->undefined_value();
43343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
434fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ElementsAccessor* accessor = array->GetElementsAccessor();
435fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  int new_length = len - 1;
4363484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> element =
4373484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org      accessor->Get(array, array, new_length, elms_obj).ToHandleChecked();
4383484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  if (element->IsTheHole()) {
4393484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    return CallJsBuiltin(isolate, "ArrayPop", args);
44043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
4418496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_ON_EXCEPTION(
442202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      isolate,
443202b1d8cd93e567672cc92f48fedc35989c47312machenbach@chromium.org      accessor->SetLength(array, handle(Smi::FromInt(new_length), isolate)));
44469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  return *element;
44543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
44643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
44743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
448ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgBUILTIN(ArrayShift) {
4497010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  HandleScope scope(isolate);
450ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
4517010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<Object> receiver = args.receiver();
4528f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  MaybeHandle<FixedArrayBase> maybe_elms_obj =
453a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
4548f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<FixedArrayBase> elms_obj;
4558f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (!maybe_elms_obj.ToHandle(&elms_obj) ||
4567010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      !IsJSArrayFastElementMovingAllowed(heap,
4577010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org                                         *Handle<JSArray>::cast(receiver))) {
458ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return CallJsBuiltin(isolate, "ArrayShift", args);
4595c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
4607010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  Handle<JSArray> array = Handle<JSArray>::cast(receiver);
461e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!array->map()->is_observed());
462e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
4635c838251403b0be9a882540f1922577abba4c872ager@chromium.org  int len = Smi::cast(array->length())->value();
464ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (len == 0) return heap->undefined_value();
4655c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4665c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Get first element
467fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ElementsAccessor* accessor = array->GetElementsAccessor();
4683484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org  Handle<Object> first =
4693484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    accessor->Get(array, array, 0, elms_obj).ToHandleChecked();
4705c838251403b0be9a882540f1922577abba4c872ager@chromium.org  if (first->IsTheHole()) {
4713484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org    return CallJsBuiltin(isolate, "ArrayShift", args);
4725c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
4735c838251403b0be9a882540f1922577abba4c872ager@chromium.org
47463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org  if (heap->CanMoveObjectStart(*elms_obj)) {
4753e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org    array->set_elements(heap->LeftTrimFixedArray(*elms_obj, 1));
4765d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  } else {
4775d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org    // Shift the elements.
478fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    if (elms_obj->IsFixedArray()) {
4797010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
48079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      DisallowHeapAllocation no_gc;
4817010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      heap->MoveElements(*elms, 0, 1, len - 1);
482fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      elms->set(len - 1, heap->the_hole_value());
483fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else {
4847010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj);
4857010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org      MoveDoubleElements(*elms, 0, *elms, 1, len - 1);
486fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      elms->set_the_hole(len - 1);
487fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
4885d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  }
4895c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4905c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Set the length.
4915c838251403b0be9a882540f1922577abba4c872ager@chromium.org  array->set_length(Smi::FromInt(len - 1));
4925c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4937010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  return *first;
4945c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
4955c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4965c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4975c838251403b0be9a882540f1922577abba4c872ager@chromium.orgBUILTIN(ArrayUnshift) {
498fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  HandleScope scope(isolate);
499ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
500fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Handle<Object> receiver = args.receiver();
5018f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  MaybeHandle<FixedArrayBase> maybe_elms_obj =
502a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
5038f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<FixedArrayBase> elms_obj;
5048f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (!maybe_elms_obj.ToHandle(&elms_obj) ||
505fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      !IsJSArrayFastElementMovingAllowed(heap,
506fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                                         *Handle<JSArray>::cast(receiver))) {
507ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return CallJsBuiltin(isolate, "ArrayUnshift", args);
508ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
509fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Handle<JSArray> array = Handle<JSArray>::cast(receiver);
510e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!array->map()->is_observed());
511fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (!array->HasFastSmiOrObjectElements()) {
512fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    return CallJsBuiltin(isolate, "ArrayUnshift", args);
513fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
5145c838251403b0be9a882540f1922577abba4c872ager@chromium.org  int len = Smi::cast(array->length())->value();
5155c838251403b0be9a882540f1922577abba4c872ager@chromium.org  int to_add = args.length() - 1;
5165c838251403b0be9a882540f1922577abba4c872ager@chromium.org  int new_length = len + to_add;
5175c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Currently fixed arrays cannot grow too big, so
5185c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // we should never hit this case.
519e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(to_add <= (Smi::kMaxValue - len));
5205c838251403b0be9a882540f1922577abba4c872ager@chromium.org
521fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  if (to_add > 0 && JSArray::WouldChangeReadOnlyLength(array, len + to_add)) {
522fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org    return CallJsBuiltin(isolate, "ArrayUnshift", args);
523fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  }
524fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
525fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
526fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org
527fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  JSObject::EnsureCanContainElements(array, &args, 1, to_add,
528fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                                     DONT_ALLOW_DOUBLE_ELEMENTS);
529c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
5305c838251403b0be9a882540f1922577abba4c872ager@chromium.org  if (new_length > elms->length()) {
5315c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // New backing storage is needed.
5325c838251403b0be9a882540f1922577abba4c872ager@chromium.org    int capacity = new_length + (new_length >> 1) + 16;
533fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    Handle<FixedArray> new_elms =
534fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        isolate->factory()->NewUninitializedFixedArray(capacity);
535fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
53683130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    ElementsKind kind = array->GetElementsKind();
53783130cfc204d3ffed6832a7ef149b19328a58b33svenpanne@chromium.org    ElementsAccessor* accessor = array->GetElementsAccessor();
538fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    accessor->CopyElements(
539255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        elms, 0, kind, new_elms, to_add,
540255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        ElementsAccessor::kCopyToEndAndInitializeToHole);
541fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
5425c838251403b0be9a882540f1922577abba4c872ager@chromium.org    elms = new_elms;
543fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    array->set_elements(*elms);
5445c838251403b0be9a882540f1922577abba4c872ager@chromium.org  } else {
54579e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
546fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    heap->MoveElements(*elms, to_add, 0, len);
5475c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
5485c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5495c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Add the provided values.
55079e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
5515c838251403b0be9a882540f1922577abba4c872ager@chromium.org  WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
5525c838251403b0be9a882540f1922577abba4c872ager@chromium.org  for (int i = 0; i < to_add; i++) {
5535c838251403b0be9a882540f1922577abba4c872ager@chromium.org    elms->set(i, args[i + 1], mode);
5545c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
5555c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5565c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Set the length.
5575c838251403b0be9a882540f1922577abba4c872ager@chromium.org  array->set_length(Smi::FromInt(new_length));
5585c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return Smi::FromInt(new_length);
5595c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
5605c838251403b0be9a882540f1922577abba4c872ager@chromium.org
5615c838251403b0be9a882540f1922577abba4c872ager@chromium.org
562ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.orgBUILTIN(ArraySlice) {
563c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  HandleScope scope(isolate);
564ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
565c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  Handle<Object> receiver = args.receiver();
566023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  int len = -1;
567255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  int relative_start = 0;
568255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  int relative_end = 0;
569255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  {
570255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    DisallowHeapAllocation no_gc;
571255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    if (receiver->IsJSArray()) {
572255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      JSArray* array = JSArray::cast(*receiver);
573255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (!IsJSArrayFastElementMovingAllowed(heap, array)) {
574255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
575255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        return CallJsBuiltin(isolate, "ArraySlice", args);
576255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      }
5779e3e0b618a14a05efd7d66f20bac4423dd3a1a2ffschneider@chromium.org
578255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (!array->HasFastElements()) {
579255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
580255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        return CallJsBuiltin(isolate, "ArraySlice", args);
581255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      }
582fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
583255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      len = Smi::cast(array->length())->value();
584fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else {
585255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      // Array.slice(arguments, ...) is quite a common idiom (notably more
586255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      // than 50% of invocations in Web apps).  Treat it in C++ as well.
587f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org      Map* arguments_map =
588f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org          isolate->context()->native_context()->sloppy_arguments_map();
589255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
590255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      bool is_arguments_object_with_fast_elements =
591255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          receiver->IsJSObject() &&
592255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          JSObject::cast(*receiver)->map() == arguments_map;
593255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (!is_arguments_object_with_fast_elements) {
594255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
595255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        return CallJsBuiltin(isolate, "ArraySlice", args);
596255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      }
597255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      JSObject* object = JSObject::cast(*receiver);
598fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
599255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (!object->HasFastElements()) {
600255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
601255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        return CallJsBuiltin(isolate, "ArraySlice", args);
602255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      }
6035c838251403b0be9a882540f1922577abba4c872ager@chromium.org
604255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex);
605255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (!len_obj->IsSmi()) {
606255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
607255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        return CallJsBuiltin(isolate, "ArraySlice", args);
608255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      }
609255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      len = Smi::cast(len_obj)->value();
610255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (len > object->elements()->length()) {
611255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
612fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        return CallJsBuiltin(isolate, "ArraySlice", args);
613fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
6145c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
615255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
616e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(len >= 0);
617255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    int n_arguments = args.length() - 1;
618255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
619255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    // Note carefully choosen defaults---if argument is missing,
620255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    // it's undefined which gets converted to 0 for relative_start
621255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    // and to len for relative_end.
622255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    relative_start = 0;
623255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    relative_end = len;
624255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    if (n_arguments > 0) {
625255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      Object* arg1 = args[1];
626255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (arg1->IsSmi()) {
627255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        relative_start = Smi::cast(arg1)->value();
628255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      } else if (arg1->IsHeapNumber()) {
629255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        double start = HeapNumber::cast(arg1)->value();
630255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        if (start < kMinInt || start > kMaxInt) {
631255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          AllowHeapAllocation allow_allocation;
632fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org          return CallJsBuiltin(isolate, "ArraySlice", args);
633fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        }
634255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
635255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      } else if (!arg1->IsUndefined()) {
636255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
637ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return CallJsBuiltin(isolate, "ArraySlice", args);
6385c838251403b0be9a882540f1922577abba4c872ager@chromium.org      }
639255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (n_arguments > 1) {
640255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        Object* arg2 = args[2];
641255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        if (arg2->IsSmi()) {
642255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          relative_end = Smi::cast(arg2)->value();
643255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        } else if (arg2->IsHeapNumber()) {
644255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          double end = HeapNumber::cast(arg2)->value();
645255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          if (end < kMinInt || end > kMaxInt) {
646255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            AllowHeapAllocation allow_allocation;
647255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            return CallJsBuiltin(isolate, "ArraySlice", args);
648255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          }
649255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          relative_end = std::isnan(end) ? 0 : static_cast<int>(end);
650255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        } else if (!arg2->IsUndefined()) {
651255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          AllowHeapAllocation allow_allocation;
652255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          return CallJsBuiltin(isolate, "ArraySlice", args);
653255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        }
654255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      }
6555c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
6565c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
6575c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6585c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 6.
659ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int k = (relative_start < 0) ? Max(len + relative_start, 0)
660ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                               : Min(relative_start, len);
6615c838251403b0be9a882540f1922577abba4c872ager@chromium.org
6625c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // ECMAScript 232, 3rd Edition, Section 15.4.4.10, step 8.
663ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int final = (relative_end < 0) ? Max(len + relative_end, 0)
664ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                 : Min(relative_end, len);
6655c838251403b0be9a882540f1922577abba4c872ager@chromium.org
666fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Calculate the length of result array.
667fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  int result_len = Max(final - k, 0);
6685c838251403b0be9a882540f1922577abba4c872ager@chromium.org
669255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<JSObject> object = Handle<JSObject>::cast(receiver);
670255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<FixedArrayBase> elms(object->elements(), isolate);
671255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
672a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  ElementsKind kind = object->GetElementsKind();
673a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  if (IsHoleyElementsKind(kind)) {
674255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    DisallowHeapAllocation no_gc;
675a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    bool packed = true;
676a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
677a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    for (int i = k; i < final; i++) {
6788f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org      if (!accessor->HasElement(object, object, i, elms)) {
679a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        packed = false;
680a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org        break;
681a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      }
682a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
683a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    if (packed) {
684a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      kind = GetPackedElementsKind(kind);
685a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    } else if (!receiver->IsJSArray()) {
686255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      AllowHeapAllocation allow_allocation;
687a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org      return CallJsBuiltin(isolate, "ArraySlice", args);
688a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org    }
689a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  }
690a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org
691c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  Handle<JSArray> result_array =
692c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org      isolate->factory()->NewJSArray(kind, result_len, result_len);
6938e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
69479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org  DisallowHeapAllocation no_gc;
695c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  if (result_len == 0) return *result_array;
696c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
697fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ElementsAccessor* accessor = object->GetElementsAccessor();
698255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  accessor->CopyElements(
699255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      elms, k, kind, handle(result_array->elements(), isolate), 0, result_len);
700c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  return *result_array;
7015c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
7025c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7035c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7045c838251403b0be9a882540f1922577abba4c872ager@chromium.orgBUILTIN(ArraySplice) {
705fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  HandleScope scope(isolate);
706ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
707fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Handle<Object> receiver = args.receiver();
7088f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  MaybeHandle<FixedArrayBase> maybe_elms_obj =
709a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org      EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
7108f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  Handle<FixedArrayBase> elms_obj;
7118f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  if (!maybe_elms_obj.ToHandle(&elms_obj) ||
712fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      !IsJSArrayFastElementMovingAllowed(heap,
713fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                                         *Handle<JSArray>::cast(receiver))) {
714ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    return CallJsBuiltin(isolate, "ArraySplice", args);
715ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
716fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Handle<JSArray> array = Handle<JSArray>::cast(receiver);
717e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!array->map()->is_observed());
718e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org
7195c838251403b0be9a882540f1922577abba4c872ager@chromium.org  int len = Smi::cast(array->length())->value();
7205c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7215c838251403b0be9a882540f1922577abba4c872ager@chromium.org  int n_arguments = args.length() - 1;
7225c838251403b0be9a882540f1922577abba4c872ager@chromium.org
723ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int relative_start = 0;
72431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  if (n_arguments > 0) {
725255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    DisallowHeapAllocation no_gc;
726255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    Object* arg1 = args[1];
72731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    if (arg1->IsSmi()) {
728255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      relative_start = Smi::cast(arg1)->value();
729fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    } else if (arg1->IsHeapNumber()) {
730255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      double start = HeapNumber::cast(arg1)->value();
731fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (start < kMinInt || start > kMaxInt) {
732255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
733fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        return CallJsBuiltin(isolate, "ArraySplice", args);
734fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
735ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org      relative_start = std::isnan(start) ? 0 : static_cast<int>(start);
73631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    } else if (!arg1->IsUndefined()) {
737255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      AllowHeapAllocation allow_allocation;
738ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      return CallJsBuiltin(isolate, "ArraySplice", args);
73931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    }
7405c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
741ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  int actual_start = (relative_start < 0) ? Max(len + relative_start, 0)
742ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                          : Min(relative_start, len);
7435c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7445c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // SpiderMonkey, TraceMonkey and JSC treat the case where no delete count is
74531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // given as a request to delete all the elements from the start.
74631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // And it differs from the case of undefined delete count.
7475c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // This does not follow ECMA-262, but we do the same for
7485c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // compatibility.
74931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  int actual_delete_count;
75031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  if (n_arguments == 1) {
751e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(len - actual_start >= 0);
75231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    actual_delete_count = len - actual_start;
75331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  } else {
75431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    int value = 0;  // ToInteger(undefined) == 0
75531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    if (n_arguments > 1) {
756255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      DisallowHeapAllocation no_gc;
75731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org      Object* arg2 = args[2];
75831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org      if (arg2->IsSmi()) {
75931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org        value = Smi::cast(arg2)->value();
76031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org      } else {
761255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
762ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org        return CallJsBuiltin(isolate, "ArraySplice", args);
76331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org      }
7645c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
76531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org    actual_delete_count = Min(Max(value, 0), len - actual_start);
7665c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
7675c838251403b0be9a882540f1922577abba4c872ager@chromium.org
768fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  ElementsKind elements_kind = array->GetElementsKind();
769fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
770fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
771fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  int new_length = len - actual_delete_count + item_count;
772fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
773fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  // For double mode we do not support changing the length.
774fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (new_length > len && IsFastDoubleElementsKind(elements_kind)) {
775fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    return CallJsBuiltin(isolate, "ArraySplice", args);
776fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
777fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
778fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (new_length == 0) {
779fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    Handle<JSArray> result = isolate->factory()->NewJSArrayWithElements(
780fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        elms_obj, elements_kind, actual_delete_count);
781fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    array->set_elements(heap->empty_fixed_array());
782fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    array->set_length(Smi::FromInt(0));
783fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    return *result;
784fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  }
785fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
786fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  Handle<JSArray> result_array =
787fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      isolate->factory()->NewJSArray(elements_kind,
788fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                                     actual_delete_count,
789fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                                     actual_delete_count);
7905c838251403b0be9a882540f1922577abba4c872ager@chromium.org
791fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (actual_delete_count > 0) {
79279e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
793fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    ElementsAccessor* accessor = array->GetElementsAccessor();
794fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    accessor->CopyElements(
795255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        elms_obj, actual_start, elements_kind,
796255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        handle(result_array->elements(), isolate), 0, actual_delete_count);
797ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  }
7985c838251403b0be9a882540f1922577abba4c872ager@chromium.org
799c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool elms_changed = false;
800ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  if (item_count < actual_delete_count) {
8015c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Shrink the array.
802fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    const bool trim_array = !heap->lo_space()->Contains(*elms_obj) &&
80325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      ((actual_start + item_count) <
80425156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org          (len - actual_delete_count - actual_start));
80525156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    if (trim_array) {
80625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      const int delta = actual_delete_count - item_count;
80725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
808fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (elms_obj->IsFixedDoubleArray()) {
809fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        Handle<FixedDoubleArray> elms =
810fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org            Handle<FixedDoubleArray>::cast(elms_obj);
811fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        MoveDoubleElements(*elms, delta, *elms, 0, actual_start);
812fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      } else {
813fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
81479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org        DisallowHeapAllocation no_gc;
815fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        heap->MoveElements(*elms, delta, 0, actual_start);
81625156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org      }
81725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org
818b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      if (heap->CanMoveObjectStart(*elms_obj)) {
819b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        // On the fast path we move the start of the object in memory.
8203e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org        elms_obj = handle(heap->LeftTrimFixedArray(*elms_obj, delta));
821b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      } else {
822b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        // This is the slow path. We are going to move the elements to the left
823b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        // by copying them. For trimmed values we store the hole.
824b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        if (elms_obj->IsFixedDoubleArray()) {
825b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org          Handle<FixedDoubleArray> elms =
826b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org              Handle<FixedDoubleArray>::cast(elms_obj);
827b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org          MoveDoubleElements(*elms, 0, *elms, delta, len - delta);
8282f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org          elms->FillWithHoles(len - delta, len);
829b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        } else {
830b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org          Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
831b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org          DisallowHeapAllocation no_gc;
832b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org          heap->MoveElements(*elms, 0, delta, len - delta);
8332f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org          elms->FillWithHoles(len - delta, len);
834b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org        }
835b5ed9300c59e8590c9dc588727b6564c244b0f5cmachenbach@chromium.org      }
836c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      elms_changed = true;
83725156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    } else {
838fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (elms_obj->IsFixedDoubleArray()) {
839fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        Handle<FixedDoubleArray> elms =
840fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org            Handle<FixedDoubleArray>::cast(elms_obj);
841fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        MoveDoubleElements(*elms, actual_start + item_count,
842fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org                           *elms, actual_start + actual_delete_count,
843fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                           (len - actual_delete_count - actual_start));
8442f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org        elms->FillWithHoles(new_length, len);
845fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      } else {
846fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
84779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org        DisallowHeapAllocation no_gc;
848fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        heap->MoveElements(*elms, actual_start + item_count,
84959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                           actual_start + actual_delete_count,
85059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                           (len - actual_delete_count - actual_start));
8512f599e5925b02d78bd78703b44741d6b27e53a44machenbach@chromium.org        elms->FillWithHoles(new_length, len);
852fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
85325156ded31ef771a2d799ed902483d83b3ebcbdclrn@chromium.org    }
854ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  } else if (item_count > actual_delete_count) {
855fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
8565c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Currently fixed arrays cannot grow too big, so
8575c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // we should never hit this case.
858e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((item_count - actual_delete_count) <= (Smi::kMaxValue - len));
8595c838251403b0be9a882540f1922577abba4c872ager@chromium.org
8605c838251403b0be9a882540f1922577abba4c872ager@chromium.org    // Check if array need to grow.
8615c838251403b0be9a882540f1922577abba4c872ager@chromium.org    if (new_length > elms->length()) {
8625c838251403b0be9a882540f1922577abba4c872ager@chromium.org      // New backing storage is needed.
8635c838251403b0be9a882540f1922577abba4c872ager@chromium.org      int capacity = new_length + (new_length >> 1) + 16;
864fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      Handle<FixedArray> new_elms =
865fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org          isolate->factory()->NewUninitializedFixedArray(capacity);
866fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
86779e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      DisallowHeapAllocation no_gc;
8688e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org
869fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      ElementsKind kind = array->GetElementsKind();
870fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      ElementsAccessor* accessor = array->GetElementsAccessor();
8718e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      if (actual_start > 0) {
8728e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org        // Copy the part before actual_start as is.
873fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org        accessor->CopyElements(
874255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org            elms, 0, kind, new_elms, 0, actual_start);
8758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      }
876fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      accessor->CopyElements(
877255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          elms, actual_start + actual_delete_count, kind,
878fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org          new_elms, actual_start + item_count,
879255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org          ElementsAccessor::kCopyToEndAndInitializeToHole);
8805c838251403b0be9a882540f1922577abba4c872ager@chromium.org
881fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      elms_obj = new_elms;
882c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      elms_changed = true;
883ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org    } else {
88479e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org      DisallowHeapAllocation no_gc;
885fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org      heap->MoveElements(*elms, actual_start + item_count,
88659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                         actual_start + actual_delete_count,
88759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org                         (len - actual_delete_count - actual_start));
8885c838251403b0be9a882540f1922577abba4c872ager@chromium.org    }
8895c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
8905c838251403b0be9a882540f1922577abba4c872ager@chromium.org
891fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  if (IsFastDoubleElementsKind(elements_kind)) {
892fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    Handle<FixedDoubleArray> elms = Handle<FixedDoubleArray>::cast(elms_obj);
893fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    for (int k = actual_start; k < actual_start + item_count; k++) {
894fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      Object* arg = args[3 + k - actual_start];
895fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      if (arg->IsSmi()) {
896fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        elms->set(k, Smi::cast(arg)->value());
897fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      } else {
898fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org        elms->set(k, HeapNumber::cast(arg)->value());
899fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      }
900fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
901fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  } else {
902fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
90379e7902fa5f94747b5383dd40f3002dd8b62303arossberg@chromium.org    DisallowHeapAllocation no_gc;
904fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
905fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    for (int k = actual_start; k < actual_start + item_count; k++) {
906fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org      elms->set(k, args[3 + k - actual_start], mode);
907fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org    }
9085c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
9095c838251403b0be9a882540f1922577abba4c872ager@chromium.org
910c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  if (elms_changed) {
911fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org    array->set_elements(*elms_obj);
912c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
9135c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Set the length.
9145c838251403b0be9a882540f1922577abba4c872ager@chromium.org  array->set_length(Smi::FromInt(new_length));
9155c838251403b0be9a882540f1922577abba4c872ager@chromium.org
916fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  return *result_array;
9175c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
9185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
9195c838251403b0be9a882540f1922577abba4c872ager@chromium.org
920086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.orgBUILTIN(ArrayConcat) {
921c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  HandleScope scope(isolate);
922086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
923086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int n_arguments = args.length();
924086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  int result_len = 0;
925830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  ElementsKind elements_kind = GetInitialFastElementsKind();
9268e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  bool has_double = false;
927255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  {
928255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    DisallowHeapAllocation no_gc;
929255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    Heap* heap = isolate->heap();
930255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    Context* native_context = isolate->context()->native_context();
931255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    JSObject* array_proto =
932255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        JSObject::cast(native_context->array_function()->prototype());
933255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    if (!ArrayPrototypeHasNoElements(heap, native_context, array_proto)) {
934255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      AllowHeapAllocation allow_allocation;
935aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org      return CallJsBuiltin(isolate, "ArrayConcatJS", args);
936086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    }
937086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
938255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    // Iterate through all the arguments performing checks
939255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    // and calculating total length.
940255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    bool is_holey = false;
941255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    for (int i = 0; i < n_arguments; i++) {
942255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      Object* arg = args[i];
94393720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org      PrototypeIterator iter(isolate, arg);
94493720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org      if (!arg->IsJSArray() || !JSArray::cast(arg)->HasFastElements() ||
94593720aaa16a789ba13d52a265a479b26f4885e2emachenbach@chromium.org          iter.GetCurrent() != array_proto) {
946255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
947aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org        return CallJsBuiltin(isolate, "ArrayConcatJS", args);
948255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      }
949255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      int len = Smi::cast(JSArray::cast(arg)->length())->value();
950255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
951255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      // We shouldn't overflow when adding another len.
952255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2);
953255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt);
954255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      USE(kHalfOfMaxInt);
955255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      result_len += len;
956e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(result_len >= 0);
957255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org
958255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (result_len > FixedDoubleArray::kMaxLength) {
959255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        AllowHeapAllocation allow_allocation;
960aa107b240dc43417fae8469b5c1b0f1ec9f98400machenbach@chromium.org        return CallJsBuiltin(isolate, "ArrayConcatJS", args);
961255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      }
962086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
963255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind();
964255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      has_double = has_double || IsFastDoubleElementsKind(arg_kind);
965255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      is_holey = is_holey || IsFastHoleyElementsKind(arg_kind);
966255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) {
967255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org        elements_kind = arg_kind;
968255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org      }
969830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org    }
970255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    if (is_holey) elements_kind = GetHoleyElementsKind(elements_kind);
971086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
972086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
9738e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // If a double array is concatted into a fast elements array, the fast
9748e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // elements array needs to be initialized to contain proper holes, since
9758e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  // boxing doubles may cause incremental marking.
9768e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org  ArrayStorageAllocationMode mode =
9778e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      has_double && IsFastObjectElementsKind(elements_kind)
9788e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE : DONT_INITIALIZE_ARRAY_ELEMENTS;
979c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  Handle<JSArray> result_array =
980c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org      isolate->factory()->NewJSArray(elements_kind,
981c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org                                     result_len,
982c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org                                     result_len,
983c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org                                     mode);
984c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  if (result_len == 0) return *result_array;
985c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
986fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org  int j = 0;
987255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org  Handle<FixedArrayBase> storage(result_array->elements(), isolate);
9884cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
989086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  for (int i = 0; i < n_arguments; i++) {
990255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    // TODO(ishell): It is crucial to keep |array| as a raw pointer to avoid
991255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    // performance degradation. Revisit this later.
992255043f8054e713a64509c707cfabadd42344683machenbach@chromium.org    JSArray* array = JSArray::cast(args[i]);
993086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org    int len = Smi::cast(array->length())->value();
9944cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org    ElementsKind from_kind = array->GetElementsKind();
9958e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    if (len > 0) {
996c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org      accessor->CopyElements(array, 0, from_kind, storage, j, len);
9978e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org      j += len;
9988e8d8825f97138de12985f8e0d3163074dff5258ulan@chromium.org    }
999086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org  }
1000fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org
1001e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(j == result_len);
1002086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
1003c85dc10954aa3556a00b09b6d28cf2ebfcf528d8machenbach@chromium.org  return *result_array;
1004086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org}
1005086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
1006086aac6d6268988582d3b5b0aa8d24f61ddc1f1ffschneider@chromium.org
100743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
100854ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org// Generator and strict mode poison pills
1009ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1010ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
101140cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.orgBUILTIN(StrictModePoisonPill) {
1012c03a1924dcc113678c0ebe58aa7d3c855a657719yangguo@chromium.org  HandleScope scope(isolate);
1013ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  THROW_NEW_ERROR_RETURN_FAILURE(
1014ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      isolate,
1015ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      NewTypeError("strict_poison_pill", HandleVector<Object>(NULL, 0)));
1016ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
1017ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1018e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
101954ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.orgBUILTIN(GeneratorPoisonPill) {
102054ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org  HandleScope scope(isolate);
1021ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org  THROW_NEW_ERROR_RETURN_FAILURE(
1022ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      isolate,
1023ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org      NewTypeError("generator_poison_pill", HandleVector<Object>(NULL, 0)));
102454ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org}
102554ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org
102654ae5fb0902b9e1b89c178fa5a7ba4e1a74daa41machenbach@chromium.org
1027ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// -----------------------------------------------------------------------------
102843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen//
102943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// Searches the hidden prototype chain of the given object for the first
103249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// object that is an instance of the given type.  If no such object can
103349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// be found then Heap::null_value() is returned.
103449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.orgstatic inline Object* FindHidden(Heap* heap,
103549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                 Object* object,
103649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org                                 FunctionTemplateInfo* type) {
10379bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  for (PrototypeIterator iter(heap->isolate(), object,
10389bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                              PrototypeIterator::START_AT_RECEIVER);
10399bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org       !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
10409bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    if (type->IsTemplateFor(iter.GetCurrent())) {
10419bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org      return iter.GetCurrent();
10429bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    }
104349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  }
104449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org  return heap->null_value();
104549a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org}
104649a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
104749a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org
104843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Returns the holder JSObject if the function can legally be called
104943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with this receiver.  Returns Heap::null_value() if the call is
105043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// illegal.  Any arguments that don't fit the expected type is
105149a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// overwritten with undefined.  Note that holder and the arguments are
105249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// implicitly rewritten with the first object in the hidden prototype
105349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org// chain that actually has the expected type.
1054ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstatic inline Object* TypeCheck(Heap* heap,
1055ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                int argc,
105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                Object** argv,
105743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen                                FunctionTemplateInfo* info) {
105843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* recv = argv[0];
10591c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // API calls are only supported with JSObject receivers.
10601c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  if (!recv->IsJSObject()) return heap->null_value();
106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* sig_obj = info->signature();
106243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (sig_obj->IsUndefined()) return recv;
106343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  SignatureInfo* sig = SignatureInfo::cast(sig_obj);
106443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If necessary, check the receiver
106543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* recv_type = sig->receiver();
106643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* holder = recv;
106743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!recv_type->IsUndefined()) {
106849a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    holder = FindHidden(heap, holder, FunctionTemplateInfo::cast(recv_type));
106949a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    if (holder == heap->null_value()) return heap->null_value();
107043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
107143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* args_obj = sig->args();
107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // If there is no argument signature we're done
107343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (args_obj->IsUndefined()) return holder;
107443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  FixedArray* args = FixedArray::cast(args_obj);
107543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  int length = args->length();
107631e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  if (argc <= length) length = argc - 1;
107743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < length; i++) {
107843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* argtype = args->get(i);
107943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (argtype->IsUndefined()) continue;
108043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object** arg = &argv[-1 - i];
108143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* current = *arg;
108249a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    current = FindHidden(heap, current, FunctionTemplateInfo::cast(argtype));
108349a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    if (current == heap->null_value()) current = heap->undefined_value();
108449a44674c6935d62c3e776dfbf896b7f6f34228ammassi@chromium.org    *arg = current;
108543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
108643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return holder;
108743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
108843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
108943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1090b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgtemplate <bool is_construct>
1091a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* HandleApiCallHelper(
1092ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    BuiltinArguments<NEEDS_CALLED_FUNCTION> args, Isolate* isolate) {
1093e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(is_construct == CalledAsConstructor(isolate));
1094ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
109543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1096ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  HandleScope scope(isolate);
1097b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  Handle<JSFunction> function = args.called_function();
1098e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(function->shared()->IsApiFunction());
109943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11002ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Handle<FunctionTemplateInfo> fun_data(
11012ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org      function->shared()->get_api_func_data(), isolate);
110243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (is_construct) {
11032ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org    ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
11042ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate, fun_data,
11052ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org        isolate->factory()->ConfigureInstance(
11062ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org            fun_data, Handle<JSObject>::cast(args.receiver())));
110743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
110843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1109e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  SharedFunctionInfo* shared = function->shared();
1110486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  if (shared->strict_mode() == SLOPPY && !shared->native()) {
1111e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org    Object* recv = args[0];
1112e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!recv->IsNull());
111358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org    if (recv->IsUndefined()) args[0] = function->global_proxy();
1114e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org  }
1115e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org
11162ebef182c49d59eba907b120c3c2a50808bd1f12machenbach@chromium.org  Object* raw_holder = TypeCheck(heap, args.length(), &args[0], *fun_data);
111743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
111843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (raw_holder->IsNull()) {
111943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    // This function cannot be called with the given receiver.  Abort!
1120ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org    THROW_NEW_ERROR_RETURN_FAILURE(
1121ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        isolate,
1122ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org        NewTypeError("illegal_invocation", HandleVector(&function, 1)));
112343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
112443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
112543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* raw_call_data = fun_data->call_code();
112643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  if (!raw_call_data->IsUndefined()) {
112743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
112843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* callback_obj = call_data->callback();
1129662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org    v8::FunctionCallback callback =
1130662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org        v8::ToCData<v8::FunctionCallback>(callback_obj);
113143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* data_obj = call_data->data();
113243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    Object* result;
113343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1134ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    LOG(isolate, ApiObjectAccess("call", JSObject::cast(*args.receiver())));
1135e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(raw_holder->IsJSObject());
1136e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
1137bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    FunctionCallbackArguments custom(isolate,
1138bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     data_obj,
1139bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     *function,
1140bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     raw_holder,
1141bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     &args[0] - 1,
1142bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     args.length() - 1,
1143bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     is_construct);
114443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11451510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> value = custom.Call(callback);
114643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (value.IsEmpty()) {
1147ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      result = heap->undefined_value();
114843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
114943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      result = *reinterpret_cast<Object**>(*value);
1150de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      result->VerifyApiCallResultType();
115143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
115243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11538496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
115443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (!is_construct || result->IsJSObject()) return result;
115543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
115643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1157b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  return *args.receiver();
1158b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
1159b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1160b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1161b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgBUILTIN(HandleApiCall) {
1162ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return HandleApiCallHelper<false>(args, isolate);
1163b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org}
1164b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1165b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1166b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.orgBUILTIN(HandleApiCallConstruct) {
1167ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return HandleApiCallHelper<true>(args, isolate);
116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
116943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117105521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// Helper function to handle calls to non-function objects created through the
117205521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// API. The object can be called as either a constructor (using new) or just as
117305521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// a function (without new).
1174a77ec9c2cf67e5b9c707fe42f33574526fed189amachenbach@chromium.orgMUST_USE_RESULT static Object* HandleApiCallAsFunctionOrConstructor(
1175ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    Isolate* isolate,
1176b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    bool is_construct_call,
1177b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org    BuiltinArguments<NO_EXTRA_ARGUMENTS> args) {
117805521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  // Non-functions are never called as constructors. Even if this is an object
117905521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org  // called as a constructor the delegate call is not a construct call.
1180e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!CalledAsConstructor(isolate));
1181ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Heap* heap = isolate->heap();
118243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1183717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  Handle<Object> receiver = args.receiver();
118405521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
118543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the object called.
1186717967fd64e99e759ff094df6f069440cc866266rossberg@chromium.org  JSObject* obj = JSObject::cast(*receiver);
118743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
118843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the invocation callback from the function descriptor that was
118943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // used to create the called object.
1190e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(obj->map()->has_instance_call_handler());
119143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  JSFunction* constructor = JSFunction::cast(obj->map()->constructor());
1192e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(constructor->shared()->IsApiFunction());
119343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* handler =
1194f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org      constructor->shared()->get_api_func_data()->instance_call_handler();
1195e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!handler->IsUndefined());
119643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
119743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* callback_obj = call_data->callback();
1198662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org  v8::FunctionCallback callback =
1199662436e7b124b3535773535c671c53db322070b5verwaest@chromium.org      v8::ToCData<v8::FunctionCallback>(callback_obj);
120043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
120143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Get the data for the call and perform the callback.
120243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Object* result;
1203e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  {
1204ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    HandleScope scope(isolate);
1205ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    LOG(isolate, ApiObjectAccess("call non-function", obj));
1206e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
1207bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    FunctionCallbackArguments custom(isolate,
1208bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     call_data->data(),
1209bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     constructor,
1210bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     obj,
1211bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     &args[0] - 1,
1212bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     args.length() - 1,
1213bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                     is_construct_call);
12141510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org    v8::Handle<v8::Value> value = custom.Call(callback);
121543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (value.IsEmpty()) {
1216ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org      result = heap->undefined_value();
121743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
121843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      result = *reinterpret_cast<Object**>(*value);
1219de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org      result->VerifyApiCallResultType();
122043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
122143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
122243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Check for exceptions and return result.
12238496027a525ad457b6d5729faf41f29100a27264machenbach@chromium.org  RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
122443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return result;
122543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
122605521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
122705521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
122805521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// Handle calls to non-function objects created through the API. This delegate
122905521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// function is used when the call is a normal function call.
123005521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.orgBUILTIN(HandleApiCallAsFunction) {
1231ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return HandleApiCallAsFunctionOrConstructor(isolate, false, args);
123205521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org}
123305521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
123405521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org
123505521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// Handle calls to non-function objects created through the API. This delegate
123605521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org// function is used when the call is a construct call.
123705521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.orgBUILTIN(HandleApiCallAsConstructor) {
1238ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  return HandleApiCallAsFunctionOrConstructor(isolate, true, args);
123905521fcc4bd495d3dc2b3ae7a6bc7e52ccb7937bsgjesse@chromium.org}
124043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_LoadIC_Miss(MacroAssembler* masm) {
124343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  LoadIC::GenerateMiss(masm);
124443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
124543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
124743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_LoadIC_Normal(MacroAssembler* masm) {
124843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  LoadIC::GenerateNormal(masm);
124943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
125043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
125143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1252de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.orgstatic void Generate_LoadIC_Getter_ForDeopt(MacroAssembler* masm) {
1253eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  NamedLoadHandlerCompiler::GenerateLoadViaGetterForDeopt(masm);
1254de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org}
1255de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
1256de88679a78f9dae12fdf7955610969ac4c79b0bemstarzinger@chromium.org
1257d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.orgstatic void Generate_LoadIC_Slow(MacroAssembler* masm) {
1258d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org  LoadIC::GenerateRuntimeGetProperty(masm);
1259d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org}
1260d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
1261d4be0f0c0edfc0a0b46e745055c3dc497c0ffcb5verwaest@chromium.org
126243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedLoadIC_Initialize(MacroAssembler* masm) {
126343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  KeyedLoadIC::GenerateInitialize(masm);
126443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
126543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
126643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1267ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgstatic void Generate_KeyedLoadIC_Slow(MacroAssembler* masm) {
1268ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  KeyedLoadIC::GenerateRuntimeGetProperty(masm);
1269ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org}
1270ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
1271ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
127243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedLoadIC_Miss(MacroAssembler* masm) {
1273af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  KeyedLoadIC::GenerateMiss(masm);
127443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
127543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
127643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
127743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedLoadIC_Generic(MacroAssembler* masm) {
127843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  KeyedLoadIC::GenerateGeneric(masm);
127943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
128043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
128143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
12820c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.orgstatic void Generate_KeyedLoadIC_String(MacroAssembler* masm) {
12830c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  KeyedLoadIC::GenerateString(masm);
12840c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org}
12850c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
12860c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
128743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedLoadIC_PreMonomorphic(MacroAssembler* masm) {
128843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  KeyedLoadIC::GeneratePreMonomorphic(masm);
128943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
129043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1291e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
129243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_StoreIC_Miss(MacroAssembler* masm) {
129343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  StoreIC::GenerateMiss(masm);
129443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
129543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
129769ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.orgstatic void Generate_StoreIC_Normal(MacroAssembler* masm) {
129869ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org  StoreIC::GenerateNormal(masm);
129969ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org}
130069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
130169ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
13026474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void Generate_StoreIC_Slow(MacroAssembler* masm) {
13036474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  NamedStoreHandlerCompiler::GenerateSlow(masm);
13046474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org}
13056474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
13066474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
13076474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.orgstatic void Generate_KeyedStoreIC_Slow(MacroAssembler* masm) {
13086474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org  ElementHandlerCompiler::GenerateStoreSlow(masm);
13096474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org}
13106474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
13116474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org
131246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.orgstatic void Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) {
1313eb81c479217278e101fc47fd29872a7e68f02402machenbach@chromium.org  NamedStoreHandlerCompiler::GenerateStoreViaSetterForDeopt(masm);
131446839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org}
131546839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
131646839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
131743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedStoreIC_Generic(MacroAssembler* masm) {
1318486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  KeyedStoreIC::GenerateGeneric(masm, SLOPPY);
13199ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org}
13209ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
13219ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
13229ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgstatic void Generate_KeyedStoreIC_Generic_Strict(MacroAssembler* masm) {
1323486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  KeyedStoreIC::GenerateGeneric(masm, STRICT);
132443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
132543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
132743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedStoreIC_Miss(MacroAssembler* masm) {
1328af9cfcbed5daf6e636e189bce451c6fafdbb127dmachenbach@chromium.org  KeyedStoreIC::GenerateMiss(masm);
1329ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org}
1330ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
1331ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
133243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic void Generate_KeyedStoreIC_Initialize(MacroAssembler* masm) {
133343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  KeyedStoreIC::GenerateInitialize(masm);
133443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
133543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
133643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
13379ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.orgstatic void Generate_KeyedStoreIC_Initialize_Strict(MacroAssembler* masm) {
13389ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  KeyedStoreIC::GenerateInitialize(masm);
13399ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org}
13409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
1341e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
13423d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgstatic void Generate_KeyedStoreIC_PreMonomorphic(MacroAssembler* masm) {
13433d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  KeyedStoreIC::GeneratePreMonomorphic(masm);
13443d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org}
13453d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
13463d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
13473d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.orgstatic void Generate_KeyedStoreIC_PreMonomorphic_Strict(MacroAssembler* masm) {
13483d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  KeyedStoreIC::GeneratePreMonomorphic(masm);
13493d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org}
13503d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
13513d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org
1352486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.orgstatic void Generate_KeyedStoreIC_SloppyArguments(MacroAssembler* masm) {
1353486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  KeyedStoreIC::GenerateSloppyArguments(masm);
13547b26015ac58e54e88f4214e248f772ad4f055477whesse@chromium.org}
13559ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
1356e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1357a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.orgstatic void Generate_CallICStub_DebugBreak(MacroAssembler* masm) {
1358d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateCallICStubDebugBreak(masm);
1359a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org}
1360a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
1361a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org
13628bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
1363d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateLoadICDebugBreak(masm);
13648bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org}
13658bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13668bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13678bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_StoreIC_DebugBreak(MacroAssembler* masm) {
1368d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateStoreICDebugBreak(masm);
13698bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org}
13708bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13718bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13728bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) {
1373d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateKeyedLoadICDebugBreak(masm);
13748bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org}
13758bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13768bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13778bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) {
1378d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateKeyedStoreICDebugBreak(masm);
13798bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org}
13808bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13818bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1382f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.orgstatic void Generate_CompareNilIC_DebugBreak(MacroAssembler* masm) {
1383d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateCompareNilICDebugBreak(masm);
1384f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org}
1385f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
1386f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
13878bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.orgstatic void Generate_Return_DebugBreak(MacroAssembler* masm) {
1388d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateReturnDebugBreak(masm);
13898bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org}
13908bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
13918bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1392c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.orgstatic void Generate_CallFunctionStub_DebugBreak(MacroAssembler* masm) {
1393d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateCallFunctionStubDebugBreak(masm);
13948bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org}
1395357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
13962356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
1397fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgstatic void Generate_CallConstructStub_DebugBreak(MacroAssembler* masm) {
1398d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateCallConstructStubDebugBreak(masm);
1399fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
1400fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
1401fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
1402fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.orgstatic void Generate_CallConstructStub_Recording_DebugBreak(
1403fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org    MacroAssembler* masm) {
1404d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateCallConstructStubRecordDebugBreak(masm);
1405fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
1406fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
1407fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
14082356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.orgstatic void Generate_Slot_DebugBreak(MacroAssembler* masm) {
1409d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateSlotDebugBreak(masm);
14102356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org}
14112356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
14122356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
1413357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.orgstatic void Generate_PlainReturn_LiveEdit(MacroAssembler* masm) {
1414d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GeneratePlainReturnLiveEdit(masm);
1415357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
1416357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
14172356e6fbe66ac3aa027b61cb43a3c3619b3c3a5evegorov@chromium.org
1418357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.orgstatic void Generate_FrameDropper_LiveEdit(MacroAssembler* masm) {
1419d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  DebugCodegen::GenerateFrameDropperLiveEdit(masm);
1420357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
14218bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org
1422ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1423ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgBuiltins::Builtins() : initialized_(false) {
1424ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  memset(builtins_, 0, sizeof(builtins_[0]) * builtin_count);
1425ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  memset(names_, 0, sizeof(names_[0]) * builtin_count);
1426ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
1427ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1428ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1429ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgBuiltins::~Builtins() {
1430ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
1431ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
143243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1433b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org#define DEF_ENUM_C(name, ignore) FUNCTION_ADDR(Builtin_##name),
1434ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgAddress const Builtins::c_functions_[cfunction_count] = {
1435ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  BUILTIN_LIST_C(DEF_ENUM_C)
1436ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org};
143743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_ENUM_C
143843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
143943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DEF_JS_NAME(name, ignore) #name,
144043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define DEF_JS_ARGC(ignore, argc) argc,
1441ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgconst char* const Builtins::javascript_names_[id_count] = {
144243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  BUILTINS_LIST_JS(DEF_JS_NAME)
144343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
144443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1445ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgint const Builtins::javascript_argc_[id_count] = {
144643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  BUILTINS_LIST_JS(DEF_JS_ARGC)
144743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
144843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_JS_NAME
144943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_JS_ARGC
145043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1451ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgstruct BuiltinDesc {
1452ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  byte* generator;
1453ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  byte* c_code;
1454ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  const char* s_name;  // name is only used for generating log information.
1455ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  int name;
1456ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Code::Flags flags;
1457ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  BuiltinExtraArguments extra_args;
1458ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org};
145943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14601456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org#define BUILTIN_FUNCTION_TABLE_INIT { V8_ONCE_INIT, {} }
14611456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org
1462ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgclass BuiltinFunctionTable {
1463ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org public:
14641456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  BuiltinDesc* functions() {
14651e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org    base::CallOnce(&once_, &Builtins::InitBuiltinFunctionTable);
14661456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    return functions_;
1467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  }
1468ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
14691e2d50cf3d94ff48285da107b7a9da1ad0fc873dmachenbach@chromium.org  base::OnceType once_;
14701456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  BuiltinDesc functions_[Builtins::builtin_count + 1];
147143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1472ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  friend class Builtins;
1473ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org};
1474ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
14751456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.orgstatic BuiltinFunctionTable builtin_function_table =
14761456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org    BUILTIN_FUNCTION_TABLE_INIT;
1477ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1478ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// Define array of pointers to generators and C builtin functions.
1479ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// We do this in a sort of roundabout way so that we can do the initialization
1480ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// within the lexical scope of Builtins:: and within a context where
1481ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org// Code::Flags names a non-abstract type.
1482ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgvoid Builtins::InitBuiltinFunctionTable() {
14831456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  BuiltinDesc* functions = builtin_function_table.functions_;
1484ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  functions[builtin_count].generator = NULL;
1485ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  functions[builtin_count].c_code = NULL;
1486ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  functions[builtin_count].s_name = NULL;
1487ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  functions[builtin_count].name = builtin_count;
1488ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  functions[builtin_count].flags = static_cast<Code::Flags>(0);
1489ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS;
1490ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1491ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#define DEF_FUNCTION_PTR_C(aname, aextra_args)                         \
1492ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->generator = FUNCTION_ADDR(Generate_Adaptor);            \
1493ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->c_code = FUNCTION_ADDR(Builtin_##aname);                \
1494ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->s_name = #aname;                                        \
1495ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->name = c_##aname;                                       \
1496ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->flags = Code::ComputeFlags(Code::BUILTIN);              \
1497ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->extra_args = aextra_args;                               \
1498ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ++functions;
1499ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1500ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org#define DEF_FUNCTION_PTR_A(aname, kind, state, extra)                       \
1501ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->generator = FUNCTION_ADDR(Generate_##aname);                 \
1502ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->c_code = NULL;                                               \
1503ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->s_name = #aname;                                             \
15047979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org    functions->name = k##aname;                                             \
1505ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->flags = Code::ComputeFlags(Code::kind,                       \
1506ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                          state,                            \
1507ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                          extra);                           \
1508ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    functions->extra_args = NO_EXTRA_ARGUMENTS;                             \
1509ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org    ++functions;
1510ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1511c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org#define DEF_FUNCTION_PTR_H(aname, kind)                                     \
151232aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    functions->generator = FUNCTION_ADDR(Generate_##aname);                 \
151332aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    functions->c_code = NULL;                                               \
151432aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    functions->s_name = #aname;                                             \
151532aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    functions->name = k##aname;                                             \
1516f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    functions->flags = Code::ComputeHandlerFlags(Code::kind);               \
151732aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    functions->extra_args = NO_EXTRA_ARGUMENTS;                             \
151832aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org    ++functions;
151932aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org
1520ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  BUILTIN_LIST_C(DEF_FUNCTION_PTR_C)
1521ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  BUILTIN_LIST_A(DEF_FUNCTION_PTR_A)
152232aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org  BUILTIN_LIST_H(DEF_FUNCTION_PTR_H)
1523ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  BUILTIN_LIST_DEBUG_A(DEF_FUNCTION_PTR_A)
152443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
152543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_FUNCTION_PTR_C
152643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#undef DEF_FUNCTION_PTR_A
1527ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org}
1528ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1529e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org
1530e900018c7a2a695fde788911564da37535c7e736mstarzinger@chromium.orgvoid Builtins::SetUp(Isolate* isolate, bool create_heap_objects) {
1531e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(!initialized_);
1532ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
1533ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Create a scope for the handles in the builtins.
1534c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  HandleScope scope(isolate);
1535ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
15361456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  const BuiltinDesc* functions = builtin_function_table.functions();
153743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
153843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // For now we generate builtin adaptor code into a stack-allocated
1539c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // buffer, before copying it into individual code objects. Be careful
1540c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // with alignment, some platforms don't like unaligned code.
15413c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org#ifdef DEBUG
15423c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  // We can generate a lot of debug code on Arm64.
15433c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  const size_t buffer_size = 32*KB;
15443c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org#else
15453c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  const size_t buffer_size = 8*KB;
15463c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org#endif
15473c3c8d733702cb2b41471efa5eead1faf5b5711bmachenbach@chromium.org  union { int force_alignment; byte buffer[buffer_size]; } u;
154843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
154943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Traverse the list of builtins and generate an adaptor in a
155043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // separate code object for each one.
155143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  for (int i = 0; i < builtin_count; i++) {
155243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    if (create_heap_objects) {
1553c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      MacroAssembler masm(isolate, u.buffer, sizeof u.buffer);
155443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Generate the code/adaptor.
1555b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments);
155643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Generator g = FUNCTION_CAST<Generator>(functions[i].generator);
155743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // We pass all arguments to the generator, but it may not use all of
155843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // them.  This works because the first arguments are on top of the
155943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // stack.
1560e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK(!masm.has_frame());
1561b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org      g(&masm, functions[i].name, functions[i].extra_args);
156243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Move the code into the object heap.
156343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      CodeDesc desc;
156443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      masm.GetCode(&desc);
156543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Code::Flags flags =  functions[i].flags;
15669fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      Handle<Code> code =
15679fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org          isolate->factory()->NewCode(desc, flags, masm.CodeObject());
156843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Log the event and add the code to the builtins array.
1569c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org      PROFILE(isolate,
15709fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org              CodeCreateEvent(Logger::BUILTIN_TAG, *code, functions[i].s_name));
15719fa619507474a4c1c21c6935b3209070bc13a218machenbach@chromium.org      builtins_[i] = *code;
15724c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org      if (code->kind() == Code::BUILTIN) code->set_builtin_index(i);
15737be3c996bea370e151c9fe4ecf7f779cdc5f87adkasperl@chromium.org#ifdef ENABLE_DISASSEMBLER
157431e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager      if (FLAG_print_builtin_code) {
1575e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org        CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
1576f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        OFStream os(trace_scope.file());
1577f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "Builtin: " << functions[i].s_name << "\n";
1578f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        code->Disassemble(functions[i].s_name, os);
1579f15d0cdbef11a212e108432465f014a7d3c3aa12machenbach@chromium.org        os << "\n";
158031e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager      }
158131e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager#endif
158243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    } else {
158343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      // Deserializing. The values will be filled in during IterateBuiltins.
158443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      builtins_[i] = NULL;
158543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
158643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    names_[i] = functions[i].s_name;
158743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
158843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
158943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Mark as initialized.
1590ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  initialized_ = true;
159143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
159243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
159343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
159443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Builtins::TearDown() {
1595ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  initialized_ = false;
159643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
159743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Builtins::IterateBuiltins(ObjectVisitor* v) {
160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  v->VisitPointers(&builtins_[0], &builtins_[0] + builtin_count);
160143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
160243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
160343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
160443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenconst char* Builtins::Lookup(byte* pc) {
1605ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // may be called during initialization (disassembler!)
1606ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  if (initialized_) {
160743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    for (int i = 0; i < builtin_count; i++) {
160843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      Code* entry = Code::cast(builtins_[i]);
160943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      if (entry->contains(pc)) {
161043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen        return names_[i];
161143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen      }
161243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen    }
161343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  }
161443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  return NULL;
161543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}
161643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1617a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1618dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid Builtins::Generate_InterruptCheck(MacroAssembler* masm) {
161947390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  masm->TailCallRuntime(Runtime::kInterrupt, 0, 1);
1620dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org}
1621dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
1622dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
1623dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.orgvoid Builtins::Generate_StackCheck(MacroAssembler* masm) {
162447390597afd6b17870f41dfb5dd8c057aea1f068machenbach@chromium.org  masm->TailCallRuntime(Runtime::kStackGuard, 0, 1);
1625dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org}
1626dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
1627dc94e19484d1700cb0ec22365444223e49a3ac1ejkummerow@chromium.org
16287979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#define DEFINE_BUILTIN_ACCESSOR_C(name, ignore)               \
16297979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgHandle<Code> Builtins::name() {                               \
16307979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  Code** code_address =                                       \
16317979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      reinterpret_cast<Code**>(builtin_address(k##name));     \
16327979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  return Handle<Code>(code_address);                          \
16337979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org}
16347979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
16357979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgHandle<Code> Builtins::name() {                             \
16367979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  Code** code_address =                                     \
16377979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org      reinterpret_cast<Code**>(builtin_address(k##name));   \
16387979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org  return Handle<Code>(code_address);                        \
16397979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org}
1640c86e8c29eea534916f0d6a2a285b65a86d1b3b67machenbach@chromium.org#define DEFINE_BUILTIN_ACCESSOR_H(name, kind)               \
164132aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.orgHandle<Code> Builtins::name() {                             \
164232aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org  Code** code_address =                                     \
164332aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org      reinterpret_cast<Code**>(builtin_address(k##name));   \
164432aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org  return Handle<Code>(code_address);                        \
164532aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.org}
16467979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgBUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
16477979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgBUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
164832aa03c4b5fe6e129df7529ecdaaeefce3ecee29jkummerow@chromium.orgBUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
16497979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.orgBUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
16507979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#undef DEFINE_BUILTIN_ACCESSOR_C
16517979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org#undef DEFINE_BUILTIN_ACCESSOR_A
16527979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
16537979bbb1df2eaff193e85d44c8da1ffa1525b7fcfschneider@chromium.org
165443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
1655