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

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)
@@ -1397,6 +1397,133 @@
}
+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;
+}
+
+
+void MacroAssembler::PrepareCallApiFunction(int arg_stack_space,
+ int unwind_space,
+ Register scratch) {
+ mov(scratch, Operand(unwind_space));
antonm 2011/01/11 14:11:33 it looks like a lot of code below is shared with M
Zaheer 2011/01/11 15:44:35 The behavior is different from EnterExitFrame - v8
antonm 2011/01/11 19:27:40 Zaheer, I am not sure it's something which cannot
Zaheer 2011/01/12 13:20:03 split the code as EnterApiExitFramePrologue/Epilog
+ add(ip, sp, Operand(scratch, LSL, kPointerSizeLog2));
SeRya 2011/01/11 16:34:50 add(ip, sp, Operand(unwind_space * kPointerSize));
Zaheer 2011/01/12 13:20:03 Done
+
+ stm(db_w, sp, fp.bit() | ip.bit() | lr.bit());
+ mov(fp, Operand(sp));
+
+ mov(ip, Operand(CodeObject()));
+ push(ip);
+ push(ip); // Exit Frame pc patched before call
+
+ // create space for the args
+ sub(sp, sp, Operand(arg_stack_space * kPointerSize));
+
+ int frame_alignment = ActivationFrameAlignment();
+ int frame_alignment_mask = frame_alignment - 1;
+ if (frame_alignment > kPointerSize) {
+ mov(scratch, Operand(0));
+ tst(sp, Operand(frame_alignment_mask));
+ push(scratch, nz);
SeRya 2011/01/11 16:34:50 ASSERT(frame_alignment == 2 * kPointerSize);
Zaheer 2011/01/12 13:20:03 Done
+ }
+
+ mov(ip, Operand(ExternalReference(Top::k_c_entry_fp_address)));
SeRya 2011/01/11 16:34:50 ia32 code allocates C arguments below c_entry_fp_a
Zaheer 2011/01/12 13:20:03 i do allocate the args on top of the exit frame si
+ str(fp, MemOperand(ip));
+ mov(ip, Operand(ExternalReference(Top::k_context_address)));
+ str(cp, MemOperand(ip));
+}
+
+
+MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(
+ ApiFunction* function) {
+ ExternalReference next_address =
+ ExternalReference::handle_scope_next_address();
+ ExternalReference limit_address =
+ ExternalReference::handle_scope_limit_address();
+ ExternalReference level_address =
+ ExternalReference::handle_scope_level_address();
+
+ // Allocate HandleScope in callee-save registers.
+ mov(ip, Operand(next_address));
SeRya 2011/01/11 16:34:50 x64 implementation use offsets to eliminate 2 of 3
Zaheer 2011/01/12 13:20:03 Done! but i could remove only the mov not ldr inst
+ ldr(r4, MemOperand(ip));
+ mov(ip, Operand(limit_address));
+ ldr(r5, MemOperand(ip));
+ mov(ip, Operand(level_address));
+ ldr(r6, MemOperand(ip));
+ add(r6, r6, Operand(1));
+ str(r6, MemOperand(ip));
+
+ // patch the exit frame pc and Call the api function!
antonm 2011/01/11 14:11:33 nit: [P]atch and [c]all.
antonm 2011/01/11 14:11:33 once again, can we factor out frame handling?
Zaheer 2011/01/11 15:44:35 Done
Zaheer 2011/01/11 15:44:35 same issues as mentioned before for refactoring
+ add(ip, pc, Operand(8));
+ str(ip, MemOperand(fp, -2 * kPointerSize));
antonm 2011/01/11 14:11:33 do not we have a named constant for -2?
Zaheer 2011/01/11 15:44:35 check ExitFrame::FillState(..) it seems to be hard
+ Call(function->address(), RelocInfo::RUNTIME_ENTRY);
+
+ Label empty_handle;
+ Label prologue;
+ Label promote_scheduled_exception;
+ Label delete_allocated_handles;
+ Label leave_exit_frame;
+
+ // Check if the result handle holds 0.
+ cmp(r0, Operand(0));
+ b(eq, &empty_handle);
+ // It was non-zero. Dereference to get the result value.
+ ldr(r0, MemOperand(r0));
SeRya 2011/01/11 16:34:50 LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
Zaheer 2011/01/12 13:20:03 Done! Thanks for the pointer, it simplifies the co
+ bind(&prologue);
+ // No more valid handles (the result handle was the last one). Restore
+ // previous handle scope.
+ mov(ip, Operand(next_address));
+ str(r4, MemOperand(ip));
+ mov(ip, Operand(level_address));
+ ldr(r6, MemOperand(ip));
+ sub(r6, r6, Operand(1));
+ str(r6, MemOperand(ip));
+ mov(ip, Operand(limit_address));
+ ldr(ip, MemOperand(ip));
+ cmp(r5, ip);
+ b(ne, &delete_allocated_handles);
+
+ // Check if the function scheduled an exception.
+ bind(&leave_exit_frame);
+ mov(ip, Operand(ExternalReference::the_hole_value_location()));
+ ldr(r4, MemOperand(ip));
antonm 2011/01/11 14:11:33 Shouldn't it be LoadRoot(r4, Heap::kTheHoleValueRo
Zaheer 2011/01/11 15:44:35 Done
+ mov(ip, Operand(ExternalReference(Top::k_pending_exception_address)));
+ ldr(r5, MemOperand(ip));
+ cmp(r4, r5);
+ b(ne, &promote_scheduled_exception);
+ LeaveExitFrame(0);
antonm 2011/01/11 14:11:33 LeaveExitFrame apparently takes bool, not int
Zaheer 2011/01/11 15:44:35 done
+
+ bind(&promote_scheduled_exception);
+ MaybeObject* result = TryTailCallExternalReference(
+ ExternalReference(Runtime::kPromoteScheduledException), 0, 1);
+ if (result->IsFailure()) {
+ return result;
+ }
+
+ bind(&empty_handle);
+ // It was zero; the result is undefined.
+ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
+ b(&prologue);
+
+ // HandleScope limit has changed. Delete allocated extensions.
+ bind(&delete_allocated_handles);
+ mov(ip, Operand(limit_address));
+ str(r5, MemOperand(ip));
+ 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 +1776,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 +1803,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) {

Powered by Google App Engine
This is Rietveld 408576698