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

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

Issue 2801008: Port faster callbacks invocation to x64. (Closed)
Patch Set: Minor cosmetic changes Created 10 years, 5 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/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/macro-assembler-x64.cc
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index a5634a794da1650878f50e6f1eb999ac6c22e61c..88f61d4725751b647b3a8b7ad40a156011db2bd5 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -336,12 +336,32 @@ void MacroAssembler::CallStub(CodeStub* stub) {
}
+Object* MacroAssembler::TryCallStub(CodeStub* stub) {
+ ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
+ Object* result = stub->TryGetCode();
+ if (!result->IsFailure()) {
+ call(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET);
+ }
+ return result;
+}
+
+
void MacroAssembler::TailCallStub(CodeStub* stub) {
ASSERT(allow_stub_calls()); // calls are not allowed in some stubs
Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
}
+Object* MacroAssembler::TryTailCallStub(CodeStub* stub) {
+ ASSERT(allow_stub_calls()); // Calls are not allowed in some stubs.
+ Object* result = stub->TryGetCode();
+ if (!result->IsFailure()) {
+ jmp(Handle<Code>(Code::cast(result)), RelocInfo::CODE_TARGET);
+ }
+ return result;
+}
+
+
void MacroAssembler::StubReturn(int argc) {
ASSERT(argc >= 1 && generating_stub());
ret((argc - 1) * kPointerSize);
@@ -361,6 +381,12 @@ void MacroAssembler::CallRuntime(Runtime::FunctionId id, int num_arguments) {
}
+Object* MacroAssembler::TryCallRuntime(Runtime::FunctionId id,
+ int num_arguments) {
+ return TryCallRuntime(Runtime::FunctionForId(id), num_arguments);
+}
+
+
void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
// If the expected number of arguments of the runtime function is
// constant, we check that the actual number of arguments match the
@@ -381,6 +407,26 @@ void MacroAssembler::CallRuntime(Runtime::Function* f, int num_arguments) {
}
+Object* MacroAssembler::TryCallRuntime(Runtime::Function* f,
+ int num_arguments) {
+ if (f->nargs >= 0 && f->nargs != num_arguments) {
+ IllegalOperation(num_arguments);
+ // Since we did not call the stub, there was no allocation failure.
+ // Return some non-failure object.
+ return Heap::undefined_value();
+ }
+
+ // 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.
+ Set(rax, num_arguments);
+ movq(rbx, ExternalReference(f));
+ CEntryStub ces(f->result_size);
+ return TryCallStub(&ces);
+}
+
+
void MacroAssembler::CallExternalReference(const ExternalReference& ext,
int num_arguments) {
Set(rax, num_arguments);
@@ -417,6 +463,87 @@ void MacroAssembler::TailCallRuntime(Runtime::FunctionId fid,
}
+static int Offset(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);
+}
+
+
+void MacroAssembler::PushHandleScope(Register scratch) {
+ ExternalReference extensions_address =
+ ExternalReference::handle_scope_extensions_address();
+ const int kExtensionsOffset = 0;
+ const int kNextOffset = Offset(
+ ExternalReference::handle_scope_next_address(),
+ extensions_address);
+ const int kLimitOffset = Offset(
+ ExternalReference::handle_scope_limit_address(),
+ extensions_address);
+
+ // Push the number of extensions, smi-tagged so the gc will ignore it.
+ movq(kScratchRegister, extensions_address);
+ movq(scratch, Operand(kScratchRegister, kExtensionsOffset));
+ movq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0));
+ Integer32ToSmi(scratch, scratch);
+ push(scratch);
+ // Push next and limit pointers which will be wordsize aligned and
+ // hence automatically smi tagged.
+ push(Operand(kScratchRegister, kNextOffset));
+ push(Operand(kScratchRegister, kLimitOffset));
+}
+
+
+Object* MacroAssembler::PopHandleScopeHelper(Register saved,
+ Register scratch,
+ bool gc_allowed) {
+ ExternalReference extensions_address =
+ ExternalReference::handle_scope_extensions_address();
+ const int kExtensionsOffset = 0;
+ const int kNextOffset = Offset(
+ ExternalReference::handle_scope_next_address(),
+ extensions_address);
+ const int kLimitOffset = Offset(
+ ExternalReference::handle_scope_limit_address(),
+ extensions_address);
+
+ Object* result = NULL;
+ Label write_back;
+ movq(kScratchRegister, extensions_address);
+ cmpq(Operand(kScratchRegister, kExtensionsOffset), Immediate(0));
+ j(equal, &write_back);
+ push(saved);
+ if (gc_allowed) {
+ CallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
+ } else {
+ result = TryCallRuntime(Runtime::kDeleteHandleScopeExtensions, 0);
+ if (result->IsFailure()) return result;
+ }
+ pop(saved);
+ movq(kScratchRegister, extensions_address);
+
+ bind(&write_back);
+ pop(Operand(kScratchRegister, kLimitOffset));
+ pop(Operand(kScratchRegister, kNextOffset));
+ pop(scratch);
+ SmiToInteger32(scratch, scratch);
+ movq(Operand(kScratchRegister, kExtensionsOffset), scratch);
+
+ return result;
+}
+
+
+void MacroAssembler::PopHandleScope(Register saved, Register scratch) {
+ PopHandleScopeHelper(saved, scratch, true);
+}
+
+
+Object* MacroAssembler::TryPopHandleScope(Register saved, Register scratch) {
+ return PopHandleScopeHelper(saved, scratch, false);
+}
+
+
void MacroAssembler::JumpToExternalReference(const ExternalReference& ext,
int result_size) {
// Set the entry point and jump to the C entry runtime stub.
@@ -2208,7 +2335,8 @@ void MacroAssembler::LeaveFrame(StackFrame::Type type) {
}
-void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
+void MacroAssembler::EnterExitFramePrologue(ExitFrame::Mode mode,
+ bool save_rax) {
// Setup the frame structure on the stack.
// All constants are relative to the frame pointer of the exit frame.
ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
@@ -2226,18 +2354,19 @@ void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
// Save the frame pointer and the context in top.
ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
ExternalReference context_address(Top::k_context_address);
- movq(r14, rax); // Backup rax before we use it.
+ if (save_rax) {
+ movq(r14, rax); // Backup rax before we use it.
+ }
movq(rax, rbp);
store_rax(c_entry_fp_address);
movq(rax, rsi);
store_rax(context_address);
+}
- // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
- // so it must be retained across the C-call.
- int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
- lea(r12, Operand(rbp, r14, times_pointer_size, offset));
-
+void MacroAssembler::EnterExitFrameEpilogue(ExitFrame::Mode mode,
+ int result_size,
+ int argc) {
#ifdef ENABLE_DEBUGGER_SUPPORT
// Save the state of all registers to the stack from the memory
// location. This is needed to allow nested break points.
@@ -2258,7 +2387,7 @@ void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
// Reserve space for the Arguments object. The Windows 64-bit ABI
// requires us to pass this structure as a pointer to its location on
// the stack. The structure contains 2 values.
- int argument_stack_space = 2 * kPointerSize;
+ int argument_stack_space = argc * kPointerSize;
// We also need backing space for 4 parameters, even though
// we only pass one or two parameter, and it is in a register.
int argument_mirror_space = 4 * kPointerSize;
@@ -2280,6 +2409,33 @@ void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
}
+void MacroAssembler::EnterExitFrame(ExitFrame::Mode mode, int result_size) {
+ EnterExitFramePrologue(mode, true);
+
+ // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
+ // so it must be retained across the C-call.
+ int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
+ lea(r12, Operand(rbp, r14, times_pointer_size, offset));
+
+ EnterExitFrameEpilogue(mode, result_size, 2);
+}
+
+
+void MacroAssembler::EnterApiExitFrame(ExitFrame::Mode mode,
+ int stack_space,
+ int argc,
+ int result_size) {
+ EnterExitFramePrologue(mode, false);
+
+ // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame,
+ // so it must be retained across the C-call.
+ int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
+ lea(r12, Operand(rbp, (stack_space * kPointerSize) + offset));
+
+ EnterExitFrameEpilogue(mode, result_size, argc);
+}
+
+
void MacroAssembler::LeaveExitFrame(ExitFrame::Mode mode, int result_size) {
// Registers:
// r12 : argv
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/stub-cache-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698