| Index: runtime/vm/intermediate_language_mips.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_mips.cc (revision 22056)
|
| +++ runtime/vm/intermediate_language_mips.cc (working copy)
|
| @@ -1301,11 +1301,10 @@
|
|
|
| LocationSummary* InstantiateTypeArgumentsInstr::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 1;
|
| - const intptr_t kNumTemps = 1;
|
| + const intptr_t kNumTemps = 0;
|
| LocationSummary* locs =
|
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall);
|
| locs->set_in(0, Location::RegisterLocation(T0));
|
| - locs->set_temp(0, Location::RegisterLocation(T1));
|
| locs->set_out(Location::RegisterLocation(T0));
|
| return locs;
|
| }
|
| @@ -1315,52 +1314,41 @@
|
| FlowGraphCompiler* compiler) {
|
| __ TraceSimMsg("InstantiateTypeArgumentsInstr");
|
| Register instantiator_reg = locs()->in(0).reg();
|
| - Register temp = locs()->temp(0).reg();
|
| Register result_reg = locs()->out().reg();
|
|
|
| // 'instantiator_reg' is the instantiator AbstractTypeArguments object
|
| // (or null).
|
| - // If the instantiator is null and if the type argument vector
|
| - // instantiated from null becomes a vector of dynamic, then use null as
|
| - // the type arguments.
|
| - Label type_arguments_instantiated;
|
| - const intptr_t len = type_arguments().Length();
|
| - if (type_arguments().IsRawInstantiatedRaw(len)) {
|
| - __ BranchEqual(instantiator_reg, reinterpret_cast<intptr_t>(Object::null()),
|
| - &type_arguments_instantiated);
|
| - }
|
| - // Instantiate non-null type arguments.
|
| - if (type_arguments().IsUninstantiatedIdentity()) {
|
| - // Check if the instantiator type argument vector is a TypeArguments of a
|
| - // matching length and, if so, use it as the instantiated type_arguments.
|
| - // No need to check the instantiator ('instantiator_reg') for null here,
|
| - // because a null instantiator will have the wrong class (Null instead of
|
| - // TypeArguments).
|
| - Label type_arguments_uninstantiated;
|
| - __ LoadClassId(temp, instantiator_reg);
|
| - __ BranchNotEqual(temp, kTypeArgumentsCid, &type_arguments_uninstantiated);
|
| - __ lw(temp, FieldAddress(instantiator_reg, TypeArguments::length_offset()));
|
| - __ BranchEqual(temp, Smi::RawValue(len), &type_arguments_instantiated);
|
| - __ Bind(&type_arguments_uninstantiated);
|
| - }
|
| - // A runtime call to instantiate the type arguments is required.
|
| - __ addiu(SP, SP, Immediate(-3 * kWordSize));
|
| - __ LoadObject(TMP1, Object::ZoneHandle());
|
| - __ LoadObject(TMP2, type_arguments());
|
| - __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result.
|
| - __ sw(TMP2, Address(SP, 1 * kWordSize));
|
| - // Push instantiator type arguments.
|
| - __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
|
| + if (!type_arguments().IsUninstantiatedIdentity()) {
|
| + // If the instantiator is null and if the type argument vector
|
| + // instantiated from null becomes a vector of dynamic, then use null as
|
| + // the type arguments.
|
| + Label type_arguments_instantiated;
|
| + const intptr_t len = type_arguments().Length();
|
| + if (type_arguments().IsRawInstantiatedRaw(len)) {
|
| + __ BranchEqual(instantiator_reg,
|
| + reinterpret_cast<intptr_t>(Object::null()),
|
| + &type_arguments_instantiated);
|
| + }
|
| + // Instantiate non-null type arguments.
|
| + // A runtime call to instantiate the type arguments is required.
|
| + __ addiu(SP, SP, Immediate(-3 * kWordSize));
|
| + __ LoadObject(TMP1, Object::ZoneHandle());
|
| + __ LoadObject(TMP2, type_arguments());
|
| + __ sw(TMP1, Address(SP, 2 * kWordSize)); // Make room for the result.
|
| + __ sw(TMP2, Address(SP, 1 * kWordSize));
|
| + // Push instantiator type arguments.
|
| + __ sw(instantiator_reg, Address(SP, 0 * kWordSize));
|
|
|
| - compiler->GenerateCallRuntime(token_pos(),
|
| - deopt_id(),
|
| - kInstantiateTypeArgumentsRuntimeEntry,
|
| - locs());
|
| - // Pop instantiated type arguments.
|
| - __ lw(result_reg, Address(SP, 2 * kWordSize));
|
| - // Drop instantiator and uninstantiated type arguments.
|
| - __ addiu(SP, SP, Immediate(3 * kWordSize));
|
| - __ Bind(&type_arguments_instantiated);
|
| + compiler->GenerateCallRuntime(token_pos(),
|
| + deopt_id(),
|
| + kInstantiateTypeArgumentsRuntimeEntry,
|
| + locs());
|
| + // Pop instantiated type arguments.
|
| + __ lw(result_reg, Address(SP, 2 * kWordSize));
|
| + // Drop instantiator and uninstantiated type arguments.
|
| + __ addiu(SP, SP, Immediate(3 * kWordSize));
|
| + __ Bind(&type_arguments_instantiated);
|
| + }
|
| ASSERT(instantiator_reg == result_reg);
|
| // 'result_reg': Instantiated type arguments.
|
| }
|
| @@ -1369,12 +1357,11 @@
|
| LocationSummary*
|
| ExtractConstructorTypeArgumentsInstr::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 1;
|
| - const intptr_t kNumTemps = 1;
|
| + const intptr_t kNumTemps = 0;
|
| LocationSummary* locs =
|
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| locs->set_in(0, Location::RequiresRegister());
|
| locs->set_out(Location::SameAsFirstInput());
|
| - locs->set_temp(0, Location::RequiresRegister());
|
| return locs;
|
| }
|
|
|
| @@ -1384,40 +1371,28 @@
|
| Register instantiator_reg = locs()->in(0).reg();
|
| Register result_reg = locs()->out().reg();
|
| ASSERT(instantiator_reg == result_reg);
|
| - Register temp_reg = locs()->temp(0).reg();
|
|
|
| // instantiator_reg is the instantiator type argument vector, i.e. an
|
| // AbstractTypeArguments object (or null).
|
| - // If the instantiator is null and if the type argument vector
|
| - // instantiated from null becomes a vector of dynamic, then use null as
|
| - // the type arguments.
|
| - Label type_arguments_instantiated;
|
| - const intptr_t len = type_arguments().Length();
|
| - if (type_arguments().IsRawInstantiatedRaw(len)) {
|
| - __ BranchEqual(instantiator_reg, reinterpret_cast<intptr_t>(Object::null()),
|
| - &type_arguments_instantiated);
|
| + if (!type_arguments().IsUninstantiatedIdentity()) {
|
| + // If the instantiator is null and if the type argument vector
|
| + // instantiated from null becomes a vector of dynamic, then use null as
|
| + // the type arguments.
|
| + Label type_arguments_instantiated;
|
| + const intptr_t len = type_arguments().Length();
|
| + if (type_arguments().IsRawInstantiatedRaw(len)) {
|
| + __ BranchEqual(instantiator_reg,
|
| + reinterpret_cast<intptr_t>(Object::null()),
|
| + &type_arguments_instantiated);
|
| + }
|
| + // Instantiate non-null type arguments.
|
| + // In the non-factory case, we rely on the allocation stub to
|
| + // instantiate the type arguments.
|
| + __ LoadObject(result_reg, type_arguments());
|
| + // result_reg: uninstantiated type arguments.
|
| + __ Bind(&type_arguments_instantiated);
|
| }
|
| - // Instantiate non-null type arguments.
|
| - if (type_arguments().IsUninstantiatedIdentity()) {
|
| - // Check if the instantiator type argument vector is a TypeArguments of a
|
| - // matching length and, if so, use it as the instantiated type_arguments.
|
| - // No need to check instantiator_reg for null here, because a null
|
| - // instantiator will have the wrong class (Null instead of TypeArguments).
|
| - Label type_arguments_uninstantiated;
|
| - __ LoadClassId(temp_reg, instantiator_reg);
|
| - __ BranchNotEqual(temp_reg, kTypeArgumentsCid,
|
| - &type_arguments_uninstantiated);
|
| - __ lw(temp_reg,
|
| - FieldAddress(instantiator_reg, TypeArguments::length_offset()));
|
| - __ BranchEqual(temp_reg, Smi::RawValue(type_arguments().Length()),
|
| - &type_arguments_instantiated);
|
| - __ Bind(&type_arguments_uninstantiated);
|
| - }
|
| - // In the non-factory case, we rely on the allocation stub to
|
| - // instantiate the type arguments.
|
| - __ LoadObject(result_reg, type_arguments());
|
| - // result_reg: uninstantiated type arguments.
|
| - __ Bind(&type_arguments_instantiated);
|
| + ASSERT(instantiator_reg == result_reg);
|
| // result_reg: uninstantiated or instantiated type arguments.
|
| }
|
|
|
| @@ -1425,12 +1400,11 @@
|
| LocationSummary*
|
| ExtractConstructorInstantiatorInstr::MakeLocationSummary() const {
|
| const intptr_t kNumInputs = 1;
|
| - const intptr_t kNumTemps = 1;
|
| + const intptr_t kNumTemps = 0;
|
| LocationSummary* locs =
|
| new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
| locs->set_in(0, Location::RequiresRegister());
|
| locs->set_out(Location::SameAsFirstInput());
|
| - locs->set_temp(0, Location::RequiresRegister());
|
| return locs;
|
| }
|
|
|
| @@ -1439,50 +1413,30 @@
|
| FlowGraphCompiler* compiler) {
|
| Register instantiator_reg = locs()->in(0).reg();
|
| ASSERT(locs()->out().reg() == instantiator_reg);
|
| - Register temp_reg = locs()->temp(0).reg();
|
|
|
| // instantiator_reg is the instantiator AbstractTypeArguments object
|
| - // (or null). If the instantiator is null and if the type argument vector
|
| - // instantiated from null becomes a vector of dynamic, then use null as
|
| - // the type arguments and do not pass the instantiator.
|
| - Label done;
|
| - const intptr_t len = type_arguments().Length();
|
| - if (type_arguments().IsRawInstantiatedRaw(len)) {
|
| - Label instantiator_not_null;
|
| - __ BranchNotEqual(instantiator_reg,
|
| - reinterpret_cast<intptr_t>(Object::null()), &instantiator_not_null);
|
| - // Null was used in VisitExtractConstructorTypeArguments as the
|
| - // instantiated type arguments, no proper instantiator needed.
|
| - __ LoadImmediate(instantiator_reg,
|
| - Smi::RawValue(StubCode::kNoInstantiator));
|
| - __ b(&done);
|
| - __ Bind(&instantiator_not_null);
|
| - }
|
| - // Instantiate non-null type arguments.
|
| + // (or null).
|
| if (type_arguments().IsUninstantiatedIdentity()) {
|
| - // TODO(regis): The following emitted code is duplicated in
|
| - // VisitExtractConstructorTypeArguments above. The reason is that the code
|
| - // is split between two computations, so that each one produces a
|
| - // single value, rather than producing a pair of values.
|
| - // If this becomes an issue, we should expose these tests at the IL level.
|
| -
|
| - // Check if the instantiator type argument vector is a TypeArguments of a
|
| - // matching length and, if so, use it as the instantiated type_arguments.
|
| - // No need to check the instantiator ('instantiator_reg') for null here,
|
| - // because a null instantiator will have the wrong class (Null instead of
|
| - // TypeArguments).
|
| - __ LoadClassId(temp_reg, instantiator_reg);
|
| - __ BranchNotEqual(temp_reg, kTypeArgumentsCid, &done);
|
| - __ lw(temp_reg,
|
| - FieldAddress(instantiator_reg, TypeArguments::length_offset()));
|
| - __ BranchNotEqual(temp_reg, Smi::RawValue(type_arguments().Length()),
|
| - &done);
|
| // The instantiator was used in VisitExtractConstructorTypeArguments as the
|
| // instantiated type arguments, no proper instantiator needed.
|
| __ LoadImmediate(instantiator_reg,
|
| Smi::RawValue(StubCode::kNoInstantiator));
|
| + } else {
|
| + // If the instantiator is null and if the type argument vector
|
| + // instantiated from null becomes a vector of dynamic, then use null as
|
| + // the type arguments and do not pass the instantiator.
|
| + const intptr_t len = type_arguments().Length();
|
| + if (type_arguments().IsRawInstantiatedRaw(len)) {
|
| + Label instantiator_not_null;
|
| + __ BranchNotEqual(instantiator_reg,
|
| + reinterpret_cast<intptr_t>(Object::null()), &instantiator_not_null);
|
| + // Null was used in VisitExtractConstructorTypeArguments as the
|
| + // instantiated type arguments, no proper instantiator needed.
|
| + __ LoadImmediate(instantiator_reg,
|
| + Smi::RawValue(StubCode::kNoInstantiator));
|
| + __ Bind(&instantiator_not_null);
|
| + }
|
| }
|
| - __ Bind(&done);
|
| // instantiator_reg: instantiator or kNoInstantiator.
|
| }
|
|
|
|
|