break;
}
+ int object_index = 0;
+ int dematerialized_index = 0;
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
-
- // TODO(mstarzinger): Introduce marker operands to indicate that this value
- // is not present and must be reconstructed from the deoptimizer. Currently
- // this is only used for the arguments object.
- if (value == NULL) {
- int arguments_count = environment->values()->length() - translation_size;
- translation->BeginArgumentsObject(arguments_count);
- for (int i = 0; i < arguments_count; ++i) {
- LOperand* value = environment->values()->at(translation_size + i);
- AddToTranslation(translation,
- value,
- environment->HasTaggedValueAt(translation_size + i),
- environment->HasUint32ValueAt(translation_size + i));
- }
- continue;
- }
-
- AddToTranslation(translation,
+ AddToTranslation(environment,
+ translation,
value,
environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
+ environment->HasUint32ValueAt(i),
+ &object_index,
+ &dematerialized_index);
}
}
-void LCodeGen::AddToTranslation(Translation* translation,
+void LCodeGen::AddToTranslation(LEnvironment* environment,
+ Translation* translation,
LOperand* op,
bool is_tagged,
- bool is_uint32) {
+ bool is_uint32,
+ int* object_index_pointer,
+ int* dematerialized_index_pointer) {
+ if (op == LEnvironment::materialization_marker()) {
+ int object_index = (*object_index_pointer)++;
+ if (environment->ObjectIsDuplicateAt(object_index)) {
+ int dupe_of = environment->ObjectDuplicateOfAt(object_index);
+ translation->DuplicateObject(dupe_of);
+ return;
+ }
+ int object_length = environment->ObjectLengthAt(object_index);
+ if (environment->ObjectIsArgumentsAt(object_index)) {
+ translation->BeginArgumentsObject(object_length);
+ } else {
+ translation->BeginCapturedObject(object_length);
+ }
+ int dematerialized_index = *dematerialized_index_pointer;
+ int env_offset = environment->translation_size() + dematerialized_index;
+ *dematerialized_index_pointer += object_length;
+ for (int i = 0; i < object_length; ++i) {
+ LOperand* value = environment->values()->at(env_offset + i);
+ AddToTranslation(environment,
+ translation,
+ value,
+ environment->HasTaggedValueAt(env_offset + i),
+ environment->HasUint32ValueAt(env_offset + i),
+ object_index_pointer,
+ dematerialized_index_pointer);
+ }
+ return;
+ }
+
if (op->IsStackSlot()) {
if (is_tagged) {
translation->StoreStackSlot(op->index());
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;
}
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);
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 {
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));
}
+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());