| Index: src/mips/lithium-mips.cc
|
| diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
|
| index 300c0c6cc7826c23d91d102dc72ac698a7a09357..67bb7a6cb4c43e0043b063416e811dc56c8d2ca3 100644
|
| --- a/src/mips/lithium-mips.cc
|
| +++ b/src/mips/lithium-mips.cc
|
| @@ -598,8 +598,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;
|
| }
|
|
|
| @@ -903,11 +905,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);
|
| @@ -922,16 +926,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 {
|
| @@ -942,15 +946,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));
|
| @@ -2358,6 +2380,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());
|
|
|