| Index: src/mips/lithium-codegen-mips.cc
|
| diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
|
| index 2a9ca324fc69561d7f4dafa2d76d7eb82fa93163..6bd45fe2f2353633032609927c205d0e483fa763 100644
|
| --- a/src/mips/lithium-codegen-mips.cc
|
| +++ b/src/mips/lithium-codegen-mips.cc
|
| @@ -407,15 +407,14 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
|
| if (r.IsInteger32()) {
|
| ASSERT(literal->IsNumber());
|
| __ li(scratch, Operand(static_cast<int32_t>(literal->Number())));
|
| + } else if (r.IsSmi()) {
|
| + ASSERT(constant->HasSmiValue());
|
| + __ li(scratch, Operand(Smi::FromInt(constant->Integer32Value())));
|
| } else if (r.IsDouble()) {
|
| Abort("EmitLoadRegister: Unsupported double immediate.");
|
| } else {
|
| ASSERT(r.IsTagged());
|
| - if (literal->IsSmi()) {
|
| - __ li(scratch, Operand(literal));
|
| - } else {
|
| - __ LoadHeapObject(scratch, Handle<HeapObject>::cast(literal));
|
| - }
|
| + __ LoadObject(scratch, literal);
|
| }
|
| return scratch;
|
| } else if (op->IsStackSlot() || op->IsArgument()) {
|
| @@ -481,9 +480,18 @@ bool LCodeGen::IsSmi(LConstantOperand* op) const {
|
| }
|
|
|
|
|
| -int LCodeGen::ToInteger32(LConstantOperand* op) const {
|
| +int32_t LCodeGen::ToInteger32(LConstantOperand* op) const {
|
| + return ToRepresentation(op, Representation::Integer32());
|
| +}
|
| +
|
| +
|
| +int32_t LCodeGen::ToRepresentation(LConstantOperand* op,
|
| + const Representation& r) const {
|
| HConstant* constant = chunk_->LookupConstant(op);
|
| - return constant->Integer32Value();
|
| + int32_t value = constant->Integer32Value();
|
| + if (r.IsInteger32()) return value;
|
| + ASSERT(r.IsSmiOrTagged());
|
| + return reinterpret_cast<int32_t>(Smi::FromInt(value));
|
| }
|
|
|
|
|
| @@ -505,7 +513,10 @@ Operand LCodeGen::ToOperand(LOperand* op) {
|
| LConstantOperand* const_op = LConstantOperand::cast(op);
|
| HConstant* constant = chunk()->LookupConstant(const_op);
|
| Representation r = chunk_->LookupLiteralRepresentation(const_op);
|
| - if (r.IsInteger32()) {
|
| + if (r.IsSmi()) {
|
| + ASSERT(constant->HasSmiValue());
|
| + return Operand(Smi::FromInt(constant->Integer32Value()));
|
| + } else if (r.IsInteger32()) {
|
| ASSERT(constant->HasInteger32Value());
|
| return Operand(constant->Integer32Value());
|
| } else if (r.IsDouble()) {
|
| @@ -790,14 +801,6 @@ void LCodeGen::DeoptimizeIf(Condition cc,
|
| }
|
|
|
|
|
| -void LCodeGen::SoftDeoptimize(LEnvironment* environment,
|
| - Register src1,
|
| - const Operand& src2) {
|
| - ASSERT(!info()->IsStub());
|
| - DeoptimizeIf(al, environment, Deoptimizer::SOFT, src1, src2);
|
| -}
|
| -
|
| -
|
| void LCodeGen::RegisterDependentCodeForEmbeddedMaps(Handle<Code> code) {
|
| ZoneList<Handle<Map> > maps(1, zone());
|
| int mode_mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
|
| @@ -1379,7 +1382,9 @@ void LCodeGen::DoMulI(LMulI* instr) {
|
|
|
| if (right_op->IsConstantOperand() && !can_overflow) {
|
| // Use optimized code for specific constants.
|
| - int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
|
| + int32_t constant = ToRepresentation(
|
| + LConstantOperand::cast(right_op),
|
| + instr->hydrogen()->right()->representation());
|
|
|
| if (bailout_on_minus_zero && (constant < 0)) {
|
| // The case of a null constant will be handled separately.
|
| @@ -1446,13 +1451,25 @@ void LCodeGen::DoMulI(LMulI* instr) {
|
|
|
| if (can_overflow) {
|
| // hi:lo = left * right.
|
| - __ mult(left, right);
|
| - __ mfhi(scratch);
|
| - __ mflo(result);
|
| + if (instr->hydrogen()->representation().IsSmi()) {
|
| + __ SmiUntag(result, left);
|
| + __ mult(result, right);
|
| + __ mfhi(scratch);
|
| + __ mflo(result);
|
| + } else {
|
| + __ mult(left, right);
|
| + __ mfhi(scratch);
|
| + __ mflo(result);
|
| + }
|
| __ sra(at, result, 31);
|
| DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
|
| } else {
|
| - __ Mul(result, left, right);
|
| + if (instr->hydrogen()->representation().IsSmi()) {
|
| + __ SmiUntag(result, left);
|
| + __ Mul(result, result, right);
|
| + } else {
|
| + __ Mul(result, left, right);
|
| + }
|
| }
|
|
|
| if (bailout_on_minus_zero) {
|
| @@ -1507,6 +1524,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
|
| LOperand* right_op = instr->right();
|
| Register left = ToRegister(instr->left());
|
| Register result = ToRegister(instr->result());
|
| + Register scratch = scratch0();
|
|
|
| if (right_op->IsRegister()) {
|
| // No need to mask the right operand on MIPS, it is built into the variable
|
| @@ -1563,7 +1581,14 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
|
| break;
|
| case Token::SHL:
|
| if (shift_count != 0) {
|
| - __ sll(result, left, shift_count);
|
| + if (instr->hydrogen_value()->representation().IsSmi() &&
|
| + instr->can_deopt()) {
|
| + __ sll(result, left, shift_count - 1);
|
| + __ SmiTagCheckOverflow(result, result, scratch);
|
| + DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
|
| + } else {
|
| + __ sll(result, left, shift_count);
|
| + }
|
| } else {
|
| __ Move(result, left);
|
| }
|
| @@ -1636,12 +1661,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
|
| void LCodeGen::DoConstantT(LConstantT* instr) {
|
| Handle<Object> value = instr->value();
|
| AllowDeferredHandleDereference smi_check;
|
| - if (value->IsSmi()) {
|
| - __ li(ToRegister(instr->result()), Operand(value));
|
| - } else {
|
| - __ LoadHeapObject(ToRegister(instr->result()),
|
| - Handle<HeapObject>::cast(value));
|
| - }
|
| + __ LoadObject(ToRegister(instr->result()), value);
|
| }
|
|
|
|
|
| @@ -1820,7 +1840,7 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
|
| LOperand* right = instr->right();
|
| HMathMinMax::Operation operation = instr->hydrogen()->operation();
|
| Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
|
| - if (instr->hydrogen()->representation().IsInteger32()) {
|
| + if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
|
| Register left_reg = ToRegister(left);
|
| Operand right_op = (right->IsRegister() || right->IsConstantOperand())
|
| ? ToOperand(right)
|
| @@ -2240,13 +2260,6 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
|
| }
|
|
|
|
|
| -void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
|
| - Register left = ToRegister(instr->left());
|
| -
|
| - EmitBranch(instr, eq, left, Operand(instr->hydrogen()->right()));
|
| -}
|
| -
|
| -
|
| Condition LCodeGen::EmitIsObject(Register input,
|
| Register temp1,
|
| Register temp2,
|
| @@ -2901,9 +2914,9 @@ void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
|
| __ lw(result, FieldMemOperand(object, JSObject::kPropertiesOffset));
|
| __ lw(result, FieldMemOperand(result, offset + FixedArray::kHeaderSize));
|
| }
|
| - } else if (lookup.IsConstantFunction()) {
|
| - Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
|
| - __ LoadHeapObject(result, function);
|
| + } else if (lookup.IsConstant()) {
|
| + Handle<Object> constant(lookup.GetConstantFromMap(*type), isolate());
|
| + __ LoadObject(result, constant);
|
| } else {
|
| // Negative lookup.
|
| // Check prototypes.
|
| @@ -4187,9 +4200,25 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::ApplyCheckIf(Condition cc,
|
| + LBoundsCheck* check,
|
| + Register src1,
|
| + const Operand& src2) {
|
| + if (FLAG_debug_code && check->hydrogen()->skip_check()) {
|
| + Label done;
|
| + __ Branch(&done, NegateCondition(cc), src1, src2);
|
| + __ stop("eliminated bounds check failed");
|
| + __ bind(&done);
|
| + } else {
|
| + DeoptimizeIf(cc, check->environment(), src1, src2);
|
| + }
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
|
| if (instr->hydrogen()->skip_check()) return;
|
|
|
| + Condition condition = instr->hydrogen()->allow_equality() ? hi : hs;
|
| if (instr->index()->IsConstantOperand()) {
|
| int constant_index =
|
| ToInteger32(LConstantOperand::cast(instr->index()));
|
| @@ -4198,13 +4227,13 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
|
| } else {
|
| __ li(at, Operand(constant_index));
|
| }
|
| - DeoptimizeIf(hs,
|
| - instr->environment(),
|
| + ApplyCheckIf(condition,
|
| + instr,
|
| at,
|
| Operand(ToRegister(instr->length())));
|
| } else {
|
| - DeoptimizeIf(hs,
|
| - instr->environment(),
|
| + ApplyCheckIf(condition,
|
| + instr,
|
| ToRegister(instr->index()),
|
| Operand(ToRegister(instr->length())));
|
| }
|
| @@ -4426,7 +4455,7 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
|
| // Write barrier.
|
| __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
|
| scratch, GetRAState(), kDontSaveFPRegs);
|
| - } else if (FLAG_compiled_transitions) {
|
| + } else {
|
| PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
|
| __ mov(a0, object_reg);
|
| __ li(a1, Operand(to_map));
|
| @@ -4434,28 +4463,6 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
|
| __ CallStub(&stub);
|
| RecordSafepointWithRegisters(
|
| instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
|
| - } else if (IsFastSmiElementsKind(from_kind) &&
|
| - IsFastDoubleElementsKind(to_kind)) {
|
| - Register fixed_object_reg = ToRegister(instr->temp());
|
| - ASSERT(fixed_object_reg.is(a2));
|
| - Register new_map_reg = ToRegister(instr->new_map_temp());
|
| - ASSERT(new_map_reg.is(a3));
|
| - __ li(new_map_reg, Operand(to_map));
|
| - __ mov(fixed_object_reg, object_reg);
|
| - CallCode(isolate()->builtins()->TransitionElementsSmiToDouble(),
|
| - RelocInfo::CODE_TARGET, instr);
|
| - } else if (IsFastDoubleElementsKind(from_kind) &&
|
| - IsFastObjectElementsKind(to_kind)) {
|
| - Register fixed_object_reg = ToRegister(instr->temp());
|
| - ASSERT(fixed_object_reg.is(a2));
|
| - Register new_map_reg = ToRegister(instr->new_map_temp());
|
| - ASSERT(new_map_reg.is(a3));
|
| - __ li(new_map_reg, Operand(to_map));
|
| - __ mov(fixed_object_reg, object_reg);
|
| - CallCode(isolate()->builtins()->TransitionElementsDoubleToObject(),
|
| - RelocInfo::CODE_TARGET, instr);
|
| - } else {
|
| - UNREACHABLE();
|
| }
|
| __ bind(¬_applicable);
|
| }
|
| @@ -5195,6 +5202,7 @@ void LCodeGen::DoCheckMapCommon(Register map_reg,
|
|
|
|
|
| void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
|
| + if (instr->hydrogen()->CanOmitMapChecks()) return;
|
| Register map_reg = scratch0();
|
| LOperand* input = instr->value();
|
| ASSERT(input->IsRegister());
|
| @@ -5263,6 +5271,8 @@ void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
|
|
|
|
|
| void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
|
| + if (instr->hydrogen()->CanOmitPrototypeChecks()) return;
|
| +
|
| Register prototype_reg = ToRegister(instr->temp());
|
| Register map_reg = ToRegister(instr->temp2());
|
|
|
| @@ -5271,12 +5281,10 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
|
|
|
| ASSERT(prototypes->length() == maps->length());
|
|
|
| - if (!instr->hydrogen()->CanOmitPrototypeChecks()) {
|
| - for (int i = 0; i < prototypes->length(); i++) {
|
| - __ LoadHeapObject(prototype_reg, prototypes->at(i));
|
| - __ lw(map_reg, FieldMemOperand(prototype_reg, HeapObject::kMapOffset));
|
| - DoCheckMapCommon(map_reg, maps->at(i), instr->environment());
|
| - }
|
| + for (int i = 0; i < prototypes->length(); i++) {
|
| + __ LoadHeapObject(prototype_reg, prototypes->at(i));
|
| + __ lw(map_reg, FieldMemOperand(prototype_reg, HeapObject::kMapOffset));
|
| + DoCheckMapCommon(map_reg, maps->at(i), instr->environment());
|
| }
|
| }
|
|
|
| @@ -5649,11 +5657,15 @@ void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
|
|
|
|
|
| void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
|
| - if (instr->hydrogen_value()->IsSoftDeoptimize()) {
|
| - SoftDeoptimize(instr->environment(), zero_reg, Operand(zero_reg));
|
| - } else {
|
| - DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg));
|
| - }
|
| + Deoptimizer::BailoutType type = instr->hydrogen()->type();
|
| + // TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
|
| + // needed return address), even though the implementation of LAZY and EAGER is
|
| + // now identical. When LAZY is eventually completely folded into EAGER, remove
|
| + // the special case below.
|
| + if (info()->IsStub() && type == Deoptimizer::EAGER) {
|
| + type = Deoptimizer::LAZY;
|
| + }
|
| + DeoptimizeIf(al, instr->environment(), type, zero_reg, Operand(zero_reg));
|
| }
|
|
|
|
|
|
|