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

Unified Diff: src/arm/macro-assembler-arm.cc

Issue 6170001: Direct call api functions (arm implementation) (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 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
Index: src/arm/macro-assembler-arm.cc
===================================================================
--- src/arm/macro-assembler-arm.cc (revision 6213)
+++ src/arm/macro-assembler-arm.cc (working copy)
@@ -542,30 +542,23 @@
}
-void MacroAssembler::EnterExitFrame(bool save_doubles) {
- // r0 is argc.
- // Compute callee's stack pointer before making changes and save it as
- // ip register so that it is restored as sp register on exit, thereby
- // popping the args.
-
- // ip = sp + kPointerSize * #args;
- add(ip, sp, Operand(r0, LSL, kPointerSizeLog2));
-
- // Compute the argv pointer and keep it in a callee-saved register.
- sub(r6, ip, Operand(kPointerSize));
-
- // Prepare the stack to be aligned when calling into C. After this point there
- // are 5 pushes before the call into C, so the stack needs to be aligned after
- // 5 pushes.
+void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
+ // Prepare the stack to be aligned when calling into C.
+ int pending_pushes = stack_space + 4; // 4 pushes in this function.
int frame_alignment = ActivationFrameAlignment();
int frame_alignment_mask = frame_alignment - 1;
if (frame_alignment != kPointerSize) {
// The following code needs to be more general if this assert does not hold.
ASSERT(frame_alignment == 2 * kPointerSize);
- // With 5 pushes left the frame must be unaligned at this point.
mov(r7, Operand(Smi::FromInt(0)));
- tst(sp, Operand((frame_alignment - kPointerSize) & frame_alignment_mask));
- push(r7, eq); // Push if aligned to make it unaligned.
+ tst(sp, Operand(frame_alignment_mask));
+ // If stack is unaligned, align it if requesting even slots otherwise
+ // unalign it if requesting odd slots.
+ if (pending_pushes % 2 == 0) {
+ push(r7, ne);
+ } else {
+ push(r7, eq);
+ }
}
// Push in reverse order: caller_fp, sp_on_exit, and caller_pc.
@@ -581,10 +574,6 @@
mov(ip, Operand(ExternalReference(Top::k_context_address)));
str(cp, MemOperand(ip));
- // Setup argc and the builtin function in callee-saved registers.
- mov(r4, Operand(r0));
- mov(r5, Operand(r1));
-
// Optionally save all double registers.
if (save_doubles) {
// TODO(regis): Use vstrm instruction.
@@ -1397,6 +1386,121 @@
}
+MaybeObject* MacroAssembler::TryTailCallStub(CodeStub* stub, Condition cond) {
+ ASSERT(allow_stub_calls()); // stub calls are not allowed in some stubs
+ Object* result;
+ { MaybeObject* maybe_result = stub->TryGetCode();
+ if (!maybe_result->ToObject(&result)) return maybe_result;
+ }
+ Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
+ return result;
+}
+
Erik Corry 2011/01/24 21:45:16 You should have 2 blank lines between functions.
Zaheer 2011/01/25 07:39:52 Done.
+void MacroAssembler::PrepareCallApiFunction(int arg_stack_space,
+ int unwind_space) {
+ add(ip, sp, Operand(unwind_space * kPointerSize));
+ EnterExitFrame(false, arg_stack_space + 1);
+
+ // Create space for the arguments below the exit frame.
+ // +- exit frame -+- arguments -+- stack grows here -+
+ // 1 for the return address
+ sub(sp, sp, Operand((arg_stack_space + 1) * kPointerSize));
+}
+
+static int AddressOffset(ExternalReference ref0, ExternalReference ref1) {
+ int64_t offset = (ref0.address() - ref1.address());
+ // Check that fits into int.
+ ASSERT(static_cast<int>(offset) == offset);
+ return static_cast<int>(offset);
+}
+
+MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
+ ApiFunction* function) {
+ ExternalReference next_address =
+ ExternalReference::handle_scope_next_address();
+ const int kNextOffset = 0;
+ const int kLimitOffset = AddressOffset(
+ ExternalReference::handle_scope_limit_address(),
+ next_address);
+ const int kLevelOffset = AddressOffset(
+ ExternalReference::handle_scope_level_address(),
+ next_address);
+
+ // Allocate HandleScope in callee-save registers.
+ mov(r7, Operand(next_address));
+ ldr(r4, MemOperand(r7, kNextOffset));
+ ldr(r5, MemOperand(r7, kLimitOffset));
+ ldr(r6, MemOperand(r7, kLevelOffset));
+ add(r6, r6, Operand(1));
+ str(r6, MemOperand(r7, kLevelOffset));
+
+ // Native call returns to the DirectCEntry stub which redirects to the
+ // return address pushed on stack (could have moved after GC).
+ DirectCEntryStub stub;
+ mov(lr, Operand(reinterpret_cast<intptr_t>(stub.GetCode().location()),
+ RelocInfo::CODE_TARGET));
+
+ // Push return address (accessible to GC through exit frame pc).
+ ExternalReference ref =
+ ExternalReference(function, ExternalReference::DIRECT_CALL);
+ mov(r2, Operand(reinterpret_cast<intptr_t>(ref.address())));
+ add(ip, pc, Operand(4));
+ str(ip, MemOperand(fp, ExitFrameConstants::kPCOffset));
+ Jump(r2); // Call the api function.
+
+ Label promote_scheduled_exception;
+ Label delete_allocated_handles;
+ Label leave_exit_frame;
+
+ // If result is non-zero, dereference to get the result value
+ // otherwise set it to undefined.
+ cmp(r0, Operand(0));
+ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
+ ldr(r0, MemOperand(r0), ne);
+
+ // No more valid handles (the result handle was the last one). Restore
+ // previous handle scope.
+ str(r4, MemOperand(r7, kNextOffset));
+ if (FLAG_debug_code) {
+ ldr(r1, MemOperand(r7, kLevelOffset));
+ cmp(r1, r6);
+ Check(eq, "Unexpected level after return from api call");
+ }
+ sub(r6, r6, Operand(1));
+ str(r6, MemOperand(r7, kLevelOffset));
+ ldr(ip, MemOperand(r7, kLimitOffset));
+ cmp(r5, ip);
+ b(ne, &delete_allocated_handles);
+
+ // Check if the function scheduled an exception.
+ bind(&leave_exit_frame);
+ LoadRoot(r4, Heap::kTheHoleValueRootIndex);
+ mov(ip, Operand(ExternalReference(Top::k_pending_exception_address)));
+ ldr(r5, MemOperand(ip));
+ cmp(r4, r5);
+ b(ne, &promote_scheduled_exception);
+ LeaveExitFrame(false);
+
+ bind(&promote_scheduled_exception);
+ MaybeObject* result = TryTailCallExternalReference(
+ ExternalReference(Runtime::kPromoteScheduledException), 0, 1);
+ if (result->IsFailure()) {
+ return result;
+ }
+
+ // HandleScope limit has changed. Delete allocated extensions.
+ bind(&delete_allocated_handles);
+ str(r5, MemOperand(r7, kLimitOffset));
+ mov(r4, r0);
+ PrepareCallCFunction(0, r5);
+ CallCFunction(ExternalReference::delete_handle_scope_extensions(), 0);
+ mov(r0, r4);
+ jmp(&leave_exit_frame);
+
+ return result;
+}
+
+
void MacroAssembler::IllegalOperation(int num_arguments) {
if (num_arguments > 0) {
add(sp, sp, Operand(num_arguments * kPointerSize));
@@ -1649,6 +1753,15 @@
JumpToExternalReference(ext);
}
+MaybeObject* MacroAssembler::TryTailCallExternalReference(
+ const ExternalReference& ext, int num_arguments, int result_size) {
+ // TODO(1236192): Most runtime routines don't need the number of
+ // arguments passed in because it is constant. At some point we
+ // should remove this need and make the runtime routine entry code
+ // smarter.
+ mov(r0, Operand(num_arguments));
+ return TryJumpToExternalReference(ext);
+}
void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
int num_arguments,
@@ -1667,6 +1780,16 @@
Jump(stub.GetCode(), RelocInfo::CODE_TARGET);
}
+MaybeObject* MacroAssembler::TryJumpToExternalReference(
+ const ExternalReference& builtin) {
+#if defined(__thumb__)
+ // Thumb mode builtin.
+ ASSERT((reinterpret_cast<intptr_t>(builtin.address()) & 1) == 1);
+#endif
+ mov(r1, Operand(builtin));
+ CEntryStub stub(1);
+ return TryTailCallStub(&stub);
+}
void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
InvokeJSFlags flags) {
« no previous file with comments | « src/arm/macro-assembler-arm.h ('k') | src/arm/simulator-arm.h » ('j') | src/arm/simulator-arm.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698