From 6124e8f141eee176e8844b9275f0e252a60d4872 Mon Sep 17 00:00:00 2001 From: "palfia@homejinni.com" Date: Wed, 12 Jun 2013 21:46:53 +0000 Subject: [PATCH] MIPS: Allow the deoptimizer translation to track de-materialized objects. Port r15087 (63e1626) Original commit message: This allows the deoptimizer to materialize objects (e.g. the arguments object) while deopting without having a consective stack area holding the object values. The LEnvironment explicitly tracks locations for these values and preserves them in the translation. TEST=mjsunit/compiler/inline-arguments BUG= Review URL: https://codereview.chromium.org/16846002 Patch from Balazs Kilvady . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15097 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/lithium-codegen-mips.cc | 89 +++++++++++--------------------- src/mips/lithium-codegen-mips.h | 10 +--- src/mips/lithium-mips.cc | 22 +++++++- 3 files changed, 53 insertions(+), 68 deletions(-) diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 4e5693797..f8d743eeb 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -561,27 +561,15 @@ MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const { void LCodeGen::WriteTranslation(LEnvironment* environment, - Translation* translation, - int* pushed_arguments_index, - int* pushed_arguments_count) { + Translation* translation) { if (environment == NULL) return; // The translation includes one command per value in the environment. - int translation_size = environment->values()->length(); + int translation_size = environment->translation_size(); // The output frame height does not include the parameters. int height = translation_size - environment->parameter_count(); - // Function parameters are arguments to the outermost environment. The - // arguments index points to the first element of a sequence of tagged - // values on the stack that represent the arguments. This needs to be - // kept in sync with the LArgumentsElements implementation. - *pushed_arguments_index = -environment->parameter_count(); - *pushed_arguments_count = environment->parameter_count(); - - WriteTranslation(environment->outer(), - translation, - pushed_arguments_index, - pushed_arguments_count); + WriteTranslation(environment->outer(), translation); bool has_closure_id = !info()->closure().is_null() && !info()->closure().is_identical_to(environment->closure()); int closure_id = has_closure_id @@ -613,23 +601,6 @@ void LCodeGen::WriteTranslation(LEnvironment* environment, break; } - // Inlined frames which push their arguments cause the index to be - // bumped and another stack area to be used for materialization, - // otherwise actual argument values are unknown for inlined frames. - bool arguments_known = true; - int arguments_index = *pushed_arguments_index; - int arguments_count = *pushed_arguments_count; - if (environment->entry() != NULL) { - arguments_known = environment->entry()->arguments_pushed(); - arguments_index = arguments_index < 0 - ? GetStackSlotCount() : arguments_index + arguments_count; - arguments_count = environment->entry()->arguments_count() + 1; - if (environment->entry()->arguments_pushed()) { - *pushed_arguments_index = arguments_index; - *pushed_arguments_count = arguments_count; - } - } - for (int i = 0; i < translation_size; ++i) { LOperand* value = environment->values()->at(i); // spilled_registers_ and spilled_double_registers_ are either @@ -641,10 +612,7 @@ void LCodeGen::WriteTranslation(LEnvironment* environment, AddToTranslation(translation, environment->spilled_registers()[value->index()], environment->HasTaggedValueAt(i), - environment->HasUint32ValueAt(i), - arguments_known, - arguments_index, - arguments_count); + environment->HasUint32ValueAt(i)); } else if ( value->IsDoubleRegister() && environment->spilled_double_registers()[value->index()] != NULL) { @@ -653,20 +621,36 @@ void LCodeGen::WriteTranslation(LEnvironment* environment, translation, environment->spilled_double_registers()[value->index()], false, - false, - arguments_known, - arguments_index, - arguments_count); + false); + } + } + + // 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); + ASSERT(environment->spilled_registers() == NULL || + !value->IsRegister() || + environment->spilled_registers()[value->index()] == NULL); + ASSERT(environment->spilled_registers() == NULL || + !value->IsDoubleRegister() || + environment->spilled_double_registers()[value->index()] == NULL); + AddToTranslation(translation, + value, + environment->HasTaggedValueAt(translation_size + i), + environment->HasUint32ValueAt(translation_size + i)); } + continue; } AddToTranslation(translation, value, environment->HasTaggedValueAt(i), - environment->HasUint32ValueAt(i), - arguments_known, - arguments_index, - arguments_count); + environment->HasUint32ValueAt(i)); } } @@ -674,17 +658,8 @@ void LCodeGen::WriteTranslation(LEnvironment* environment, void LCodeGen::AddToTranslation(Translation* translation, LOperand* op, bool is_tagged, - bool is_uint32, - bool arguments_known, - int arguments_index, - int arguments_count) { - if (op == NULL) { - // TODO(twuerthinger): 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. - translation->StoreArgumentsObject( - arguments_known, arguments_index, arguments_count); - } else if (op->IsStackSlot()) { + bool is_uint32) { + if (op->IsStackSlot()) { if (is_tagged) { translation->StoreStackSlot(op->index()); } else if (is_uint32) { @@ -779,8 +754,6 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, int frame_count = 0; int jsframe_count = 0; - int args_index = 0; - int args_count = 0; for (LEnvironment* e = environment; e != NULL; e = e->outer()) { ++frame_count; if (e->frame_type() == JS_FUNCTION) { @@ -788,7 +761,7 @@ void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, } } Translation translation(&translations_, frame_count, jsframe_count, zone()); - WriteTranslation(environment, &translation, &args_index, &args_count); + WriteTranslation(environment, &translation); int deoptimization_index = deoptimizations_.length(); int pc_offset = masm()->pc_offset(); environment->Register(deoptimization_index, diff --git a/src/mips/lithium-codegen-mips.h b/src/mips/lithium-codegen-mips.h index ee013834b..a8d7e0436 100644 --- a/src/mips/lithium-codegen-mips.h +++ b/src/mips/lithium-codegen-mips.h @@ -169,10 +169,7 @@ class LCodeGen BASE_EMBEDDED { int additional_offset); // Emit frame translation commands for an environment. - void WriteTranslation(LEnvironment* environment, - Translation* translation, - int* arguments_index, - int* arguments_count); + void WriteTranslation(LEnvironment* environment, Translation* translation); // Declare methods that deal with the individual node types. #define DECLARE_DO(type) void Do##type(L##type* node); @@ -295,10 +292,7 @@ class LCodeGen BASE_EMBEDDED { void AddToTranslation(Translation* translation, LOperand* op, bool is_tagged, - bool is_uint32, - bool arguments_known, - int arguments_index, - int arguments_count); + bool is_uint32); void RegisterDependentCodeForEmbeddedMaps(Handle code); void PopulateDeoptimizationData(Handle code); int DefineDeoptimizationLiteral(Handle literal); diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index ad39c618e..889e99700 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -933,7 +933,7 @@ LEnvironment* LChunkBuilder::CreateEnvironment( BailoutId ast_id = hydrogen_env->ast_id(); ASSERT(!ast_id.IsNone() || hydrogen_env->frame_type() != JS_FUNCTION); - int value_count = hydrogen_env->length(); + int value_count = hydrogen_env->length() - hydrogen_env->specials_count(); LEnvironment* result = new(zone()) LEnvironment( hydrogen_env->closure(), hydrogen_env->frame_type(), @@ -944,13 +944,15 @@ LEnvironment* LChunkBuilder::CreateEnvironment( outer, hydrogen_env->entry(), zone()); + bool needs_arguments_object_materialization = false; int argument_index = *argument_index_accumulator; - for (int i = 0; i < value_count; ++i) { + for (int i = 0; i < hydrogen_env->length(); ++i) { if (hydrogen_env->is_special_index(i)) continue; HValue* value = hydrogen_env->values()->at(i); LOperand* op = NULL; if (value->IsArgumentsObject()) { + needs_arguments_object_materialization = true; op = NULL; } else if (value->IsPushArgument()) { op = new(zone()) LArgument(argument_index++); @@ -962,6 +964,22 @@ 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()); + ASSERT(HInstruction::cast(value)->IsLinked()); + LOperand* op = UseAny(value); + result->AddValue(op, + value->representation(), + value->CheckFlag(HInstruction::kUint32)); + } + } + if (hydrogen_env->frame_type() == JS_FUNCTION) { *argument_index_accumulator = argument_index; } -- 2.34.1