Index: runtime/vm/stub_code_mips.cc |
=================================================================== |
--- runtime/vm/stub_code_mips.cc (revision 33072) |
+++ runtime/vm/stub_code_mips.cc (working copy) |
@@ -1414,160 +1414,6 @@ |
} |
-// Called for inline allocation of closures. |
-// Input parameters: |
-// RA: 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; |
- |
- __ TraceSimMsg("AllocationStubForClosure"); |
- __ 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(T5, heap->TopAddress()); |
- __ lw(T2, Address(T5)); |
- __ AddImmediate(T3, T2, closure_size); |
- if (is_implicit_instance_closure) { |
- __ mov(T4, T3); // T4: new context address. |
- __ AddImmediate(T3, context_size); |
- } |
- // Check if the allocation fits into the remaining space. |
- // T2: potential new closure object. |
- // T3: address of top of heap. |
- // T4: potential new context object (only if is_implicit_closure). |
- __ LoadImmediate(TMP, heap->EndAddress()); |
- __ lw(CMPRES1, Address(TMP)); |
- if (FLAG_use_slow_path) { |
- __ b(&slow_case); |
- } else { |
- __ BranchUnsignedGreaterEqual(T3, CMPRES1, &slow_case); |
- } |
- |
- // Successfully allocated the object, now update top to point to |
- // next object start and initialize the object. |
- __ sw(T3, Address(T5)); |
- if (is_implicit_instance_closure) { |
- // This closure allocates a context, update allocation stats. |
- // T3: context size. |
- __ LoadImmediate(T3, context_size); |
- // T5: Clobbered. |
- __ UpdateAllocationStatsWithSize(kContextCid, T3, T5); |
- } |
- // The closure allocation is attributed to the signature class. |
- // T5: Will be clobbered. |
- __ UpdateAllocationStats(cls.id(), T5); |
- |
- // T2: new closure object. |
- // T4: 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(T0, tags); |
- __ sw(T0, Address(T2, Instance::tags_offset())); |
- |
- // Initialize the function field in the object. |
- // T2: new closure object. |
- // T4: new context object (only if is_implicit_closure). |
- __ LoadObject(T0, func); // Load function of closure to be allocated. |
- __ sw(T0, Address(T2, 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(T0, tags); |
- __ sw(T0, Address(T4, Context::tags_offset())); |
- |
- // Set number of variables field to 1 (for captured receiver). |
- __ LoadImmediate(T0, 1); |
- __ sw(T0, Address(T4, Context::num_variables_offset())); |
- |
- // Set isolate field to isolate of current context. |
- __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
- __ sw(T0, Address(T4, Context::isolate_offset())); |
- |
- // Set the parent to null. |
- __ LoadImmediate(TMP, reinterpret_cast<intptr_t>(Object::null())); |
- __ sw(TMP, Address(T4, Context::parent_offset())); |
- |
- // Initialize the context variable to the receiver. |
- __ lw(T0, Address(FP, kReceiverFPOffset)); |
- __ sw(T0, Address(T4, Context::variable_offset(0))); |
- |
- // Set the newly allocated context in the newly allocated closure. |
- __ AddImmediate(T1, T4, kHeapObjectTag); |
- __ sw(T1, Address(T2, Closure::context_offset())); |
- } else { |
- __ sw(CTX, Address(T2, Closure::context_offset())); |
- } |
- |
- // Set the type arguments field in the newly allocated closure. |
- __ lw(T0, Address(FP, kTypeArgumentsFPOffset)); |
- __ sw(T0, Address(T2, Closure::type_arguments_offset())); |
- |
- // Done allocating and initializing the instance. |
- // V0: new object. |
- __ addiu(V0, T2, Immediate(kHeapObjectTag)); |
- |
- __ LeaveStubFrameAndReturn(RA); |
- |
- __ Bind(&slow_case); |
- } |
- |
- // If it's an implicit instance closure we need 4 stack slots, o/w only 3. |
- intptr_t num_slots = is_implicit_instance_closure ? 4 : 3; |
- __ addiu(SP, SP, Immediate(-num_slots * kWordSize)); |
- // Setup space on stack for return value. |
- __ LoadImmediate(T7, reinterpret_cast<intptr_t>(Object::null())); |
- __ sw(T7, Address(SP, (num_slots - 1) * kWordSize)); |
- __ LoadObject(TMP, func); |
- __ sw(TMP, Address(SP, (num_slots - 2) * kWordSize)); |
- __ mov(T2, T7); |
- if (is_implicit_instance_closure) { |
- __ lw(T1, Address(FP, kReceiverFPOffset)); |
- __ sw(T1, Address(SP, (num_slots - 3) * kWordSize)); // Receiver. |
- } |
- if (has_type_arguments) { |
- __ lw(T2, Address(FP, kTypeArgumentsFPOffset)); |
- } |
- __ sw(T2, Address(SP, 0 * kWordSize)); |
- |
- if (is_implicit_instance_closure) { |
- __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); |
- __ TraceSimMsg("AllocationStubForClosure return"); |
- } else { |
- ASSERT(func.IsNonImplicitClosureFunction()); |
- __ CallRuntime(kAllocateClosureRuntimeEntry, 2); |
- __ TraceSimMsg("AllocationStubForClosure return"); |
- } |
- __ lw(V0, Address(SP, (num_slots - 1) * kWordSize)); // Pop function object. |
- __ addiu(SP, SP, Immediate(num_slots * kWordSize)); |
- |
- // V0: new object |
- // Restore the frame pointer. |
- __ LeaveStubFrameAndReturn(RA); |
-} |
- |
- |
// 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. |