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 <kilvadyb@homejinni.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15097 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
2a56e33da7
commit
6124e8f141
@ -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,
|
||||
|
@ -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> code);
|
||||
void PopulateDeoptimizationData(Handle<Code> code);
|
||||
int DefineDeoptimizationLiteral(Handle<Object> literal);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user