Chromium Code Reviews| Index: runtime/vm/stub_code_ia32.cc |
| =================================================================== |
| --- runtime/vm/stub_code_ia32.cc (revision 403) |
| +++ runtime/vm/stub_code_ia32.cc (working copy) |
| @@ -1242,12 +1242,12 @@ |
| // Called for inline allocation of closures. |
| // Input parameters: |
| -// ESP + 4 : receiver (only if non-static implicit closure). |
| +// ESP + 8 : receiver (only if implicit instance closure). |
| +// ESP + 4 : type arguments object (only if signature class is parameterized). |
| // ESP : points to return address. |
|
siva
2011/10/13 20:52:21
if signature class is not parameterized ESP + 4 w
regis
2011/10/13 21:33:46
Done.
|
| // Uses EAX, EBX, ECX, EDX as temporary registers. |
| void StubCode::GenerateAllocationStubForClosure(Assembler* assembler, |
| const Function& func) { |
| - const intptr_t kReceiverOffset = 1 * kWordSize; |
| const Immediate raw_null = |
| Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| ASSERT(func.IsClosureFunction()); |
| @@ -1255,11 +1255,14 @@ |
| func.IsImplicitStaticClosureFunction(); |
| const bool is_implicit_instance_closure = |
| func.IsImplicitInstanceClosureFunction(); |
| + const Class& cls = Class::ZoneHandle(func.signature_class()); |
| + const bool is_cls_parameterized = cls.IsParameterized(); |
| + const intptr_t kTypeArgumentsOffset = 1 * kWordSize; |
| + const intptr_t kReceiverOffset = (is_cls_parameterized ? 2 : 1) * kWordSize; |
| const intptr_t closure_size = Closure::InstanceSize(); |
| const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. |
| if (FLAG_inline_alloc && |
| PageSpace::IsPageAllocatableSize(closure_size + context_size)) { |
| - const Class& cls = Class::ZoneHandle(func.signature_class()); |
| Label slow_case; |
| Heap* heap = Isolate::Current()->heap(); |
| __ movl(EAX, Address::Absolute(heap->TopAddress())); |
| @@ -1327,11 +1330,20 @@ |
| } else { |
| __ movl(Address(EAX, Closure::context_offset()), CTX); |
| } |
| + |
| + // Set the type arguments field in the newly allocated closure. |
| + if (is_cls_parameterized) { |
| + ASSERT(!is_implicit_static_closure); |
| + // Use the passed-in type arguments. |
| + __ movl(EDX, Address(ESP, kTypeArgumentsOffset)); |
| + __ movl(Address(EAX, Closure::type_arguments_offset()), EDX); |
| + } else { |
| + // Set to null. |
| + __ movl(Address(EAX, Closure::type_arguments_offset()), raw_null); |
| + } |
| + |
| __ movl(Address(EAX, Closure::smrck_offset()), raw_null); |
| - // TODO(regis): Store the actual type arguments. |
| - __ movl(Address(EAX, Closure::type_arguments_offset()), raw_null); |
| - |
| // Done allocating and initializing the instance. |
| // EAX: new object. |
| __ addl(EAX, Immediate(kHeapObjectTag)); |
| @@ -1339,6 +1351,9 @@ |
| __ Bind(&slow_case); |
| } |
| + if (is_cls_parameterized) { |
| + __ movl(ECX, Address(ESP, kTypeArgumentsOffset)); |
| + } |
| if (is_implicit_instance_closure) { |
| __ movl(EAX, Address(ESP, kReceiverOffset)); |
| } |
| @@ -1347,6 +1362,11 @@ |
| const Closure& new_closure = Closure::ZoneHandle(); |
| __ PushObject(new_closure); // Push Null closure for return value. |
| __ PushObject(func); |
| + if (is_cls_parameterized) { |
| + __ pushl(ECX); // Push type arguments of closure to be allocated. |
| + } else { |
| + __ PushObject(TypeArguments::ZoneHandle()); // Push null type arguments. |
|
siva
2011/10/13 20:52:21
why not use pushl(raw_null) here?
regis
2011/10/13 21:33:46
Done here and at some other locations.
|
| + } |
| if (is_implicit_static_closure) { |
| __ CallRuntimeFromStub(kAllocateImplicitStaticClosureRuntimeEntry); |
| } else if (is_implicit_instance_closure) { |
| @@ -1357,6 +1377,7 @@ |
| ASSERT(func.IsNonImplicitClosureFunction()); |
| __ CallRuntimeFromStub(kAllocateClosureRuntimeEntry); |
| } |
| + __ popl(EAX); // Pop argument (type arguments of object). |
| __ popl(EAX); // Pop function object. |
| __ popl(EAX); |
| // EAX: new object |
| @@ -1393,7 +1414,6 @@ |
| __ EnterFrame(0); |
| // Setup space for return value on stack by pushing smi 0. |
| - // TODO(regis): Why are we using smi 0 instead of raw_null in stubs? |
| __ pushl(Immediate(0)); // Result from noSuchMethod. |
| __ pushl(EAX); // Receiver. |
| __ pushl(ECX); // Function name. |