From 7ff35bd54269132ddb49825806934465195b79b0 Mon Sep 17 00:00:00 2001
From: Junliang Yan <jyan@ca.ibm.com>
Date: Tue, 8 May 2018 17:12:18 -0400
Subject: [PATCH] PPC/s390: [builtins] Convert CEntry/GetProperty/StringAdd
 stubs to builtins

Port d8131cd63a8b037998a7bad6344e9cc308b315b3

Original Commit Message:

    Stubs and builtins are very similar. The main differences are that
    stubs can be parameterized and may be generated at runtime, whereas
    builtins are generated at mksnapshot-time and shipped with the snapshot
    (or embedded into the binary).

    My main motivation for these conversions is that we can generate
    faster calls and jumps to (embedded) builtins callees from (embedded)
    builtin callers. Instead of going through the builtins constants table
    indirection, we can simply do a pc-relative call/jump.

    This also unlocks other refactorings, e.g. removal of
    CallRuntimeDelayed.

R=jgruber@chromium.org, joransiu@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N

Change-Id: I193e4275470d492912a7d0f8523c3b8c29f1b146
Reviewed-on: https://chromium-review.googlesource.com/1050732
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Reviewed-by: Joran Siu <joransiu@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#53081}
---
 src/builtins/ppc/builtins-ppc.cc       | 205 +++++++++++++++++++++++-
 src/builtins/s390/builtins-s390.cc     | 192 ++++++++++++++++++++++-
 src/ppc/code-stubs-ppc.cc              | 206 -------------------------
 src/ppc/interface-descriptors-ppc.cc   |   6 -
 src/ppc/macro-assembler-ppc.cc         |  26 ++--
 src/s390/code-stubs-s390.cc            | 193 -----------------------
 src/s390/interface-descriptors-s390.cc |   6 -
 src/s390/macro-assembler-s390.cc       |  36 +++--
 8 files changed, 419 insertions(+), 451 deletions(-)

diff --git a/src/builtins/ppc/builtins-ppc.cc b/src/builtins/ppc/builtins-ppc.cc
index 124e9a57fa0..100794c6780 100644
--- a/src/builtins/ppc/builtins-ppc.cc
+++ b/src/builtins/ppc/builtins-ppc.cc
@@ -5,6 +5,7 @@
 #if V8_TARGET_ARCH_PPC
 
 #include "src/assembler-inl.h"
+#include "src/code-factory.h"
 #include "src/code-stubs.h"
 #include "src/debug/debug.h"
 #include "src/deoptimizer.h"
@@ -52,7 +53,7 @@ void AdaptorWithExitFrameType(MacroAssembler* masm,
   // ordinary functions).
   __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset));
 
-  // CEntryStub expects r3 to contain the number of arguments including the
+  // CEntry expects r3 to contain the number of arguments including the
   // receiver and the extra arguments.
   __ addi(r3, r3,
           Operand(BuiltinExitFrameConstants::kNumExtraArgsWithReceiver));
@@ -67,9 +68,10 @@ void AdaptorWithExitFrameType(MacroAssembler* masm,
   // JumpToExternalReference. We have already loaded entry point to r15
   // in Generate_adaptor.
   __ mr(r4, r15);
-  CEntryStub stub(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
-                  exit_frame_type == Builtins::BUILTIN_EXIT);
-  __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+  Handle<Code> code =
+      CodeFactory::CEntry(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
+                          exit_frame_type == Builtins::BUILTIN_EXIT);
+  __ Jump(code, RelocInfo::CODE_TARGET);
 }
 }  // namespace
 
@@ -2664,7 +2666,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
 
     // Pass the WASM instance as an explicit argument to WasmCompileLazy.
     __ Push(kWasmInstanceRegister);
-    // Initialize the JavaScript context with 0. CEntryStub will use it to
+    // Initialize the JavaScript context with 0. CEntry will use it to
     // set the current context on the isolate.
     __ LoadSmiLiteral(cp, Smi::kZero);
     __ CallRuntime(Runtime::kWasmCompileLazy);
@@ -2681,6 +2683,199 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
   __ Jump(r11);
 }
 
+void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
+                               SaveFPRegsMode save_doubles, ArgvMode argv_mode,
+                               bool builtin_exit_frame) {
+  // Called from JavaScript; parameters are on stack as if calling JS function.
+  // r3: number of arguments including receiver
+  // r4: pointer to builtin function
+  // fp: frame pointer  (restored after C call)
+  // sp: stack pointer  (restored as callee's sp after C call)
+  // cp: current context  (C callee-saved)
+  //
+  // If argv_mode == kArgvInRegister:
+  // r5: pointer to the first argument
+  ProfileEntryHookStub::MaybeCallEntryHook(masm);
+
+  __ mr(r15, r4);
+
+  if (argv_mode == kArgvInRegister) {
+    // Move argv into the correct register.
+    __ mr(r4, r5);
+  } else {
+    // Compute the argv pointer.
+    __ ShiftLeftImm(r4, r3, Operand(kPointerSizeLog2));
+    __ add(r4, r4, sp);
+    __ subi(r4, r4, Operand(kPointerSize));
+  }
+
+  // Enter the exit frame that transitions from JavaScript to C++.
+  FrameScope scope(masm, StackFrame::MANUAL);
+
+  // Need at least one extra slot for return address location.
+  int arg_stack_space = 1;
+
+  // Pass buffer for return value on stack if necessary
+  bool needs_return_buffer =
+      (result_size == 2 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS);
+  if (needs_return_buffer) {
+    arg_stack_space += result_size;
+  }
+
+  __ EnterExitFrame(
+      save_doubles, arg_stack_space,
+      builtin_exit_frame ? StackFrame::BUILTIN_EXIT : StackFrame::EXIT);
+
+  // Store a copy of argc in callee-saved registers for later.
+  __ mr(r14, r3);
+
+  // r3, r14: number of arguments including receiver  (C callee-saved)
+  // r4: pointer to the first argument
+  // r15: pointer to builtin function  (C callee-saved)
+
+  // Result returned in registers or stack, depending on result size and ABI.
+
+  Register isolate_reg = r5;
+  if (needs_return_buffer) {
+    // The return value is a non-scalar value.
+    // Use frame storage reserved by calling function to pass return
+    // buffer as implicit first argument.
+    __ mr(r5, r4);
+    __ mr(r4, r3);
+    __ addi(r3, sp, Operand((kStackFrameExtraParamSlot + 1) * kPointerSize));
+    isolate_reg = r6;
+  }
+
+  // Call C built-in.
+  __ Move(isolate_reg, ExternalReference::isolate_address(masm->isolate()));
+
+  Register target = r15;
+  if (ABI_USES_FUNCTION_DESCRIPTORS) {
+    // AIX/PPC64BE Linux use a function descriptor.
+    __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(r15, kPointerSize));
+    __ LoadP(ip, MemOperand(r15, 0));  // Instruction address
+    target = ip;
+  } else if (ABI_CALL_VIA_IP) {
+    __ Move(ip, r15);
+    target = ip;
+  }
+
+  // To let the GC traverse the return address of the exit frames, we need to
+  // know where the return address is. The CEntryStub is unmovable, so
+  // we can store the address on the stack to be able to find it again and
+  // we never have to restore it, because it will not change.
+  Label start_call;
+  constexpr int after_call_offset = 5 * Assembler::kInstrSize;
+  DCHECK_NE(r7, target);
+  __ LoadPC(r7);
+  __ bind(&start_call);
+  __ addi(r7, r7, Operand(after_call_offset));
+  __ StoreP(r7, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize));
+  __ Call(target);
+  DCHECK_EQ(after_call_offset - Assembler::kInstrSize,
+            __ SizeOfCodeGeneratedSince(&start_call));
+
+  // If return value is on the stack, pop it to registers.
+  if (needs_return_buffer) {
+    __ LoadP(r4, MemOperand(r3, kPointerSize));
+    __ LoadP(r3, MemOperand(r3));
+  }
+
+  // Check result for exception sentinel.
+  Label exception_returned;
+  __ CompareRoot(r3, Heap::kExceptionRootIndex);
+  __ beq(&exception_returned);
+
+  // Check that there is no pending exception, otherwise we
+  // should have returned the exception sentinel.
+  if (FLAG_debug_code) {
+    Label okay;
+    ExternalReference pending_exception_address = ExternalReference::Create(
+        IsolateAddressId::kPendingExceptionAddress, masm->isolate());
+
+    __ Move(r6, pending_exception_address);
+    __ LoadP(r6, MemOperand(r6));
+    __ CompareRoot(r6, Heap::kTheHoleValueRootIndex);
+    // Cannot use check here as it attempts to generate call into runtime.
+    __ beq(&okay);
+    __ stop("Unexpected pending exception");
+    __ bind(&okay);
+  }
+
+  // Exit C frame and return.
+  // r3:r4: result
+  // sp: stack pointer
+  // fp: frame pointer
+  Register argc = argv_mode == kArgvInRegister
+                      // We don't want to pop arguments so set argc to no_reg.
+                      ? no_reg
+                      // r14: still holds argc (callee-saved).
+                      : r14;
+  __ LeaveExitFrame(save_doubles, argc);
+  __ blr();
+
+  // Handling of exception.
+  __ bind(&exception_returned);
+
+  ExternalReference pending_handler_context_address = ExternalReference::Create(
+      IsolateAddressId::kPendingHandlerContextAddress, masm->isolate());
+  ExternalReference pending_handler_entrypoint_address =
+      ExternalReference::Create(
+          IsolateAddressId::kPendingHandlerEntrypointAddress, masm->isolate());
+  ExternalReference pending_handler_constant_pool_address =
+      ExternalReference::Create(
+          IsolateAddressId::kPendingHandlerConstantPoolAddress,
+          masm->isolate());
+  ExternalReference pending_handler_fp_address = ExternalReference::Create(
+      IsolateAddressId::kPendingHandlerFPAddress, masm->isolate());
+  ExternalReference pending_handler_sp_address = ExternalReference::Create(
+      IsolateAddressId::kPendingHandlerSPAddress, masm->isolate());
+
+  // Ask the runtime for help to determine the handler. This will set r3 to
+  // contain the current pending exception, don't clobber it.
+  ExternalReference find_handler =
+      ExternalReference::Create(Runtime::kUnwindAndFindExceptionHandler);
+  {
+    FrameScope scope(masm, StackFrame::MANUAL);
+    __ PrepareCallCFunction(3, 0, r3);
+    __ li(r3, Operand::Zero());
+    __ li(r4, Operand::Zero());
+    __ Move(r5, ExternalReference::isolate_address(masm->isolate()));
+    __ CallCFunction(find_handler, 3);
+  }
+
+  // Retrieve the handler context, SP and FP.
+  __ Move(cp, pending_handler_context_address);
+  __ LoadP(cp, MemOperand(cp));
+  __ Move(sp, pending_handler_sp_address);
+  __ LoadP(sp, MemOperand(sp));
+  __ Move(fp, pending_handler_fp_address);
+  __ LoadP(fp, MemOperand(fp));
+
+  // If the handler is a JS frame, restore the context to the frame. Note that
+  // the context will be set to (cp == 0) for non-JS frames.
+  Label skip;
+  __ cmpi(cp, Operand::Zero());
+  __ beq(&skip);
+  __ StoreP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  __ bind(&skip);
+
+  // Reset the masking register.
+  if (FLAG_branch_load_poisoning) {
+    __ ResetSpeculationPoisonRegister();
+  }
+
+  // Compute the handler entry address and jump to it.
+  ConstantPoolUnavailableScope constant_pool_unavailable(masm);
+  __ Move(ip, pending_handler_entrypoint_address);
+  __ LoadP(ip, MemOperand(ip));
+  if (FLAG_enable_embedded_constant_pool) {
+    __ Move(kConstantPoolRegister, pending_handler_constant_pool_address);
+    __ LoadP(kConstantPoolRegister, MemOperand(kConstantPoolRegister));
+  }
+  __ Jump(ip);
+}
+
 void Builtins::Generate_DoubleToI(MacroAssembler* masm) {
   Label out_of_range, only_low, negate, done, fastpath_done;
   Register result_reg = r3;
diff --git a/src/builtins/s390/builtins-s390.cc b/src/builtins/s390/builtins-s390.cc
index 2172828a167..211455a2402 100644
--- a/src/builtins/s390/builtins-s390.cc
+++ b/src/builtins/s390/builtins-s390.cc
@@ -5,6 +5,7 @@
 #if V8_TARGET_ARCH_S390
 
 #include "src/assembler-inl.h"
+#include "src/code-factory.h"
 #include "src/code-stubs.h"
 #include "src/debug/debug.h"
 #include "src/deoptimizer.h"
@@ -52,7 +53,7 @@ void AdaptorWithExitFrameType(MacroAssembler* masm,
   // ordinary functions).
   __ LoadP(cp, FieldMemOperand(r3, JSFunction::kContextOffset));
 
-  // CEntryStub expects r2 to contain the number of arguments including the
+  // CEntry expects r2 to contain the number of arguments including the
   // receiver and the extra arguments.
   __ AddP(r2, r2,
           Operand(BuiltinExitFrameConstants::kNumExtraArgsWithReceiver));
@@ -67,9 +68,10 @@ void AdaptorWithExitFrameType(MacroAssembler* masm,
   // JumpToExternalReference. We have already loaded entry point to r7
   // in Generate_adaptor.
   __ LoadRR(r3, r7);
-  CEntryStub stub(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
-                  exit_frame_type == Builtins::BUILTIN_EXIT);
-  __ Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+  Handle<Code> code =
+      CodeFactory::CEntry(masm->isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
+                          exit_frame_type == Builtins::BUILTIN_EXIT);
+  __ Jump(code, RelocInfo::CODE_TARGET);
 }
 }  // namespace
 
@@ -2672,7 +2674,7 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
 
     // Pass the WASM instance as an explicit argument to WasmCompileLazy.
     __ Push(kWasmInstanceRegister);
-    // Initialize the JavaScript context with 0. CEntryStub will use it to
+    // Initialize the JavaScript context with 0. CEntry will use it to
     // set the current context on the isolate.
     __ LoadSmiLiteral(cp, Smi::kZero);
     __ CallRuntime(Runtime::kWasmCompileLazy);
@@ -2689,6 +2691,186 @@ void Builtins::Generate_WasmCompileLazy(MacroAssembler* masm) {
   __ Jump(ip);
 }
 
+void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
+                               SaveFPRegsMode save_doubles, ArgvMode argv_mode,
+                               bool builtin_exit_frame) {
+  // Called from JavaScript; parameters are on stack as if calling JS function.
+  // r2: number of arguments including receiver
+  // r3: pointer to builtin function
+  // fp: frame pointer  (restored after C call)
+  // sp: stack pointer  (restored as callee's sp after C call)
+  // cp: current context  (C callee-saved)
+  //
+  // If argv_mode == kArgvInRegister:
+  // r4: pointer to the first argument
+  ProfileEntryHookStub::MaybeCallEntryHook(masm);
+
+  __ LoadRR(r7, r3);
+
+  if (argv_mode == kArgvInRegister) {
+    // Move argv into the correct register.
+    __ LoadRR(r3, r4);
+  } else {
+    // Compute the argv pointer.
+    __ ShiftLeftP(r3, r2, Operand(kPointerSizeLog2));
+    __ lay(r3, MemOperand(r3, sp, -kPointerSize));
+  }
+
+  // Enter the exit frame that transitions from JavaScript to C++.
+  FrameScope scope(masm, StackFrame::MANUAL);
+
+  // Need at least one extra slot for return address location.
+  int arg_stack_space = 1;
+
+  // Pass buffer for return value on stack if necessary
+  bool needs_return_buffer =
+      result_size == 2 && !ABI_RETURNS_OBJECTPAIR_IN_REGS;
+  if (needs_return_buffer) {
+    arg_stack_space += result_size;
+  }
+
+#if V8_TARGET_ARCH_S390X
+  // 64-bit linux pass Argument object by reference not value
+  arg_stack_space += 2;
+#endif
+
+  __ EnterExitFrame(
+      save_doubles, arg_stack_space,
+      builtin_exit_frame ? StackFrame::BUILTIN_EXIT : StackFrame::EXIT);
+
+  // Store a copy of argc, argv in callee-saved registers for later.
+  __ LoadRR(r6, r2);
+  __ LoadRR(r8, r3);
+  // r2, r6: number of arguments including receiver  (C callee-saved)
+  // r3, r8: pointer to the first argument
+  // r7: pointer to builtin function  (C callee-saved)
+
+  // Result returned in registers or stack, depending on result size and ABI.
+
+  Register isolate_reg = r4;
+  if (needs_return_buffer) {
+    // The return value is 16-byte non-scalar value.
+    // Use frame storage reserved by calling function to pass return
+    // buffer as implicit first argument in R2.  Shfit original parameters
+    // by one register each.
+    __ LoadRR(r4, r3);
+    __ LoadRR(r3, r2);
+    __ la(r2, MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kPointerSize));
+    isolate_reg = r5;
+  }
+  // Call C built-in.
+  __ Move(isolate_reg, ExternalReference::isolate_address(masm->isolate()));
+
+  Register target = r7;
+
+  // To let the GC traverse the return address of the exit frames, we need to
+  // know where the return address is. The CEntryStub is unmovable, so
+  // we can store the address on the stack to be able to find it again and
+  // we never have to restore it, because it will not change.
+  {
+    Label return_label;
+    __ larl(r14, &return_label);  // Generate the return addr of call later.
+    __ StoreP(r14, MemOperand(sp, kStackFrameRASlot * kPointerSize));
+
+    // zLinux ABI requires caller's frame to have sufficient space for callee
+    // preserved regsiter save area.
+    // __ lay(sp, MemOperand(sp, -kCalleeRegisterSaveAreaSize));
+    __ b(target);
+    __ bind(&return_label);
+    // __ la(sp, MemOperand(sp, +kCalleeRegisterSaveAreaSize));
+  }
+
+  // If return value is on the stack, pop it to registers.
+  if (needs_return_buffer) {
+    __ LoadP(r3, MemOperand(r2, kPointerSize));
+    __ LoadP(r2, MemOperand(r2));
+  }
+
+  // Check result for exception sentinel.
+  Label exception_returned;
+  __ CompareRoot(r2, Heap::kExceptionRootIndex);
+  __ beq(&exception_returned, Label::kNear);
+
+  // Check that there is no pending exception, otherwise we
+  // should have returned the exception sentinel.
+  if (FLAG_debug_code) {
+    Label okay;
+    ExternalReference pending_exception_address = ExternalReference::Create(
+        IsolateAddressId::kPendingExceptionAddress, masm->isolate());
+    __ Move(r1, pending_exception_address);
+    __ LoadP(r1, MemOperand(r1));
+    __ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
+    // Cannot use check here as it attempts to generate call into runtime.
+    __ beq(&okay, Label::kNear);
+    __ stop("Unexpected pending exception");
+    __ bind(&okay);
+  }
+
+  // Exit C frame and return.
+  // r2:r3: result
+  // sp: stack pointer
+  // fp: frame pointer
+  Register argc = argv_mode == kArgvInRegister
+                      // We don't want to pop arguments so set argc to no_reg.
+                      ? no_reg
+                      // r6: still holds argc (callee-saved).
+                      : r6;
+  __ LeaveExitFrame(save_doubles, argc);
+  __ b(r14);
+
+  // Handling of exception.
+  __ bind(&exception_returned);
+
+  ExternalReference pending_handler_context_address = ExternalReference::Create(
+      IsolateAddressId::kPendingHandlerContextAddress, masm->isolate());
+  ExternalReference pending_handler_entrypoint_address =
+      ExternalReference::Create(
+          IsolateAddressId::kPendingHandlerEntrypointAddress, masm->isolate());
+  ExternalReference pending_handler_fp_address = ExternalReference::Create(
+      IsolateAddressId::kPendingHandlerFPAddress, masm->isolate());
+  ExternalReference pending_handler_sp_address = ExternalReference::Create(
+      IsolateAddressId::kPendingHandlerSPAddress, masm->isolate());
+
+  // Ask the runtime for help to determine the handler. This will set r3 to
+  // contain the current pending exception, don't clobber it.
+  ExternalReference find_handler =
+      ExternalReference::Create(Runtime::kUnwindAndFindExceptionHandler);
+  {
+    FrameScope scope(masm, StackFrame::MANUAL);
+    __ PrepareCallCFunction(3, 0, r2);
+    __ LoadImmP(r2, Operand::Zero());
+    __ LoadImmP(r3, Operand::Zero());
+    __ Move(r4, ExternalReference::isolate_address(masm->isolate()));
+    __ CallCFunction(find_handler, 3);
+  }
+
+  // Retrieve the handler context, SP and FP.
+  __ Move(cp, pending_handler_context_address);
+  __ LoadP(cp, MemOperand(cp));
+  __ Move(sp, pending_handler_sp_address);
+  __ LoadP(sp, MemOperand(sp));
+  __ Move(fp, pending_handler_fp_address);
+  __ LoadP(fp, MemOperand(fp));
+
+  // If the handler is a JS frame, restore the context to the frame. Note that
+  // the context will be set to (cp == 0) for non-JS frames.
+  Label skip;
+  __ CmpP(cp, Operand::Zero());
+  __ beq(&skip, Label::kNear);
+  __ StoreP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
+  __ bind(&skip);
+
+  // Reset the masking register.
+  if (FLAG_branch_load_poisoning) {
+    __ ResetSpeculationPoisonRegister();
+  }
+
+  // Compute the handler entry address and jump to it.
+  __ Move(r3, pending_handler_entrypoint_address);
+  __ LoadP(r3, MemOperand(r3));
+  __ Jump(r3);
+}
+
 void Builtins::Generate_DoubleToI(MacroAssembler* masm) {
   Label out_of_range, only_low, negate, done, fastpath_done;
   Register result_reg = r2;
diff --git a/src/ppc/code-stubs-ppc.cc b/src/ppc/code-stubs-ppc.cc
index dd1137d4e13..4cda05c629b 100644
--- a/src/ppc/code-stubs-ppc.cc
+++ b/src/ppc/code-stubs-ppc.cc
@@ -36,217 +36,11 @@ void ArrayNArgumentsConstructorStub::Generate(MacroAssembler* masm) {
   __ TailCallRuntime(Runtime::kNewArray);
 }
 
-Movability CEntryStub::NeedsImmovableCode() { return kImmovable; }
-
 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
-  CEntryStub::GenerateAheadOfTime(isolate);
   CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
   StoreFastElementStub::GenerateAheadOfTime(isolate);
 }
 
-
-void CodeStub::GenerateFPStubs(Isolate* isolate) {
-  // Generate if not already in cache.
-  SaveFPRegsMode mode = kSaveFPRegs;
-  CEntryStub(isolate, 1, mode).GetCode();
-}
-
-
-void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
-  CEntryStub stub(isolate, 1, kDontSaveFPRegs);
-  stub.GetCode();
-  CEntryStub save_doubles(isolate, 1, kSaveFPRegs);
-  save_doubles.GetCode();
-}
-
-
-void CEntryStub::Generate(MacroAssembler* masm) {
-  // Called from JavaScript; parameters are on stack as if calling JS function.
-  // r3: number of arguments including receiver
-  // r4: pointer to builtin function
-  // fp: frame pointer  (restored after C call)
-  // sp: stack pointer  (restored as callee's sp after C call)
-  // cp: current context  (C callee-saved)
-  //
-  // If argv_in_register():
-  // r5: pointer to the first argument
-  ProfileEntryHookStub::MaybeCallEntryHook(masm);
-
-  __ mr(r15, r4);
-
-  if (argv_in_register()) {
-    // Move argv into the correct register.
-    __ mr(r4, r5);
-  } else {
-    // Compute the argv pointer.
-    __ ShiftLeftImm(r4, r3, Operand(kPointerSizeLog2));
-    __ add(r4, r4, sp);
-    __ subi(r4, r4, Operand(kPointerSize));
-  }
-
-  // Enter the exit frame that transitions from JavaScript to C++.
-  FrameScope scope(masm, StackFrame::MANUAL);
-
-  // Need at least one extra slot for return address location.
-  int arg_stack_space = 1;
-
-  // Pass buffer for return value on stack if necessary
-  bool needs_return_buffer =
-      (result_size() == 2 && !ABI_RETURNS_OBJECT_PAIRS_IN_REGS);
-  if (needs_return_buffer) {
-    arg_stack_space += result_size();
-  }
-
-  __ EnterExitFrame(save_doubles(), arg_stack_space, is_builtin_exit()
-                                           ? StackFrame::BUILTIN_EXIT
-                                           : StackFrame::EXIT);
-
-  // Store a copy of argc in callee-saved registers for later.
-  __ mr(r14, r3);
-
-  // r3, r14: number of arguments including receiver  (C callee-saved)
-  // r4: pointer to the first argument
-  // r15: pointer to builtin function  (C callee-saved)
-
-  // Result returned in registers or stack, depending on result size and ABI.
-
-  Register isolate_reg = r5;
-  if (needs_return_buffer) {
-    // The return value is a non-scalar value.
-    // Use frame storage reserved by calling function to pass return
-    // buffer as implicit first argument.
-    __ mr(r5, r4);
-    __ mr(r4, r3);
-    __ addi(r3, sp, Operand((kStackFrameExtraParamSlot + 1) * kPointerSize));
-    isolate_reg = r6;
-  }
-
-  // Call C built-in.
-  __ mov(isolate_reg, Operand(ExternalReference::isolate_address(isolate())));
-
-  Register target = r15;
-  if (ABI_USES_FUNCTION_DESCRIPTORS) {
-    // AIX/PPC64BE Linux use a function descriptor.
-    __ LoadP(ToRegister(ABI_TOC_REGISTER), MemOperand(r15, kPointerSize));
-    __ LoadP(ip, MemOperand(r15, 0));  // Instruction address
-    target = ip;
-  } else if (ABI_CALL_VIA_IP) {
-    __ Move(ip, r15);
-    target = ip;
-  }
-
-  // To let the GC traverse the return address of the exit frames, we need to
-  // know where the return address is. The CEntryStub is unmovable, so
-  // we can store the address on the stack to be able to find it again and
-  // we never have to restore it, because it will not change.
-  Label after_call;
-  __ mov_label_addr(r0, &after_call);
-  __ StoreP(r0, MemOperand(sp, kStackFrameExtraParamSlot * kPointerSize));
-  __ Call(target);
-  __ bind(&after_call);
-
-  // If return value is on the stack, pop it to registers.
-  if (needs_return_buffer) {
-    __ LoadP(r4, MemOperand(r3, kPointerSize));
-    __ LoadP(r3, MemOperand(r3));
-  }
-
-  // Check result for exception sentinel.
-  Label exception_returned;
-  __ CompareRoot(r3, Heap::kExceptionRootIndex);
-  __ beq(&exception_returned);
-
-  // Check that there is no pending exception, otherwise we
-  // should have returned the exception sentinel.
-  if (FLAG_debug_code) {
-    Label okay;
-    ExternalReference pending_exception_address = ExternalReference::Create(
-        IsolateAddressId::kPendingExceptionAddress, isolate());
-
-    __ mov(r6, Operand(pending_exception_address));
-    __ LoadP(r6, MemOperand(r6));
-    __ CompareRoot(r6, Heap::kTheHoleValueRootIndex);
-    // Cannot use check here as it attempts to generate call into runtime.
-    __ beq(&okay);
-    __ stop("Unexpected pending exception");
-    __ bind(&okay);
-  }
-
-  // Exit C frame and return.
-  // r3:r4: result
-  // sp: stack pointer
-  // fp: frame pointer
-  Register argc = argv_in_register()
-                      // We don't want to pop arguments so set argc to no_reg.
-                      ? no_reg
-                      // r14: still holds argc (callee-saved).
-                      : r14;
-  __ LeaveExitFrame(save_doubles(), argc);
-  __ blr();
-
-  // Handling of exception.
-  __ bind(&exception_returned);
-
-  ExternalReference pending_handler_context_address = ExternalReference::Create(
-      IsolateAddressId::kPendingHandlerContextAddress, isolate());
-  ExternalReference pending_handler_entrypoint_address =
-      ExternalReference::Create(
-          IsolateAddressId::kPendingHandlerEntrypointAddress, isolate());
-  ExternalReference pending_handler_constant_pool_address =
-      ExternalReference::Create(
-          IsolateAddressId::kPendingHandlerConstantPoolAddress, isolate());
-  ExternalReference pending_handler_fp_address = ExternalReference::Create(
-      IsolateAddressId::kPendingHandlerFPAddress, isolate());
-  ExternalReference pending_handler_sp_address = ExternalReference::Create(
-      IsolateAddressId::kPendingHandlerSPAddress, isolate());
-
-  // Ask the runtime for help to determine the handler. This will set r3 to
-  // contain the current pending exception, don't clobber it.
-  ExternalReference find_handler =
-      ExternalReference::Create(Runtime::kUnwindAndFindExceptionHandler);
-  {
-    FrameScope scope(masm, StackFrame::MANUAL);
-    __ PrepareCallCFunction(3, 0, r3);
-    __ li(r3, Operand::Zero());
-    __ li(r4, Operand::Zero());
-    __ mov(r5, Operand(ExternalReference::isolate_address(isolate())));
-    __ CallCFunction(find_handler, 3);
-  }
-
-  // Retrieve the handler context, SP and FP.
-  __ mov(cp, Operand(pending_handler_context_address));
-  __ LoadP(cp, MemOperand(cp));
-  __ mov(sp, Operand(pending_handler_sp_address));
-  __ LoadP(sp, MemOperand(sp));
-  __ mov(fp, Operand(pending_handler_fp_address));
-  __ LoadP(fp, MemOperand(fp));
-
-  // If the handler is a JS frame, restore the context to the frame. Note that
-  // the context will be set to (cp == 0) for non-JS frames.
-  Label skip;
-  __ cmpi(cp, Operand::Zero());
-  __ beq(&skip);
-  __ StoreP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  __ bind(&skip);
-
-  // Reset the masking register.
-  if (FLAG_branch_load_poisoning) {
-    __ ResetSpeculationPoisonRegister();
-  }
-
-  // Compute the handler entry address and jump to it.
-  ConstantPoolUnavailableScope constant_pool_unavailable(masm);
-  __ mov(ip, Operand(pending_handler_entrypoint_address));
-  __ LoadP(ip, MemOperand(ip));
-  if (FLAG_enable_embedded_constant_pool) {
-    __ mov(kConstantPoolRegister,
-           Operand(pending_handler_constant_pool_address));
-    __ LoadP(kConstantPoolRegister, MemOperand(kConstantPoolRegister));
-  }
-  __ Jump(ip);
-}
-
-
 void JSEntryStub::Generate(MacroAssembler* masm) {
   // r3: code entry
   // r4: function
diff --git a/src/ppc/interface-descriptors-ppc.cc b/src/ppc/interface-descriptors-ppc.cc
index c76c7525b6d..443716e55cc 100644
--- a/src/ppc/interface-descriptors-ppc.cc
+++ b/src/ppc/interface-descriptors-ppc.cc
@@ -253,12 +253,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
   data->InitializePlatformSpecific(arraysize(registers), registers);
 }
 
-void StringAddDescriptor::InitializePlatformSpecific(
-    CallInterfaceDescriptorData* data) {
-  Register registers[] = {r4, r3};
-  data->InitializePlatformSpecific(arraysize(registers), registers);
-}
-
 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
     CallInterfaceDescriptorData* data) {
   Register registers[] = {
diff --git a/src/ppc/macro-assembler-ppc.cc b/src/ppc/macro-assembler-ppc.cc
index f586d0d7805..2c0df5e5c45 100644
--- a/src/ppc/macro-assembler-ppc.cc
+++ b/src/ppc/macro-assembler-ppc.cc
@@ -12,6 +12,7 @@
 #include "src/bootstrapper.h"
 #include "src/builtins/constants-table-builder.h"
 #include "src/callable.h"
+#include "src/code-factory.h"
 #include "src/code-stubs.h"
 #include "src/debug/debug.h"
 #include "src/external-reference-table.h"
@@ -1060,7 +1061,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space,
     StoreP(kConstantPoolRegister,
            MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
   }
-  mov(r8, Operand(CodeObject()));
+  Move(r8, CodeObject());
   StoreP(r8, MemOperand(fp, ExitFrameConstants::kCodeOffset));
 
   // Save the frame pointer and the context in top.
@@ -1684,13 +1685,13 @@ void TurboAssembler::CallRuntimeDelayed(Zone* zone, Runtime::FunctionId fid,
   // smarter.
   mov(r3, Operand(f->nargs));
   Move(r4, ExternalReference::Create(f));
-  CallStubDelayed(new (zone) CEntryStub(nullptr,
 #if V8_TARGET_ARCH_PPC64
-                                        f->result_size,
+  Handle<Code> code =
+      CodeFactory::CEntry(isolate(), f->result_size, save_doubles);
 #else
-                                        1,
+  Handle<Code> code = CodeFactory::CEntry(isolate(), 1, save_doubles);
 #endif
-                                        save_doubles));
+  Call(code, RelocInfo::CODE_TARGET);
 }
 
 void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
@@ -1708,14 +1709,13 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
   // smarter.
   mov(r3, Operand(num_arguments));
   Move(r4, ExternalReference::Create(f));
-  CEntryStub stub(isolate(),
 #if V8_TARGET_ARCH_PPC64
-                  f->result_size,
+  Handle<Code> code =
+      CodeFactory::CEntry(isolate(), f->result_size, save_doubles);
 #else
-                  1,
+  Handle<Code> code = CodeFactory::CEntry(isolate(), 1, save_doubles);
 #endif
-                  save_doubles);
-  CallStub(&stub);
+  Call(code, RelocInfo::CODE_TARGET);
 }
 
 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) {
@@ -1731,9 +1731,9 @@ void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) {
 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin,
                                              bool builtin_exit_frame) {
   Move(r4, builtin);
-  CEntryStub stub(isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
-                  builtin_exit_frame);
-  Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+  Handle<Code> code = CodeFactory::CEntry(isolate(), 1, kDontSaveFPRegs,
+                                          kArgvOnStack, builtin_exit_frame);
+  Jump(code, RelocInfo::CODE_TARGET);
 }
 
 void MacroAssembler::JumpToInstructionStream(Address entry) {
diff --git a/src/s390/code-stubs-s390.cc b/src/s390/code-stubs-s390.cc
index b464fff5a17..cc41c1edcd6 100644
--- a/src/s390/code-stubs-s390.cc
+++ b/src/s390/code-stubs-s390.cc
@@ -35,204 +35,11 @@ void ArrayNArgumentsConstructorStub::Generate(MacroAssembler* masm) {
   __ TailCallRuntime(Runtime::kNewArray);
 }
 
-Movability CEntryStub::NeedsImmovableCode() { return kImmovable; }
-
 void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
-  CEntryStub::GenerateAheadOfTime(isolate);
   CommonArrayConstructorStub::GenerateStubsAheadOfTime(isolate);
   StoreFastElementStub::GenerateAheadOfTime(isolate);
 }
 
-void CodeStub::GenerateFPStubs(Isolate* isolate) {
-  SaveFPRegsMode mode = kSaveFPRegs;
-  CEntryStub(isolate, 1, mode).GetCode();
-}
-
-void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
-  CEntryStub stub(isolate, 1, kDontSaveFPRegs);
-  stub.GetCode();
-  CEntryStub save_doubles(isolate, 1, kSaveFPRegs);
-  save_doubles.GetCode();
-}
-
-void CEntryStub::Generate(MacroAssembler* masm) {
-  // Called from JavaScript; parameters are on stack as if calling JS function.
-  // r2: number of arguments including receiver
-  // r3: pointer to builtin function
-  // fp: frame pointer  (restored after C call)
-  // sp: stack pointer  (restored as callee's sp after C call)
-  // cp: current context  (C callee-saved)
-  //
-  // If argv_in_register():
-  // r4: pointer to the first argument
-  ProfileEntryHookStub::MaybeCallEntryHook(masm);
-
-  __ LoadRR(r7, r3);
-
-  if (argv_in_register()) {
-    // Move argv into the correct register.
-    __ LoadRR(r3, r4);
-  } else {
-    // Compute the argv pointer.
-    __ ShiftLeftP(r3, r2, Operand(kPointerSizeLog2));
-    __ lay(r3, MemOperand(r3, sp, -kPointerSize));
-  }
-
-  // Enter the exit frame that transitions from JavaScript to C++.
-  FrameScope scope(masm, StackFrame::MANUAL);
-
-  // Need at least one extra slot for return address location.
-  int arg_stack_space = 1;
-
-  // Pass buffer for return value on stack if necessary
-  bool needs_return_buffer =
-      result_size() == 2 && !ABI_RETURNS_OBJECTPAIR_IN_REGS;
-  if (needs_return_buffer) {
-    arg_stack_space += result_size();
-  }
-
-#if V8_TARGET_ARCH_S390X
-  // 64-bit linux pass Argument object by reference not value
-  arg_stack_space += 2;
-#endif
-
-  __ EnterExitFrame(save_doubles(), arg_stack_space, is_builtin_exit()
-                                           ? StackFrame::BUILTIN_EXIT
-                                           : StackFrame::EXIT);
-
-  // Store a copy of argc, argv in callee-saved registers for later.
-  __ LoadRR(r6, r2);
-  __ LoadRR(r8, r3);
-  // r2, r6: number of arguments including receiver  (C callee-saved)
-  // r3, r8: pointer to the first argument
-  // r7: pointer to builtin function  (C callee-saved)
-
-  // Result returned in registers or stack, depending on result size and ABI.
-
-  Register isolate_reg = r4;
-  if (needs_return_buffer) {
-    // The return value is 16-byte non-scalar value.
-    // Use frame storage reserved by calling function to pass return
-    // buffer as implicit first argument in R2.  Shfit original parameters
-    // by one register each.
-    __ LoadRR(r4, r3);
-    __ LoadRR(r3, r2);
-    __ la(r2, MemOperand(sp, (kStackFrameExtraParamSlot + 1) * kPointerSize));
-    isolate_reg = r5;
-  }
-  // Call C built-in.
-  __ mov(isolate_reg, Operand(ExternalReference::isolate_address(isolate())));
-
-  Register target = r7;
-
-  // To let the GC traverse the return address of the exit frames, we need to
-  // know where the return address is. The CEntryStub is unmovable, so
-  // we can store the address on the stack to be able to find it again and
-  // we never have to restore it, because it will not change.
-  {
-    Label return_label;
-    __ larl(r14, &return_label);  // Generate the return addr of call later.
-    __ StoreP(r14, MemOperand(sp, kStackFrameRASlot * kPointerSize));
-
-    // zLinux ABI requires caller's frame to have sufficient space for callee
-    // preserved regsiter save area.
-    // __ lay(sp, MemOperand(sp, -kCalleeRegisterSaveAreaSize));
-    __ b(target);
-    __ bind(&return_label);
-    // __ la(sp, MemOperand(sp, +kCalleeRegisterSaveAreaSize));
-  }
-
-  // If return value is on the stack, pop it to registers.
-  if (needs_return_buffer) {
-    __ LoadP(r3, MemOperand(r2, kPointerSize));
-    __ LoadP(r2, MemOperand(r2));
-  }
-
-  // Check result for exception sentinel.
-  Label exception_returned;
-  __ CompareRoot(r2, Heap::kExceptionRootIndex);
-  __ beq(&exception_returned, Label::kNear);
-
-  // Check that there is no pending exception, otherwise we
-  // should have returned the exception sentinel.
-  if (FLAG_debug_code) {
-    Label okay;
-    ExternalReference pending_exception_address = ExternalReference::Create(
-        IsolateAddressId::kPendingExceptionAddress, isolate());
-    __ mov(r1, Operand(pending_exception_address));
-    __ LoadP(r1, MemOperand(r1));
-    __ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
-    // Cannot use check here as it attempts to generate call into runtime.
-    __ beq(&okay, Label::kNear);
-    __ stop("Unexpected pending exception");
-    __ bind(&okay);
-  }
-
-  // Exit C frame and return.
-  // r2:r3: result
-  // sp: stack pointer
-  // fp: frame pointer
-  Register argc = argv_in_register()
-                      // We don't want to pop arguments so set argc to no_reg.
-                      ? no_reg
-                      // r6: still holds argc (callee-saved).
-                      : r6;
-  __ LeaveExitFrame(save_doubles(), argc);
-  __ b(r14);
-
-  // Handling of exception.
-  __ bind(&exception_returned);
-
-  ExternalReference pending_handler_context_address = ExternalReference::Create(
-      IsolateAddressId::kPendingHandlerContextAddress, isolate());
-  ExternalReference pending_handler_entrypoint_address =
-      ExternalReference::Create(
-          IsolateAddressId::kPendingHandlerEntrypointAddress, isolate());
-  ExternalReference pending_handler_fp_address = ExternalReference::Create(
-      IsolateAddressId::kPendingHandlerFPAddress, isolate());
-  ExternalReference pending_handler_sp_address = ExternalReference::Create(
-      IsolateAddressId::kPendingHandlerSPAddress, isolate());
-
-  // Ask the runtime for help to determine the handler. This will set r3 to
-  // contain the current pending exception, don't clobber it.
-  ExternalReference find_handler =
-      ExternalReference::Create(Runtime::kUnwindAndFindExceptionHandler);
-  {
-    FrameScope scope(masm, StackFrame::MANUAL);
-    __ PrepareCallCFunction(3, 0, r2);
-    __ LoadImmP(r2, Operand::Zero());
-    __ LoadImmP(r3, Operand::Zero());
-    __ mov(r4, Operand(ExternalReference::isolate_address(isolate())));
-    __ CallCFunction(find_handler, 3);
-  }
-
-  // Retrieve the handler context, SP and FP.
-  __ mov(cp, Operand(pending_handler_context_address));
-  __ LoadP(cp, MemOperand(cp));
-  __ mov(sp, Operand(pending_handler_sp_address));
-  __ LoadP(sp, MemOperand(sp));
-  __ mov(fp, Operand(pending_handler_fp_address));
-  __ LoadP(fp, MemOperand(fp));
-
-  // If the handler is a JS frame, restore the context to the frame. Note that
-  // the context will be set to (cp == 0) for non-JS frames.
-  Label skip;
-  __ CmpP(cp, Operand::Zero());
-  __ beq(&skip, Label::kNear);
-  __ StoreP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
-  __ bind(&skip);
-
-  // Reset the masking register.
-  if (FLAG_branch_load_poisoning) {
-    __ ResetSpeculationPoisonRegister();
-  }
-
-  // Compute the handler entry address and jump to it.
-  __ mov(r3, Operand(pending_handler_entrypoint_address));
-  __ LoadP(r3, MemOperand(r3));
-  __ Jump(r3);
-}
-
 void JSEntryStub::Generate(MacroAssembler* masm) {
   // r2: code entry
   // r3: function
diff --git a/src/s390/interface-descriptors-s390.cc b/src/s390/interface-descriptors-s390.cc
index 6b00957a0ec..87a802b0913 100644
--- a/src/s390/interface-descriptors-s390.cc
+++ b/src/s390/interface-descriptors-s390.cc
@@ -247,12 +247,6 @@ void BinaryOpDescriptor::InitializePlatformSpecific(
   data->InitializePlatformSpecific(arraysize(registers), registers);
 }
 
-void StringAddDescriptor::InitializePlatformSpecific(
-    CallInterfaceDescriptorData* data) {
-  Register registers[] = {r3, r2};
-  data->InitializePlatformSpecific(arraysize(registers), registers);
-}
-
 void ArgumentAdaptorDescriptor::InitializePlatformSpecific(
     CallInterfaceDescriptorData* data) {
   Register registers[] = {
diff --git a/src/s390/macro-assembler-s390.cc b/src/s390/macro-assembler-s390.cc
index 8d8554920c3..47cabb56ee6 100644
--- a/src/s390/macro-assembler-s390.cc
+++ b/src/s390/macro-assembler-s390.cc
@@ -12,6 +12,7 @@
 #include "src/bootstrapper.h"
 #include "src/builtins/constants-table-builder.h"
 #include "src/callable.h"
+#include "src/code-factory.h"
 #include "src/code-stubs.h"
 #include "src/debug/debug.h"
 #include "src/external-reference-table.h"
@@ -1084,7 +1085,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space,
   if (emit_debug_code()) {
     StoreP(MemOperand(fp, ExitFrameConstants::kSPOffset), Operand::Zero(), r1);
   }
-  mov(r1, Operand(CodeObject()));
+  Move(r1, CodeObject());
   StoreP(r1, MemOperand(fp, ExitFrameConstants::kCodeOffset));
 
   // Save the frame pointer and the context in top.
@@ -1155,14 +1156,14 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
   StoreP(MemOperand(ip), Operand(0, RelocInfo::NONE), r0);
 
   // Restore current context from top and clear it in debug mode.
-  mov(ip, Operand(ExternalReference::Create(IsolateAddressId::kContextAddress,
-                                            isolate())));
+  Move(ip,
+       ExternalReference::Create(IsolateAddressId::kContextAddress, isolate()));
   LoadP(cp, MemOperand(ip));
 
 #ifdef DEBUG
   mov(r1, Operand(Context::kInvalidContext));
-  mov(ip, Operand(ExternalReference::Create(IsolateAddressId::kContextAddress,
-                                            isolate())));
+  Move(ip,
+       ExternalReference::Create(IsolateAddressId::kContextAddress, isolate()));
   StoreP(r1, MemOperand(ip));
 #endif
 
@@ -1584,13 +1585,14 @@ void TurboAssembler::CallRuntimeDelayed(Zone* zone, Runtime::FunctionId fid,
   const Runtime::Function* f = Runtime::FunctionForId(fid);
   mov(r2, Operand(f->nargs));
   Move(r3, ExternalReference::Create(f));
-  CallStubDelayed(new (zone) CEntryStub(nullptr,
+
 #if V8_TARGET_ARCH_S390X
-                                        f->result_size,
+  Handle<Code> code =
+      CodeFactory::CEntry(isolate(), f->result_size, save_doubles);
 #else
-                                        1,
+  Handle<Code> code = CodeFactory::CEntry(isolate(), 1, save_doubles);
 #endif
-                                        save_doubles));
+  Call(code, RelocInfo::CODE_TARGET);
 }
 
 void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
@@ -1608,14 +1610,14 @@ void MacroAssembler::CallRuntime(const Runtime::Function* f, int num_arguments,
   // smarter.
   mov(r2, Operand(num_arguments));
   Move(r3, ExternalReference::Create(f));
-  CEntryStub stub(isolate(),
 #if V8_TARGET_ARCH_S390X
-                  f->result_size,
+  Handle<Code> code =
+      CodeFactory::CEntry(isolate(), f->result_size, save_doubles);
 #else
-                  1,
+  Handle<Code> code = CodeFactory::CEntry(isolate(), 1, save_doubles);
 #endif
-                  save_doubles);
-  CallStub(&stub);
+
+  Call(code, RelocInfo::CODE_TARGET);
 }
 
 void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) {
@@ -1630,9 +1632,9 @@ void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid) {
 void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin,
                                              bool builtin_exit_frame) {
   Move(r3, builtin);
-  CEntryStub stub(isolate(), 1, kDontSaveFPRegs, kArgvOnStack,
-                  builtin_exit_frame);
-  Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
+  Handle<Code> code = CodeFactory::CEntry(isolate(), 1, kDontSaveFPRegs,
+                                          kArgvOnStack, builtin_exit_frame);
+  Jump(code, RelocInfo::CODE_TARGET);
 }
 
 void MacroAssembler::JumpToInstructionStream(Address entry) {
-- 
2.18.1