diff --git a/src/builtins/builtins-internal.cc b/src/builtins/builtins-internal.cc
index bec6ff3..b1c737b 100644
--- a/src/builtins/builtins-internal.cc
+++ b/src/builtins/builtins-internal.cc
@@ -2,10 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "src/builtins/builtins.h"
 #include "src/builtins/builtins-utils.h"
+#include "src/builtins/builtins.h"
+#include "src/code-stub-assembler.h"
+#include "src/counters.h"
 #include "src/interface-descriptors.h"
 #include "src/macro-assembler.h"
+#include "src/objects-inl.h"
 
 namespace v8 {
 namespace internal {
@@ -54,86 +57,260 @@
 // TurboFan support builtins.
 
 void Builtins::Generate_CopyFastSmiOrObjectElements(
-    CodeStubAssembler* assembler) {
+    compiler::CodeAssemblerState* state) {
   typedef CodeStubAssembler::Label Label;
   typedef compiler::Node Node;
   typedef CopyFastSmiOrObjectElementsDescriptor Descriptor;
+  CodeStubAssembler assembler(state);
 
-  Node* object = assembler->Parameter(Descriptor::kObject);
+  Node* object = assembler.Parameter(Descriptor::kObject);
 
   // Load the {object}s elements.
-  Node* source = assembler->LoadObjectField(object, JSObject::kElementsOffset);
+  Node* source = assembler.LoadObjectField(object, JSObject::kElementsOffset);
 
-  CodeStubAssembler::ParameterMode mode = assembler->OptimalParameterMode();
-  Node* length = assembler->UntagParameter(
-      assembler->LoadFixedArrayBaseLength(source), mode);
+  CodeStubAssembler::ParameterMode mode = assembler.OptimalParameterMode();
+  Node* length = assembler.TaggedToParameter(
+      assembler.LoadFixedArrayBaseLength(source), mode);
 
   // Check if we can allocate in new space.
   ElementsKind kind = FAST_ELEMENTS;
   int max_elements = FixedArrayBase::GetMaxLengthForNewSpaceAllocation(kind);
-  Label if_newspace(assembler), if_oldspace(assembler);
-  assembler->Branch(
-      assembler->UintPtrLessThan(
-          length, assembler->IntPtrOrSmiConstant(max_elements, mode)),
+  Label if_newspace(&assembler), if_oldspace(&assembler);
+  assembler.Branch(
+      assembler.UintPtrOrSmiLessThan(
+          length, assembler.IntPtrOrSmiConstant(max_elements, mode), mode),
       &if_newspace, &if_oldspace);
 
+  assembler.Bind(&if_newspace);
+  {
+    Node* target = assembler.AllocateFixedArray(kind, length, mode);
+    assembler.CopyFixedArrayElements(kind, source, target, length,
+                                     SKIP_WRITE_BARRIER, mode);
+    assembler.StoreObjectField(object, JSObject::kElementsOffset, target);
+    assembler.Return(target);
+  }
+
+  assembler.Bind(&if_oldspace);
+  {
+    Node* target = assembler.AllocateFixedArray(kind, length, mode,
+                                                CodeStubAssembler::kPretenured);
+    assembler.CopyFixedArrayElements(kind, source, target, length,
+                                     UPDATE_WRITE_BARRIER, mode);
+    assembler.StoreObjectField(object, JSObject::kElementsOffset, target);
+    assembler.Return(target);
+  }
+}
+
+void Builtins::Generate_GrowFastDoubleElements(
+    compiler::CodeAssemblerState* state) {
+  typedef CodeStubAssembler::Label Label;
+  typedef compiler::Node Node;
+  typedef GrowArrayElementsDescriptor Descriptor;
+  CodeStubAssembler assembler(state);
+
+  Node* object = assembler.Parameter(Descriptor::kObject);
+  Node* key = assembler.Parameter(Descriptor::kKey);
+  Node* context = assembler.Parameter(Descriptor::kContext);
+
+  Label runtime(&assembler, CodeStubAssembler::Label::kDeferred);
+  Node* elements = assembler.LoadElements(object);
+  elements = assembler.TryGrowElementsCapacity(
+      object, elements, FAST_DOUBLE_ELEMENTS, key, &runtime);
+  assembler.Return(elements);
+
+  assembler.Bind(&runtime);
+  assembler.TailCallRuntime(Runtime::kGrowArrayElements, context, object, key);
+}
+
+void Builtins::Generate_GrowFastSmiOrObjectElements(
+    compiler::CodeAssemblerState* state) {
+  typedef CodeStubAssembler::Label Label;
+  typedef compiler::Node Node;
+  typedef GrowArrayElementsDescriptor Descriptor;
+  CodeStubAssembler assembler(state);
+
+  Node* object = assembler.Parameter(Descriptor::kObject);
+  Node* key = assembler.Parameter(Descriptor::kKey);
+  Node* context = assembler.Parameter(Descriptor::kContext);
+
+  Label runtime(&assembler, CodeStubAssembler::Label::kDeferred);
+  Node* elements = assembler.LoadElements(object);
+  elements = assembler.TryGrowElementsCapacity(object, elements, FAST_ELEMENTS,
+                                               key, &runtime);
+  assembler.Return(elements);
+
+  assembler.Bind(&runtime);
+  assembler.TailCallRuntime(Runtime::kGrowArrayElements, context, object, key);
+}
+
+namespace {
+
+void Generate_NewArgumentsElements(CodeStubAssembler* assembler,
+                                   compiler::Node* frame,
+                                   compiler::Node* length) {
+  typedef CodeStubAssembler::Label Label;
+  typedef CodeStubAssembler::Variable Variable;
+  typedef compiler::Node Node;
+
+  // Check if we can allocate in new space.
+  ElementsKind kind = FAST_ELEMENTS;
+  int max_elements = FixedArray::GetMaxLengthForNewSpaceAllocation(kind);
+  Label if_newspace(assembler), if_oldspace(assembler, Label::kDeferred);
+  assembler->Branch(assembler->IntPtrLessThan(
+                        length, assembler->IntPtrConstant(max_elements)),
+                    &if_newspace, &if_oldspace);
+
   assembler->Bind(&if_newspace);
   {
-    Node* target = assembler->AllocateFixedArray(kind, length, mode);
-    assembler->CopyFixedArrayElements(kind, source, target, length,
-                                      SKIP_WRITE_BARRIER, mode);
-    assembler->StoreObjectField(object, JSObject::kElementsOffset, target);
-    assembler->Return(target);
+    // Prefer EmptyFixedArray in case of non-positive {length} (the {length}
+    // can be negative here for rest parameters).
+    Label if_empty(assembler), if_notempty(assembler);
+    assembler->Branch(
+        assembler->IntPtrLessThanOrEqual(length, assembler->IntPtrConstant(0)),
+        &if_empty, &if_notempty);
+
+    assembler->Bind(&if_empty);
+    assembler->Return(assembler->EmptyFixedArrayConstant());
+
+    assembler->Bind(&if_notempty);
+    {
+      // Allocate a FixedArray in new space.
+      Node* result = assembler->AllocateFixedArray(kind, length);
+
+      // Compute the effective {offset} into the {frame}.
+      Node* offset = assembler->IntPtrAdd(length, assembler->IntPtrConstant(1));
+
+      // Copy the parameters from {frame} (starting at {offset}) to {result}.
+      Variable var_index(assembler, MachineType::PointerRepresentation());
+      Label loop(assembler, &var_index), done_loop(assembler);
+      var_index.Bind(assembler->IntPtrConstant(0));
+      assembler->Goto(&loop);
+      assembler->Bind(&loop);
+      {
+        // Load the current {index}.
+        Node* index = var_index.value();
+
+        // Check if we are done.
+        assembler->GotoIf(assembler->WordEqual(index, length), &done_loop);
+
+        // Load the parameter at the given {index}.
+        Node* value = assembler->Load(
+            MachineType::AnyTagged(), frame,
+            assembler->WordShl(assembler->IntPtrSub(offset, index),
+                               assembler->IntPtrConstant(kPointerSizeLog2)));
+
+        // Store the {value} into the {result}.
+        assembler->StoreFixedArrayElement(result, index, value,
+                                          SKIP_WRITE_BARRIER);
+
+        // Continue with next {index}.
+        var_index.Bind(
+            assembler->IntPtrAdd(index, assembler->IntPtrConstant(1)));
+        assembler->Goto(&loop);
+      }
+
+      assembler->Bind(&done_loop);
+      assembler->Return(result);
+    }
   }
 
   assembler->Bind(&if_oldspace);
   {
-    Node* target = assembler->AllocateFixedArray(
-        kind, length, mode, CodeStubAssembler::kPretenured);
-    assembler->CopyFixedArrayElements(kind, source, target, length,
-                                      UPDATE_WRITE_BARRIER, mode);
-    assembler->StoreObjectField(object, JSObject::kElementsOffset, target);
-    assembler->Return(target);
+    // Allocate in old space (or large object space).
+    assembler->TailCallRuntime(
+        Runtime::kNewArgumentsElements, assembler->NoContextConstant(),
+        assembler->BitcastWordToTagged(frame), assembler->SmiFromWord(length));
   }
 }
 
-void Builtins::Generate_GrowFastDoubleElements(CodeStubAssembler* assembler) {
+}  // namespace
+
+void Builtins::Generate_NewUnmappedArgumentsElements(
+    compiler::CodeAssemblerState* state) {
   typedef CodeStubAssembler::Label Label;
+  typedef CodeStubAssembler::Variable Variable;
   typedef compiler::Node Node;
-  typedef GrowArrayElementsDescriptor Descriptor;
+  typedef NewArgumentsElementsDescriptor Descriptor;
+  CodeStubAssembler assembler(state);
 
-  Node* object = assembler->Parameter(Descriptor::kObject);
-  Node* key = assembler->Parameter(Descriptor::kKey);
-  Node* context = assembler->Parameter(Descriptor::kContext);
+  Node* formal_parameter_count =
+      assembler.Parameter(Descriptor::kFormalParameterCount);
 
-  Label runtime(assembler, CodeStubAssembler::Label::kDeferred);
-  Node* elements = assembler->LoadElements(object);
-  elements = assembler->TryGrowElementsCapacity(
-      object, elements, FAST_DOUBLE_ELEMENTS, key, &runtime);
-  assembler->Return(elements);
+  // Determine the frame that holds the parameters.
+  Label done(&assembler);
+  Variable var_frame(&assembler, MachineType::PointerRepresentation()),
+      var_length(&assembler, MachineType::PointerRepresentation());
+  var_frame.Bind(assembler.LoadParentFramePointer());
+  var_length.Bind(formal_parameter_count);
+  Node* parent_frame = assembler.Load(
+      MachineType::Pointer(), var_frame.value(),
+      assembler.IntPtrConstant(StandardFrameConstants::kCallerFPOffset));
+  Node* parent_frame_type =
+      assembler.Load(MachineType::AnyTagged(), parent_frame,
+                     assembler.IntPtrConstant(
+                         CommonFrameConstants::kContextOrFrameTypeOffset));
+  assembler.GotoIfNot(assembler.MarkerIsFrameType(
+                          parent_frame_type, StackFrame::ARGUMENTS_ADAPTOR),
+                      &done);
+  {
+    // Determine the length from the ArgumentsAdaptorFrame.
+    Node* length = assembler.LoadAndUntagSmi(
+        parent_frame, ArgumentsAdaptorFrameConstants::kLengthOffset);
 
-  assembler->Bind(&runtime);
-  assembler->TailCallRuntime(Runtime::kGrowArrayElements, context, object, key);
+    // Take the arguments from the ArgumentsAdaptorFrame.
+    var_frame.Bind(parent_frame);
+    var_length.Bind(length);
+  }
+  assembler.Goto(&done);
+
+  // Allocate the actual FixedArray for the elements.
+  assembler.Bind(&done);
+  Generate_NewArgumentsElements(&assembler, var_frame.value(),
+                                var_length.value());
 }
 
-void Builtins::Generate_GrowFastSmiOrObjectElements(
-    CodeStubAssembler* assembler) {
+void Builtins::Generate_NewRestParameterElements(
+    compiler::CodeAssemblerState* state) {
   typedef CodeStubAssembler::Label Label;
   typedef compiler::Node Node;
-  typedef GrowArrayElementsDescriptor Descriptor;
+  typedef NewArgumentsElementsDescriptor Descriptor;
+  CodeStubAssembler assembler(state);
 
-  Node* object = assembler->Parameter(Descriptor::kObject);
-  Node* key = assembler->Parameter(Descriptor::kKey);
-  Node* context = assembler->Parameter(Descriptor::kContext);
+  Node* formal_parameter_count =
+      assembler.Parameter(Descriptor::kFormalParameterCount);
 
-  Label runtime(assembler, CodeStubAssembler::Label::kDeferred);
-  Node* elements = assembler->LoadElements(object);
-  elements = assembler->TryGrowElementsCapacity(object, elements, FAST_ELEMENTS,
-                                                key, &runtime);
-  assembler->Return(elements);
+  // Check if we have an ArgumentsAdaptorFrame, as we will only have rest
+  // parameters in that case.
+  Label if_empty(&assembler);
+  Node* frame = assembler.Load(
+      MachineType::Pointer(), assembler.LoadParentFramePointer(),
+      assembler.IntPtrConstant(StandardFrameConstants::kCallerFPOffset));
+  Node* frame_type =
+      assembler.Load(MachineType::AnyTagged(), frame,
+                     assembler.IntPtrConstant(
+                         CommonFrameConstants::kContextOrFrameTypeOffset));
+  assembler.GotoIfNot(
+      assembler.MarkerIsFrameType(frame_type, StackFrame::ARGUMENTS_ADAPTOR),
+      &if_empty);
 
-  assembler->Bind(&runtime);
-  assembler->TailCallRuntime(Runtime::kGrowArrayElements, context, object, key);
+  // Determine the length from the ArgumentsAdaptorFrame.
+  Node* frame_length = assembler.LoadAndUntagSmi(
+      frame, ArgumentsAdaptorFrameConstants::kLengthOffset);
+
+  // Compute the actual rest parameter length (may be negative).
+  Node* length = assembler.IntPtrSub(frame_length, formal_parameter_count);
+
+  // Allocate the actual FixedArray for the elements.
+  Generate_NewArgumentsElements(&assembler, frame, length);
+
+  // No rest parameters, return an empty FixedArray.
+  assembler.Bind(&if_empty);
+  assembler.Return(assembler.EmptyFixedArrayConstant());
+}
+
+void Builtins::Generate_ReturnReceiver(compiler::CodeAssemblerState* state) {
+  CodeStubAssembler assembler(state);
+  assembler.Return(assembler.Parameter(0));
 }
 
 }  // namespace internal
