Index: runtime/vm/stub_code_ia32.cc |
=================================================================== |
--- runtime/vm/stub_code_ia32.cc (revision 33072) |
+++ runtime/vm/stub_code_ia32.cc (working copy) |
@@ -1222,159 +1222,6 @@ |
} |
-// TODO(regis): This stub is not called anymore to allocate regular closures, |
-// but only implicit instance closures. Simplify. |
- |
-// Called for inline allocation of closures. |
-// Input parameters: |
-// ESP + 8 : receiver (null if not an implicit instance closure). |
-// ESP + 4 : type arguments object (null if class is no parameterized). |
-// ESP : points to return address. |
-// Uses EAX, EBX, ECX, EDX as temporary registers. |
-void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, |
- const Function& func) { |
- const Immediate& raw_null = |
- Immediate(reinterpret_cast<intptr_t>(Object::null())); |
- 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; |
- const intptr_t kTypeArgumentsOffset = 1 * kWordSize; |
- const intptr_t kReceiverOffset = 2 * 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(); |
- __ movl(EAX, Address::Absolute(heap->TopAddress())); |
- __ leal(EBX, Address(EAX, closure_size)); |
- if (is_implicit_instance_closure) { |
- __ movl(ECX, EBX); // ECX: new context address. |
- __ addl(EBX, Immediate(context_size)); |
- } |
- // Check if the allocation fits into the remaining space. |
- // EAX: potential new closure object. |
- // ECX: potential new context object (only if is_implicit_closure). |
- // EBX: potential next object start. |
- __ cmpl(EBX, Address::Absolute(heap->EndAddress())); |
- if (FLAG_use_slow_path) { |
- __ jmp(&slow_case); |
- } else { |
- __ j(ABOVE_EQUAL, &slow_case, Assembler::kNearJump); |
- } |
- |
- // Successfully allocated the object, now update top to point to |
- // next object start and initialize the object. |
- __ movl(Address::Absolute(heap->TopAddress()), EBX); |
- // EAX: new closure object. |
- // ECX: new context object (only if is_implicit_closure). |
- if (is_implicit_instance_closure) { |
- // This closure allocates a context, update allocation stats. |
- // EBX: context size. |
- __ movl(EBX, Immediate(context_size)); |
- // EDX: Clobbered. |
- __ UpdateAllocationStatsWithSize(kContextCid, EBX, EDX); |
- } |
- // The closure allocation is attributed to the signature class. |
- // EDX: Will be clobbered. |
- __ UpdateAllocationStats(cls.id(), EDX); |
- |
- // EAX: new closure object. |
- // ECX: 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); |
- __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); |
- |
- // Initialize the function field in the object. |
- // EAX: new closure object. |
- // ECX: new context object (only if is_implicit_closure). |
- __ LoadObject(EDX, func); // Load function of closure to be allocated. |
- __ movl(Address(EAX, Closure::function_offset()), EDX); |
- |
- // 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); |
- __ movl(Address(ECX, Context::tags_offset()), Immediate(tags)); |
- |
- // Set number of variables field to 1 (for captured receiver). |
- __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1)); |
- |
- // Set isolate field to isolate of current context. |
- __ movl(EDX, FieldAddress(CTX, Context::isolate_offset())); |
- __ movl(Address(ECX, Context::isolate_offset()), EDX); |
- |
- // Set the parent to null. |
- __ movl(Address(ECX, Context::parent_offset()), raw_null); |
- |
- // Initialize the context variable to the receiver. |
- __ movl(EDX, Address(ESP, kReceiverOffset)); |
- __ movl(Address(ECX, Context::variable_offset(0)), EDX); |
- |
- // Set the newly allocated context in the newly allocated closure. |
- __ addl(ECX, Immediate(kHeapObjectTag)); |
- __ movl(Address(EAX, Closure::context_offset()), ECX); |
- } else { |
- __ movl(Address(EAX, Closure::context_offset()), CTX); |
- } |
- |
- // Set the type arguments field in the newly allocated closure. |
- __ movl(EDX, Address(ESP, kTypeArgumentsOffset)); |
- __ movl(Address(EAX, Closure::type_arguments_offset()), EDX); |
- |
- // Done allocating and initializing the instance. |
- // EAX: new object. |
- __ addl(EAX, Immediate(kHeapObjectTag)); |
- __ ret(); |
- |
- __ Bind(&slow_case); |
- } |
- if (has_type_arguments) { |
- __ movl(ECX, Address(ESP, kTypeArgumentsOffset)); |
- } |
- if (is_implicit_instance_closure) { |
- __ movl(EAX, Address(ESP, kReceiverOffset)); |
- } |
- // Create a stub frame as we are pushing some objects on the stack before |
- // calling into the runtime. |
- __ EnterStubFrame(); |
- __ pushl(raw_null); // Setup space on stack for return value. |
- __ PushObject(func); |
- if (is_implicit_instance_closure) { |
- __ pushl(EAX); // Receiver. |
- } |
- if (has_type_arguments) { |
- __ pushl(ECX); // Push type arguments of closure to be allocated. |
- } else { |
- __ pushl(raw_null); // Push null type arguments. |
- } |
- if (is_implicit_instance_closure) { |
- __ CallRuntime(kAllocateImplicitInstanceClosureRuntimeEntry, 3); |
- __ popl(EAX); // Pop argument (type arguments of object). |
- __ popl(EAX); // Pop receiver. |
- } else { |
- ASSERT(func.IsNonImplicitClosureFunction()); |
- __ CallRuntime(kAllocateClosureRuntimeEntry, 2); |
- __ popl(EAX); // Pop argument (type arguments of object). |
- } |
- __ popl(EAX); // Pop function object. |
- __ popl(EAX); |
- // EAX: new object |
- // Restore the frame pointer. |
- __ LeaveFrame(); |
- __ 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. |