Chromium Code Reviews| Index: runtime/vm/code_generator_ia32.cc |
| diff --git a/runtime/vm/code_generator_ia32.cc b/runtime/vm/code_generator_ia32.cc |
| index 0808f1154df70040672e573f1d424ad86a3db458..f2cf0f192fe1f3e20edb668bb516de31fe820a11 100644 |
| --- a/runtime/vm/code_generator_ia32.cc |
| +++ b/runtime/vm/code_generator_ia32.cc |
| @@ -356,44 +356,14 @@ void CodeGenerator::GenerateEntryCode() { |
| LocalScope* scope = parsed_function_.node_sequence()->scope(); |
| const int num_fixed_params = function.num_fixed_parameters(); |
| const int num_opt_params = function.num_optional_parameters(); |
| - const int num_params = num_fixed_params + num_opt_params; |
| - int first_param_index; |
| - int first_local_index; |
| - int num_copied_params; |
| - // Assign indices to parameters and locals. |
| - if (num_params == num_fixed_params) { |
| - // No need to copy incoming arguments. |
| - // The body of the function will access parameter i at fp[1 + num_fixed - i] |
| - // and local variable j at fp[-1 - j]. |
| - first_param_index = 1 + num_params; |
| - first_local_index = -1; |
| - num_copied_params = 0; |
| - } else { |
| - // The body of the function will access copied parameter i at fp[-1 - i] |
| - // and local j at fp[-1 - num_params - j]. |
| - first_param_index = -1; |
| - first_local_index = -1 - num_params; |
| - num_copied_params = num_params; |
| - ASSERT(num_copied_params > 0); |
| - } |
| - |
| - // Allocate parameters and local variables, either in the local frame or in |
| - // the context(s). |
| - LocalScope* context_owner = NULL; // No context needed so far. |
| - int first_free_frame_index = |
| - scope->AllocateVariables(first_param_index, |
| - num_params, |
| - first_local_index, |
| - scope, // Initial loop owner. |
| - &context_owner); |
| - // Frame indices are relative to the frame pointer and are decreasing. |
| - ASSERT(first_free_frame_index <= first_local_index); |
| - const int num_locals = first_local_index - first_free_frame_index; |
| + const int num_copied_params = parsed_function_.copied_parameter_count(); |
| + const int stack_slot_count = |
| + num_copied_params + parsed_function_.local_count(); |
| + set_locals_space_size(stack_slot_count * kWordSize); |
| // Reserve local space for copied incoming and default arguments and locals. |
| // TODO(regis): We may give up reserving space on stack for args/locals |
| // because pushes of initial values may be more effective than moves. |
| - set_locals_space_size((num_copied_params + num_locals) * kWordSize); |
| __ EnterFrame(locals_space_size()); |
| // We check the number of passed arguments when we have to copy them due to |
| @@ -432,11 +402,12 @@ void CodeGenerator::GenerateEntryCode() { |
| __ Bind(&argc_in_range); |
| } |
| } else { |
| - ASSERT(first_param_index == -1); |
| + ASSERT(parsed_function_.first_parameter_index() == -1); |
| // Copy positional arguments. |
| // Check that no fewer than num_fixed_params positional arguments are passed |
| // in and that no more than num_params arguments are passed in. |
| // Passed argument i at fp[1 + argc - i] copied to fp[-1 - i]. |
| + const int num_params = num_fixed_params + num_opt_params; |
| // Total number of args is the first Smi in args descriptor array (EDX). |
| __ movl(EBX, FieldAddress(EDX, Array::data_offset())); |
| @@ -606,11 +577,12 @@ void CodeGenerator::GenerateEntryCode() { |
| // TODO(regis): For now, always unroll the init loop. Decide later above |
| // which threshold to implement a loop. |
| // Consider emitting pushes instead of moves. |
| - for (int index = first_local_index; index > first_free_frame_index; index--) { |
| - if (index == first_local_index) { |
| + const int base = parsed_function_.first_local_index(); |
| + for (int index = 0; index < parsed_function_.local_count(); ++index) { |
| + if (index == 0) { |
| __ movl(EAX, raw_null); |
| } |
| - __ movl(Address(EBP, index * kWordSize), EAX); |
| + __ movl(Address(EBP, (base - index) * kWordSize), EAX); |
| } |
| // Generate stack overflow check. |
| @@ -765,19 +737,20 @@ void CodeGenerator::VisitAssignableNode(AssignableNode* node) { |
| void CodeGenerator::VisitClosureNode(ClosureNode* node) { |
| const Function& function = node->function(); |
| - if (function.IsNonImplicitClosureFunction()) { |
| + if (function.IsNonImplicitClosureFunction() && |
| + (function.context_scope() == ContextScope::null())) { |
|
srdjan
2012/03/12 18:35:23
Why the changed condition? Previously we did not g
Kevin Millikin (Google)
2012/03/13 08:59:50
Now we can have both IsNonImplicitClosureFunction(
|
| const int current_context_level = state()->context_level(); |
| const ContextScope& context_scope = ContextScope::ZoneHandle( |
| node->scope()->PreserveOuterScope(current_context_level)); |
| ASSERT(!function.HasCode()); |
| - ASSERT(function.context_scope() == ContextScope::null()); |
| function.set_context_scope(context_scope); |
| } else { |
| - ASSERT(function.context_scope() != ContextScope::null()); |
| if (function.IsImplicitInstanceClosureFunction()) { |
| node->receiver()->Visit(this); |
| } |
| } |
| + ASSERT(function.context_scope() != ContextScope::null()); |
| + |
| // The function type of a closure may have type arguments. In that case, pass |
| // the type arguments of the instantiator. |
| const Class& cls = Class::Handle(function.signature_class()); |