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

Unified Diff: runtime/vm/stub_code_x64.cc

Issue 9114054: Port a couple more stubs to x64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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: runtime/vm/stub_code_x64.cc
===================================================================
--- runtime/vm/stub_code_x64.cc (revision 3170)
+++ runtime/vm/stub_code_x64.cc (working copy)
@@ -676,7 +676,7 @@
// R10: Array length as Smi.
{
Label size_tag_overflow, done;
- __ leaq(RBX, Address(R10, TIMES_2, fixed_size)); // R10 is Smi.
+ __ leaq(RBX, Address(R10, TIMES_4, fixed_size)); // R10 is Smi.
ASSERT(kSmiTagShift == 1);
__ andq(RBX, Immediate(-kObjectAlignment));
__ cmpq(RBX, Immediate(RawObject::SizeTag::kMaxSizeTag));
@@ -730,8 +730,102 @@
}
+// Input parameters:
+// R10: Arguments descriptor array (num_args is first Smi element, closure
+// object is not included in num_args).
+// Note: The closure object is pushed before the first argument to the function
+// being called, the stub accesses the closure from this location directly
+// when setting up the context and resolving the entry point.
+// Uses R13.
void StubCode::GenerateCallClosureFunctionStub(Assembler* assembler) {
- __ Unimplemented("CallClosureFunction stub");
+ const Immediate raw_null =
+ Immediate(reinterpret_cast<intptr_t>(Object::null()));
+
+ // Total number of args is the first Smi in args descriptor array (R10).
+ __ movq(RAX, FieldAddress(R10, Array::data_offset())); // Load num_args.
+ // Load closure object in R13.
+ __ movq(R13, Address(RSP, RAX, TIMES_4, kWordSize)); // RAX is a Smi.
+
+ // Verify that R13 is a closure by checking its class.
+ Label not_closure;
+ __ cmpq(R13, raw_null);
+ // Not a closure, but null object.
+ __ j(EQUAL, &not_closure, Assembler::kNearJump);
+ __ testq(R13, Immediate(kSmiTagMask));
+ __ j(ZERO, &not_closure, Assembler::kNearJump); // Not a closure, but a smi.
+ // Verify that the class of the object is a closure class by checking that
+ // class.signature_function() is not null.
+ __ movq(RAX, FieldAddress(R13, Object::class_offset()));
+ __ movq(RAX, FieldAddress(RAX, Class::signature_function_offset()));
+ __ cmpq(RAX, raw_null);
+ // Actual class is not a closure class.
+ __ j(EQUAL, &not_closure, Assembler::kNearJump);
+
+ // RAX is just the signature function. Load the actual closure function.
+ __ movq(RBX, FieldAddress(R13, Closure::function_offset()));
+
+ // Load closure context in CTX; note that CTX has already been preserved.
+ __ movq(CTX, FieldAddress(R13, Closure::context_offset()));
+
+ // Load closure function code in RAX.
+ __ movq(RAX, FieldAddress(RBX, Function::code_offset()));
+ __ cmpq(RAX, raw_null);
+ Label function_compiled;
+ __ j(NOT_EQUAL, &function_compiled, Assembler::kNearJump);
+
+ // Create a stub frame as we are pushing some objects on the stack before
+ // calling into the runtime.
+ __ EnterFrame(0);
+
+ __ pushq(R10); // Preserve arguments descriptor array.
+ __ pushq(RBX);
+ __ CallRuntimeFromStub(kCompileFunctionRuntimeEntry);
+ __ popq(RBX); // Restore read-only function object argument in RBX.
+ __ popq(R10); // Restore arguments descriptor array.
+ // Restore RAX.
+ __ movq(RAX, FieldAddress(RBX, Function::code_offset()));
+
+ // Remove the stub frame as we are about to jump to the closure function.
+ __ LeaveFrame();
+
+ __ Bind(&function_compiled);
+ // RAX: Code.
+ // RBX: Function.
+ // R10: Arguments descriptor array (num_args is first Smi element).
+
+ __ movq(RBX, FieldAddress(RAX, Code::instructions_offset()));
+ __ addq(RBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
+ __ jmp(RBX);
+
+ __ Bind(&not_closure);
+ // Call runtime to report that a closure call was attempted on a non-closure
+ // object, passing the non-closure object and its arguments array.
+ // R13: non-closure object.
+ // R10: arguments descriptor array (num_args is first Smi element, closure
+ // object is not included in num_args).
+
+ // Create a stub frame as we are pushing some objects on the stack before
+ // calling into the runtime.
+ __ EnterFrame(0);
+
+ __ pushq(raw_null); // Setup space on stack for result from error reporting.
+ __ pushq(R13); // Non-closure object.
+ // Total number of args is the first Smi in args descriptor array (R10).
+ __ movq(R13, FieldAddress(R10, Array::data_offset())); // Load num_args.
+ __ SmiUntag(R13);
+ // See stack layout below explaining "wordSize * 4" offset.
+ PushArgumentsArray(assembler, (kWordSize * 4));
+
+ // Stack:
+ // TOS + 0: Argument array.
+ // TOS + 1: Non-closure object.
+ // TOS + 2: Place for result from reporting the error.
+ // TOS + 3: Saved RBP of previous frame. <== RBP
+ // TOS + 4: Dart code return address
+ // TOS + 5: Last argument of caller.
+ // ....
+ __ CallRuntimeFromStub(kReportObjectNotClosureRuntimeEntry);
+ __ Stop("runtime call throws an exception");
}
@@ -853,10 +947,9 @@
// Called for inline allocation of contexts.
// Input:
-// RDX: number of context variables.
+// R10: number of context variables.
// Output:
// RAX: new allocated RawContext object.
-// RBX and RDX are destroyed.
void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
const Immediate raw_null =
Immediate(reinterpret_cast<intptr_t>(Object::null()));
@@ -867,8 +960,8 @@
// Create the stub frame.
__ EnterFrame(0);
__ pushq(raw_null); // Setup space on stack for the return value.
- __ SmiTag(RDX);
- __ pushq(RDX); // Push number of context variables.
+ __ SmiTag(R10);
+ __ pushq(R10); // Push number of context variables.
__ CallRuntimeFromStub(kAllocateContextRuntimeEntry); // Allocate context.
__ popq(RAX); // Pop number of context variables argument.
__ popq(RAX); // Pop the new context object.
@@ -879,8 +972,6 @@
}
-
-
// Called for inline allocation of objects.
// Input parameters:
// RSP + 16 : type arguments object (only if class is parameterized).
@@ -1141,11 +1232,68 @@
}
+// Called for invoking noSuchMethod function from the entry code of a dart
+// function after an error in passed named arguments is detected.
+// Input parameters:
+// RBP : points to previous frame pointer.
+// RBP + 8 : points to return address.
+// RBP + 16 : address of last argument (arg n-1).
+// RBP + 16 + 8*(n-1) : address of first argument (arg 0).
+// RBX : ic-data array.
+// R10 : arguments descriptor array.
void StubCode::GenerateCallNoSuchMethodFunctionStub(Assembler* assembler) {
- __ Unimplemented("CallNoSuchMethodFunction stub");
+ // The target function was not found, so invoke method
+ // "void noSuchMethod(function_name, Array arguments)".
+ // TODO(regis): For now, we simply pass the actual arguments, both positional
+ // and named, as the argument array. This is not correct if out-of-order
+ // named arguments were passed.
+ // The signature of the "noSuchMethod" method has to change from
+ // noSuchMethod(String name, Array arguments) to something like
+ // noSuchMethod(InvocationMirror call).
+ // Also, the class NoSuchMethodException has to be modified accordingly.
+ // Total number of args is the first Smi in args descriptor array (R10).
+ const Immediate raw_null =
+ Immediate(reinterpret_cast<intptr_t>(Object::null()));
+ __ movq(R13, FieldAddress(R10, Array::data_offset())); // R13 is Smi.
+ __ movq(RAX, Address(RBP, R13, TIMES_4, kWordSize)); // Get receiver.
+
+ __ EnterFrame(0);
+ __ pushq(raw_null); // Setup space on stack for result from noSuchMethod.
+ __ pushq(RAX); // Receiver.
+ __ pushq(RBX); // IC data array.
+ __ pushq(R10); // Arguments descriptor array.
+ __ SmiUntag(R13);
+ __ subq(R13, Immediate(1)); // Arguments array length, minus the receiver.
+ // See stack layout below explaining "wordSize * 8" offset.
+ PushArgumentsArray(assembler, (kWordSize * 8));
+
+ // Stack:
+ // TOS + 0: Argument array.
+ // TOS + 1: Arguments descriptor array.
+ // TOS + 2: Ic-data array.
+ // TOS + 3: Receiver.
+ // TOS + 4: Place for result from noSuchMethod.
+ // TOS + 5: Saved RBP of previous frame. <== RBP
+ // TOS + 6: Dart callee (or stub) code return address
+ // TOS + 7: Saved RBP of dart caller frame.
+ // TOS + 8: Dart caller code return address
+ // TOS + 9: Last argument of caller.
+ // ....
+ __ CallRuntimeFromStub(kInvokeNoSuchMethodFunctionRuntimeEntry);
+ // Remove arguments.
+ __ popq(RAX);
+ __ popq(RAX);
+ __ popq(RAX);
+ __ popq(RAX);
+ __ popq(RAX); // Get result into RAX.
+
+ // Remove the stub frame as we are about to return.
+ __ LeaveFrame();
+ __ ret();
}
+
// Generate inline cache check for 'num_args'.
// RBX: Inline cache data array.
// R10: Arguments array.

Powered by Google App Engine
This is Rietveld 408576698