| Index: src/ia32/lithium-ia32.cc | 
| diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc | 
| index 8c8103f61996e9f9a4604dc32a7ce3f4c4b39066..0a6b8d5bbf7446bd5985bc621fddd3c0f6607f06 100644 | 
| --- a/src/ia32/lithium-ia32.cc | 
| +++ b/src/ia32/lithium-ia32.cc | 
| @@ -663,8 +663,10 @@ LInstruction* LChunkBuilder::DefineFixedDouble( | 
| LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { | 
| HEnvironment* hydrogen_env = current_block_->last_environment(); | 
| int argument_index_accumulator = 0; | 
| +  ZoneList<HValue*> objects_to_materialize(0, zone()); | 
| instr->set_environment(CreateEnvironment(hydrogen_env, | 
| -                                           &argument_index_accumulator)); | 
| +                                           &argument_index_accumulator, | 
| +                                           &objects_to_materialize)); | 
| return instr; | 
| } | 
|  | 
| @@ -971,11 +973,13 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { | 
|  | 
| LEnvironment* LChunkBuilder::CreateEnvironment( | 
| HEnvironment* hydrogen_env, | 
| -    int* argument_index_accumulator) { | 
| +    int* argument_index_accumulator, | 
| +    ZoneList<HValue*>* objects_to_materialize) { | 
| if (hydrogen_env == NULL) return NULL; | 
|  | 
| -  LEnvironment* outer = | 
| -      CreateEnvironment(hydrogen_env->outer(), argument_index_accumulator); | 
| +  LEnvironment* outer = CreateEnvironment(hydrogen_env->outer(), | 
| +                                          argument_index_accumulator, | 
| +                                          objects_to_materialize); | 
| BailoutId ast_id = hydrogen_env->ast_id(); | 
| ASSERT(!ast_id.IsNone() || | 
| hydrogen_env->frame_type() != JS_FUNCTION); | 
| @@ -990,16 +994,16 @@ LEnvironment* LChunkBuilder::CreateEnvironment( | 
| outer, | 
| hydrogen_env->entry(), | 
| zone()); | 
| -  bool needs_arguments_object_materialization = false; | 
| int argument_index = *argument_index_accumulator; | 
| +  int object_index = objects_to_materialize->length(); | 
| for (int i = 0; i < hydrogen_env->length(); ++i) { | 
| if (hydrogen_env->is_special_index(i)) continue; | 
|  | 
| +    LOperand* op; | 
| HValue* value = hydrogen_env->values()->at(i); | 
| -    LOperand* op = NULL; | 
| -    if (value->IsArgumentsObject()) { | 
| -      needs_arguments_object_materialization = true; | 
| -      op = NULL; | 
| +    if (value->IsArgumentsObject() || value->IsCapturedObject()) { | 
| +      objects_to_materialize->Add(value, zone()); | 
| +      op = LEnvironment::materialization_marker(); | 
| } else if (value->IsPushArgument()) { | 
| op = new(zone()) LArgument(argument_index++); | 
| } else { | 
| @@ -1010,15 +1014,33 @@ LEnvironment* LChunkBuilder::CreateEnvironment( | 
| value->CheckFlag(HInstruction::kUint32)); | 
| } | 
|  | 
| -  if (needs_arguments_object_materialization) { | 
| -    HArgumentsObject* arguments = hydrogen_env->entry() == NULL | 
| -        ? graph()->GetArgumentsObject() | 
| -        : hydrogen_env->entry()->arguments_object(); | 
| -    ASSERT(arguments->IsLinked()); | 
| -    for (int i = 1; i < arguments->arguments_count(); ++i) { | 
| -      HValue* value = arguments->arguments_values()->at(i); | 
| -      ASSERT(!value->IsArgumentsObject() && !value->IsPushArgument()); | 
| -      LOperand* op = UseAny(value); | 
| +  for (int i = object_index; i < objects_to_materialize->length(); ++i) { | 
| +    HValue* object_to_materialize = objects_to_materialize->at(i); | 
| +    int previously_materialized_object = -1; | 
| +    for (int prev = 0; prev < i; ++prev) { | 
| +      if (objects_to_materialize->at(prev) == objects_to_materialize->at(i)) { | 
| +        previously_materialized_object = prev; | 
| +        break; | 
| +      } | 
| +    } | 
| +    int length = object_to_materialize->OperandCount(); | 
| +    bool is_arguments = object_to_materialize->IsArgumentsObject(); | 
| +    if (previously_materialized_object >= 0) { | 
| +      result->AddDuplicateObject(previously_materialized_object); | 
| +      continue; | 
| +    } else { | 
| +      result->AddNewObject(is_arguments ? length - 1 : length, is_arguments); | 
| +    } | 
| +    for (int i = is_arguments ? 1 : 0; i < length; ++i) { | 
| +      LOperand* op; | 
| +      HValue* value = object_to_materialize->OperandAt(i); | 
| +      if (value->IsArgumentsObject() || value->IsCapturedObject()) { | 
| +        objects_to_materialize->Add(value, zone()); | 
| +        op = LEnvironment::materialization_marker(); | 
| +      } else { | 
| +        ASSERT(!value->IsPushArgument()); | 
| +        op = UseAny(value); | 
| +      } | 
| result->AddValue(op, | 
| value->representation(), | 
| value->CheckFlag(HInstruction::kUint32)); | 
| @@ -2623,6 +2645,12 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { | 
| } | 
|  | 
|  | 
| +LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) { | 
| +  // There are no real uses of a captured object. | 
| +  return NULL; | 
| +} | 
| + | 
| + | 
| LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { | 
| info()->MarkAsRequiresFrame(); | 
| LOperand* args = UseRegister(instr->arguments()); | 
|  |