Index: runtime/vm/stub_code_arm.cc |
=================================================================== |
--- runtime/vm/stub_code_arm.cc (revision 33072) |
+++ runtime/vm/stub_code_arm.cc (working copy) |
@@ -1220,156 +1220,6 @@ |
} |
-// Called for inline allocation of closures. |
-// Input parameters: |
-// LR : return address. |
-// SP + 4 : receiver (null if not an implicit instance closure). |
-// SP + 0 : type arguments object (null if class is no parameterized). |
-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. |
- const intptr_t kTypeArgumentsFPOffset = 3 * kWordSize; |
- const intptr_t kReceiverFPOffset = 4 * 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(); |
- __ LoadImmediate(R5, heap->TopAddress()); |
- __ ldr(R2, Address(R5, 0)); |
- __ AddImmediate(R3, R2, closure_size); |
- if (is_implicit_instance_closure) { |
- __ mov(R4, ShifterOperand(R3)); // R4: new context address. |
- __ AddImmediate(R3, context_size); |
- } |
- // Check if the allocation fits into the remaining space. |
- // R2: potential new closure object. |
- // R3: potential next object start. |
- // R4: potential new context object (only if is_implicit_closure). |
- __ LoadImmediate(IP, heap->EndAddress()); |
- __ ldr(IP, Address(IP, 0)); |
- __ cmp(R3, ShifterOperand(IP)); |
- if (FLAG_use_slow_path) { |
- __ b(&slow_case); |
- } else { |
- __ b(&slow_case, CS); // Branch if unsigned higher or equal. |
- } |
- |
- // Successfully allocated the object, now update top to point to |
- // next object start and initialize the object. |
- __ str(R3, Address(R5, 0)); |
- |
- if (is_implicit_instance_closure) { |
- // This closure allocates a context, update allocation stats. |
- // R3: context size. |
- __ LoadImmediate(R3, context_size); |
- // R5: Clobbered. |
- __ UpdateAllocationStatsWithSize(kContextCid, R3, R5); |
- } |
- // The closure allocation is attributed to the signature class. |
- // R5: Will be clobbered. |
- __ UpdateAllocationStats(cls.id(), R5); |
- |
- // R2: new closure object. |
- // R4: 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); |
- __ LoadImmediate(R0, tags); |
- __ str(R0, Address(R2, Instance::tags_offset())); |
- |
- // Initialize the function field in the object. |
- // R2: new closure object. |
- // R4: new context object (only if is_implicit_closure). |
- __ LoadObject(R0, func); // Load function of closure to be allocated. |
- __ str(R0, Address(R2, Closure::function_offset())); |
- |
- // 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); |
- __ LoadImmediate(R0, tags); |
- __ str(R0, Address(R4, Context::tags_offset())); |
- |
- // Set number of variables field to 1 (for captured receiver). |
- __ LoadImmediate(R0, 1); |
- __ str(R0, Address(R4, Context::num_variables_offset())); |
- |
- // Set isolate field to isolate of current context. |
- __ ldr(R0, FieldAddress(CTX, Context::isolate_offset())); |
- __ str(R0, Address(R4, Context::isolate_offset())); |
- |
- // Set the parent to null. |
- __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
- __ str(R0, Address(R4, Context::parent_offset())); |
- |
- // Initialize the context variable to the receiver. |
- __ ldr(R0, Address(FP, kReceiverFPOffset)); |
- __ str(R0, Address(R4, Context::variable_offset(0))); |
- |
- // Set the newly allocated context in the newly allocated closure. |
- __ add(R1, R4, ShifterOperand(kHeapObjectTag)); |
- __ str(R1, Address(R2, Closure::context_offset())); |
- } else { |
- __ str(CTX, Address(R2, Closure::context_offset())); |
- } |
- |
- // Set the type arguments field in the newly allocated closure. |
- __ ldr(R0, Address(FP, kTypeArgumentsFPOffset)); |
- __ str(R0, Address(R2, Closure::type_arguments_offset())); |
- |
- // Done allocating and initializing the instance. |
- // R2: new object still missing its heap tag. |
- __ add(R0, R2, ShifterOperand(kHeapObjectTag)); |
- // R0: new object. |
- __ LeaveStubFrame(); |
- __ Ret(); |
- |
- __ Bind(&slow_case); |
- } |
- __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); |
- __ Push(R0); // Setup space on stack for return value. |
- __ PushObject(func); |
- if (is_implicit_instance_closure) { |
- __ ldr(R1, Address(FP, kReceiverFPOffset)); |
- __ Push(R1); // Receiver. |
- } |
- // R0: raw null. |
- if (has_type_arguments) { |
- __ ldr(R0, Address(FP, kTypeArgumentsFPOffset)); |
- } |
- __ Push(R0); // Push type arguments of closure to be allocated or null. |
- |
- if (is_implicit_instance_closure) { |
- __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); |
- __ Drop(2); // Pop arguments (type arguments of object and receiver). |
- } else { |
- ASSERT(func.IsNonImplicitClosureFunction()); |
- __ CallRuntime(kAllocateClosureRuntimeEntry, 2); |
- __ Drop(1); // Pop argument (type arguments of object). |
- } |
- __ Drop(1); // Pop function object. |
- __ Pop(R0); |
- // R0: new object |
- // Restore the frame pointer. |
- __ 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. |