Index: runtime/vm/stub_code_x64.cc |
=================================================================== |
--- runtime/vm/stub_code_x64.cc (revision 33072) |
+++ runtime/vm/stub_code_x64.cc (working copy) |
@@ -1215,160 +1215,6 @@ |
} |
-// Called for inline allocation of closures. |
-// Input parameters: |
-// RSP + 16 : receiver (null if not an implicit instance closure). |
-// RSP + 8 : type arguments object (null if class is not parameterized). |
-// RSP : points to return address. |
-void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, |
- const Function& func) { |
- ASSERT(func.IsClosureFunction()); |
- ASSERT(!func.IsImplicitStaticClosureFunction()); |
- const bool is_implicit_instance_closure = |
- func.IsImplicitInstanceClosureFunction(); |
- const Class& cls = Class::ZoneHandle(func.signature_class()); |
- const bool has_type_arguments = cls.NumTypeArguments() > 0; |
- |
- __ EnterStubFrame(true); // Uses pool pointer to refer to function. |
- __ LoadObject(R12, Object::null_object(), PP); |
- const intptr_t kTypeArgumentsOffset = 4 * kWordSize; |
- const intptr_t kReceiverOffset = 5 * kWordSize; |
- const intptr_t closure_size = Closure::InstanceSize(); |
- const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. |
- if (FLAG_inline_alloc && |
- Heap::IsAllocatableInNewSpace(closure_size + context_size)) { |
- Label slow_case; |
- Heap* heap = Isolate::Current()->heap(); |
- __ movq(RAX, Immediate(heap->TopAddress())); |
- __ movq(RAX, Address(RAX, 0)); |
- __ leaq(R13, Address(RAX, closure_size)); |
- if (is_implicit_instance_closure) { |
- __ movq(RBX, R13); // RBX: new context address. |
- __ addq(R13, Immediate(context_size)); |
- } |
- // Check if the allocation fits into the remaining space. |
- // RAX: potential new closure object. |
- // RBX: potential new context object (only if is_implicit_closure). |
- // R13: potential next object start. |
- __ movq(RDI, Immediate(heap->EndAddress())); |
- __ cmpq(R13, Address(RDI, 0)); |
- if (FLAG_use_slow_path) { |
- __ jmp(&slow_case); |
- } else { |
- __ j(ABOVE_EQUAL, &slow_case); |
- } |
- |
- // Successfully allocated the object, now update top to point to |
- // next object start and initialize the object. |
- __ movq(RDI, Immediate(heap->TopAddress())); |
- __ movq(Address(RDI, 0), R13); |
- |
- // RAX: new closure object. |
- // RBX: new context object (only if is_implicit_closure). |
- if (is_implicit_instance_closure) { |
- // This closure allocates a context, update allocation stats. |
- // RDI: context size. |
- __ movq(RDI, Immediate(context_size)); |
- __ UpdateAllocationStatsWithSize(kContextCid, RDI); |
- } |
- // The closure allocation is attributed to the signature class. |
- __ UpdateAllocationStats(cls.id()); |
- |
- // RAX: new closure object. |
- // RBX: new context object (only if is_implicit_closure). |
- // Set the tags. |
- uword tags = 0; |
- tags = RawObject::SizeTag::update(closure_size, tags); |
- tags = RawObject::ClassIdTag::update(cls.id(), tags); |
- __ movq(Address(RAX, Instance::tags_offset()), Immediate(tags)); |
- |
- // Initialize the function field in the object. |
- // RAX: new closure object. |
- // RBX: new context object (only if is_implicit_closure). |
- // R13: next object start. |
- // Load function of closure to be allocated. |
- __ LoadObject(R10, func, PP); |
- __ movq(Address(RAX, Closure::function_offset()), R10); |
- |
- // Setup the context for this closure. |
- if (is_implicit_instance_closure) { |
- // Initialize the new context capturing the receiver. |
- |
- const Class& context_class = Class::ZoneHandle(Object::context_class()); |
- // Set the tags. |
- uword tags = 0; |
- tags = RawObject::SizeTag::update(context_size, tags); |
- tags = RawObject::ClassIdTag::update(context_class.id(), tags); |
- __ movq(Address(RBX, Context::tags_offset()), Immediate(tags)); |
- |
- // Set number of variables field to 1 (for captured receiver). |
- __ movq(Address(RBX, Context::num_variables_offset()), Immediate(1)); |
- |
- // Set isolate field to isolate of current context. |
- __ movq(R10, FieldAddress(CTX, Context::isolate_offset())); |
- __ movq(Address(RBX, Context::isolate_offset()), R10); |
- |
- // Set the parent to null. |
- __ movq(Address(RBX, Context::parent_offset()), R12); |
- |
- // Initialize the context variable to the receiver. |
- __ movq(R10, Address(RSP, kReceiverOffset)); |
- __ movq(Address(RBX, Context::variable_offset(0)), R10); |
- |
- // Set the newly allocated context in the newly allocated closure. |
- __ addq(RBX, Immediate(kHeapObjectTag)); |
- __ movq(Address(RAX, Closure::context_offset()), RBX); |
- } else { |
- __ movq(Address(RAX, Closure::context_offset()), CTX); |
- } |
- |
- // Set the type arguments field in the newly allocated closure. |
- __ movq(R10, Address(RSP, kTypeArgumentsOffset)); |
- __ movq(Address(RAX, Closure::type_arguments_offset()), R10); |
- |
- // Done allocating and initializing the instance. |
- // RAX: new object. |
- __ addq(RAX, Immediate(kHeapObjectTag)); |
- __ LeaveStubFrame(); |
- __ ret(); |
- |
- __ Bind(&slow_case); |
- } |
- if (has_type_arguments) { |
- __ movq(RCX, Address(RSP, kTypeArgumentsOffset)); |
- } |
- if (is_implicit_instance_closure) { |
- __ movq(RAX, Address(RSP, kReceiverOffset)); |
- } |
- |
- __ pushq(R12); // Setup space on stack for the return value. |
- __ PushObject(func, PP); |
- if (is_implicit_instance_closure) { |
- __ pushq(RAX); // Receiver. |
- } |
- if (has_type_arguments) { |
- __ pushq(RCX); // Push type arguments of closure to be allocated. |
- } else { |
- __ pushq(R12); // Push null type arguments. |
- } |
- if (is_implicit_instance_closure) { |
- __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); |
- __ popq(RAX); // Pop type arguments. |
- __ popq(RAX); // Pop receiver. |
- } else { |
- ASSERT(func.IsNonImplicitClosureFunction()); |
- __ CallRuntime(kAllocateClosureRuntimeEntry, 2); |
- __ popq(RAX); // Pop type arguments. |
- } |
- __ popq(RAX); // Pop the function object. |
- __ popq(RAX); // Pop the result. |
- // RAX: New closure object. |
- // Restore the calling frame. |
- __ LeaveStubFrame(); |
- __ ret(); |
-} |
- |
- |
// Called for invoking "dynamic noSuchMethod(Invocation invocation)" function |
// from the entry code of a dart function after an error in passed argument |
// name or number is detected. |