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

Unified Diff: src/arm64/code-stubs-arm64.cc

Issue 240053010: Return Object* instead of MaybeObject* from runtime calls. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: cmpp Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/regexp-macro-assembler-arm.cc ('k') | src/arm64/regexp-macro-assembler-arm64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm64/code-stubs-arm64.cc
diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc
index a42f5cd34da87677a2f8fd4d59c417c82fbb4ee5..127588267d791170d0a88f56e32374f5a94026b0 100644
--- a/src/arm64/code-stubs-arm64.cc
+++ b/src/arm64/code-stubs-arm64.cc
@@ -1477,15 +1477,78 @@ void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
}
-void CEntryStub::GenerateCore(MacroAssembler* masm,
- Label* throw_normal,
- Label* throw_termination,
- bool do_gc,
- bool always_allocate) {
- // x0 : Result parameter for PerformGC, if do_gc is true.
+void CEntryStub::Generate(MacroAssembler* masm) {
+ // The Abort mechanism relies on CallRuntime, which in turn relies on
+ // CEntryStub, so until this stub has been generated, we have to use a
+ // fall-back Abort mechanism.
+ //
+ // Note that this stub must be generated before any use of Abort.
+ MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm);
+
+ ASM_LOCATION("CEntryStub::Generate entry");
+ ProfileEntryHookStub::MaybeCallEntryHook(masm);
+
+ // Register parameters:
+ // x0: argc (including receiver, untagged)
+ // x1: target
+ //
+ // The stack on entry holds the arguments and the receiver, with the receiver
+ // at the highest address:
+ //
+ // jssp]argc-1]: receiver
+ // jssp[argc-2]: arg[argc-2]
+ // ... ...
+ // jssp[1]: arg[1]
+ // jssp[0]: arg[0]
+ //
+ // The arguments are in reverse order, so that arg[argc-2] is actually the
+ // first argument to the target function and arg[0] is the last.
+ ASSERT(jssp.Is(__ StackPointer()));
+ const Register& argc_input = x0;
+ const Register& target_input = x1;
+
+ // Calculate argv, argc and the target address, and store them in
+ // callee-saved registers so we can retry the call without having to reload
+ // these arguments.
+ // TODO(jbramley): If the first call attempt succeeds in the common case (as
+ // it should), then we might be better off putting these parameters directly
+ // into their argument registers, rather than using callee-saved registers and
+ // preserving them on the stack.
+ const Register& argv = x21;
+ const Register& argc = x22;
+ const Register& target = x23;
+
+ // Derive argv from the stack pointer so that it points to the first argument
+ // (arg[argc-2]), or just below the receiver in case there are no arguments.
+ // - Adjust for the arg[] array.
+ Register temp_argv = x11;
+ __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2));
+ // - Adjust for the receiver.
+ __ Sub(temp_argv, temp_argv, 1 * kPointerSize);
+
+ // Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved
+ // registers.
+ FrameScope scope(masm, StackFrame::MANUAL);
+ __ EnterExitFrame(save_doubles_, x10, 3);
+ ASSERT(csp.Is(__ StackPointer()));
+
+ // Poke callee-saved registers into reserved space.
+ __ Poke(argv, 1 * kPointerSize);
+ __ Poke(argc, 2 * kPointerSize);
+ __ Poke(target, 3 * kPointerSize);
+
+ // We normally only keep tagged values in callee-saved registers, as they
+ // could be pushed onto the stack by called stubs and functions, and on the
+ // stack they can confuse the GC. However, we're only calling C functions
+ // which can push arbitrary data onto the stack anyway, and so the GC won't
+ // examine that part of the stack.
+ __ Mov(argc, argc_input);
+ __ Mov(target, target_input);
+ __ Mov(argv, temp_argv);
+
// x21 : argv
// x22 : argc
- // x23 : target
+ // x23 : call target
//
// The stack (on entry) holds the arguments and the receiver, with the
// receiver at the highest address:
@@ -1515,44 +1578,21 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
//
// After an unsuccessful call, the exit frame and suchlike are left
// untouched, and the stub either throws an exception by jumping to one of
- // the provided throw_ labels, or it falls through. The failure details are
- // passed through in x0.
+ // the exception_returned label.
+
ASSERT(csp.Is(__ StackPointer()));
Isolate* isolate = masm->isolate();
- const Register& argv = x21;
- const Register& argc = x22;
- const Register& target = x23;
-
- if (do_gc) {
- // Call Runtime::PerformGC, passing x0 (the result parameter for
- // PerformGC) and x1 (the isolate).
- __ Mov(x1, ExternalReference::isolate_address(masm->isolate()));
- __ CallCFunction(
- ExternalReference::perform_gc_function(isolate), 2, 0);
- }
-
- ExternalReference scope_depth =
- ExternalReference::heap_always_allocate_scope_depth(isolate);
- if (always_allocate) {
- __ Mov(x10, Operand(scope_depth));
- __ Ldr(x11, MemOperand(x10));
- __ Add(x11, x11, 1);
- __ Str(x11, MemOperand(x10));
- }
-
// Prepare AAPCS64 arguments to pass to the builtin.
__ Mov(x0, argc);
__ Mov(x1, argv);
__ Mov(x2, ExternalReference::isolate_address(isolate));
- // Store the return address on the stack, in the space previously allocated
- // by EnterExitFrame. The return address is queried by
- // ExitFrame::GetStateForFramePointer.
Label return_location;
__ Adr(x12, &return_location);
__ Poke(x12, 0);
+
if (__ emit_debug_code()) {
// Verify that the slot below fp[kSPOffset]-8 points to the return location
// (currently in x12).
@@ -1567,27 +1607,17 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Call the builtin.
__ Blr(target);
__ Bind(&return_location);
- const Register& result = x0;
-
- if (always_allocate) {
- __ Mov(x10, Operand(scope_depth));
- __ Ldr(x11, MemOperand(x10));
- __ Sub(x11, x11, 1);
- __ Str(x11, MemOperand(x10));
- }
// x0 result The return code from the call.
// x21 argv
// x22 argc
// x23 target
- //
- // If all of the result bits matching kFailureTagMask are '1', the result is
- // a failure. Otherwise, it's an ordinary tagged object and the call was a
- // success.
- Label failure;
- __ And(x10, result, kFailureTagMask);
- __ Cmp(x10, kFailureTagMask);
- __ B(&failure, eq);
+ const Register& result = x0;
+
+ // Check result for exception sentinel.
+ Label exception_returned;
+ __ CompareRoot(result, Heap::kExceptionRootIndex);
+ __ B(eq, &exception_returned);
// The call succeeded, so unwind the stack and return.
@@ -1612,27 +1642,15 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// hasn't changed (except for the return address).
__ SetStackPointer(csp);
- __ Bind(&failure);
- // The call failed, so check if we need to throw an exception, and fall
- // through (to retry) otherwise.
-
- Label retry;
- // x0 result The return code from the call, including the failure
- // code and details.
- // x21 argv
- // x22 argc
- // x23 target
- // Refer to the Failure class for details of the bit layout.
- STATIC_ASSERT(Failure::RETRY_AFTER_GC == 0);
- __ Tst(result, kFailureTypeTagMask << kFailureTagSize);
- __ B(eq, &retry); // RETRY_AFTER_GC
+ // Handling of exception.
+ __ Bind(&exception_returned);
// Retrieve the pending exception.
+ ExternalReference pending_exception_address(
+ Isolate::kPendingExceptionAddress, isolate);
const Register& exception = result;
const Register& exception_address = x11;
- __ Mov(exception_address,
- Operand(ExternalReference(Isolate::kPendingExceptionAddress,
- isolate)));
+ __ Mov(exception_address, Operand(pending_exception_address));
__ Ldr(exception, MemOperand(exception_address));
// Clear the pending exception.
@@ -1646,118 +1664,9 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Special handling of termination exceptions, which are uncatchable by
// JavaScript code.
+ Label throw_termination_exception;
__ Cmp(exception, Operand(isolate->factory()->termination_exception()));
- __ B(eq, throw_termination);
-
- // Handle normal exception.
- __ B(throw_normal);
-
- __ Bind(&retry);
- // The result (x0) is passed through as the next PerformGC parameter.
-}
-
-
-void CEntryStub::Generate(MacroAssembler* masm) {
- // The Abort mechanism relies on CallRuntime, which in turn relies on
- // CEntryStub, so until this stub has been generated, we have to use a
- // fall-back Abort mechanism.
- //
- // Note that this stub must be generated before any use of Abort.
- MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm);
-
- ASM_LOCATION("CEntryStub::Generate entry");
- ProfileEntryHookStub::MaybeCallEntryHook(masm);
-
- // Register parameters:
- // x0: argc (including receiver, untagged)
- // x1: target
- //
- // The stack on entry holds the arguments and the receiver, with the receiver
- // at the highest address:
- //
- // jssp]argc-1]: receiver
- // jssp[argc-2]: arg[argc-2]
- // ... ...
- // jssp[1]: arg[1]
- // jssp[0]: arg[0]
- //
- // The arguments are in reverse order, so that arg[argc-2] is actually the
- // first argument to the target function and arg[0] is the last.
- ASSERT(jssp.Is(__ StackPointer()));
- const Register& argc_input = x0;
- const Register& target_input = x1;
-
- // Calculate argv, argc and the target address, and store them in
- // callee-saved registers so we can retry the call without having to reload
- // these arguments.
- // TODO(jbramley): If the first call attempt succeeds in the common case (as
- // it should), then we might be better off putting these parameters directly
- // into their argument registers, rather than using callee-saved registers and
- // preserving them on the stack.
- const Register& argv = x21;
- const Register& argc = x22;
- const Register& target = x23;
-
- // Derive argv from the stack pointer so that it points to the first argument
- // (arg[argc-2]), or just below the receiver in case there are no arguments.
- // - Adjust for the arg[] array.
- Register temp_argv = x11;
- __ Add(temp_argv, jssp, Operand(x0, LSL, kPointerSizeLog2));
- // - Adjust for the receiver.
- __ Sub(temp_argv, temp_argv, 1 * kPointerSize);
-
- // Enter the exit frame. Reserve three slots to preserve x21-x23 callee-saved
- // registers.
- FrameScope scope(masm, StackFrame::MANUAL);
- __ EnterExitFrame(save_doubles_, x10, 3);
- ASSERT(csp.Is(__ StackPointer()));
-
- // Poke callee-saved registers into reserved space.
- __ Poke(argv, 1 * kPointerSize);
- __ Poke(argc, 2 * kPointerSize);
- __ Poke(target, 3 * kPointerSize);
-
- // We normally only keep tagged values in callee-saved registers, as they
- // could be pushed onto the stack by called stubs and functions, and on the
- // stack they can confuse the GC. However, we're only calling C functions
- // which can push arbitrary data onto the stack anyway, and so the GC won't
- // examine that part of the stack.
- __ Mov(argc, argc_input);
- __ Mov(target, target_input);
- __ Mov(argv, temp_argv);
-
- Label throw_normal;
- Label throw_termination;
-
- // Call the runtime function.
- GenerateCore(masm,
- &throw_normal,
- &throw_termination,
- false,
- false);
-
- // If successful, the previous GenerateCore will have returned to the
- // calling code. Otherwise, we fall through into the following.
-
- // Do space-specific GC and retry runtime call.
- GenerateCore(masm,
- &throw_normal,
- &throw_termination,
- true,
- false);
-
- // Do full GC and retry runtime call one final time.
- __ Mov(x0, reinterpret_cast<uint64_t>(Failure::InternalError()));
- GenerateCore(masm,
- &throw_normal,
- &throw_termination,
- true,
- true);
-
- { FrameScope scope(masm, StackFrame::MANUAL);
- __ CallCFunction(
- ExternalReference::out_of_memory_function(masm->isolate()), 0);
- }
+ __ B(eq, &throw_termination_exception);
// We didn't execute a return case, so the stack frame hasn't been updated
// (except for the return address slot). However, we don't need to initialize
@@ -1765,24 +1674,18 @@ void CEntryStub::Generate(MacroAssembler* masm) {
// unwinds the stack.
__ SetStackPointer(jssp);
- // Throw exceptions.
- // If we throw an exception, we can end up re-entering CEntryStub before we
- // pop the exit frame, so need to ensure that x21-x23 contain GC-safe values
- // here.
-
- __ Bind(&throw_termination);
- ASM_LOCATION("Throw termination");
+ ASM_LOCATION("Throw normal");
__ Mov(argv, 0);
__ Mov(argc, 0);
__ Mov(target, 0);
- __ ThrowUncatchable(x0, x10, x11, x12, x13);
+ __ Throw(x0, x10, x11, x12, x13);
- __ Bind(&throw_normal);
- ASM_LOCATION("Throw normal");
+ __ Bind(&throw_termination_exception);
+ ASM_LOCATION("Throw termination");
__ Mov(argv, 0);
__ Mov(argc, 0);
__ Mov(target, 0);
- __ Throw(x0, x10, x11, x12, x13);
+ __ ThrowUncatchable(x0, x10, x11, x12, x13);
}
@@ -1882,7 +1785,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
isolate)));
}
__ Str(code_entry, MemOperand(x10));
- __ Mov(x0, Operand(reinterpret_cast<int64_t>(Failure::Exception())));
+ __ LoadRoot(x0, Heap::kExceptionRootIndex);
__ B(&exit);
// Invoke: Link this frame into the handler chain. There's only one
« no previous file with comments | « src/arm/regexp-macro-assembler-arm.cc ('k') | src/arm64/regexp-macro-assembler-arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698