| Index: src/mips/lithium-codegen-mips.cc
|
| diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
|
| index 34e601ccaa386a3eded1aad2b94fefccaf29bf56..be5809dd8de2788f113ca462fe809709672f1544 100644
|
| --- a/src/mips/lithium-codegen-mips.cc
|
| +++ b/src/mips/lithium-codegen-mips.cc
|
| @@ -91,7 +91,7 @@ void LCodeGen::FinishCode(Handle<Code> code) {
|
| }
|
|
|
|
|
| -void LChunkBuilder::Abort(BailoutReason reason) {
|
| +void LChunkBuilder::Abort(const char* reason) {
|
| info()->set_bailout_reason(reason);
|
| status_ = ABORTED;
|
| }
|
| @@ -324,7 +324,7 @@ bool LCodeGen::GenerateDeoptJumpTable() {
|
| // end of the jump table.
|
| if (!is_int16((masm()->pc_offset() / Assembler::kInstrSize) +
|
| deopt_jump_table_.length() * 12)) {
|
| - Abort(kGeneratedCodeIsTooLarge);
|
| + Abort("Generated code is too large");
|
| }
|
|
|
| if (deopt_jump_table_.length() > 0) {
|
| @@ -411,7 +411,7 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
|
| ASSERT(constant->HasSmiValue());
|
| __ li(scratch, Operand(Smi::FromInt(constant->Integer32Value())));
|
| } else if (r.IsDouble()) {
|
| - Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
|
| + Abort("EmitLoadRegister: Unsupported double immediate.");
|
| } else {
|
| ASSERT(r.IsTagged());
|
| __ LoadObject(scratch, literal);
|
| @@ -449,9 +449,9 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
|
| __ cvt_d_w(dbl_scratch, flt_scratch);
|
| return dbl_scratch;
|
| } else if (r.IsDouble()) {
|
| - Abort(kUnsupportedDoubleImmediate);
|
| + Abort("unsupported double immediate");
|
| } else if (r.IsTagged()) {
|
| - Abort(kUnsupportedTaggedImmediate);
|
| + Abort("unsupported tagged immediate");
|
| }
|
| } else if (op->IsStackSlot() || op->IsArgument()) {
|
| MemOperand mem_op = ToMemOperand(op);
|
| @@ -520,14 +520,14 @@ Operand LCodeGen::ToOperand(LOperand* op) {
|
| ASSERT(constant->HasInteger32Value());
|
| return Operand(constant->Integer32Value());
|
| } else if (r.IsDouble()) {
|
| - Abort(kToOperandUnsupportedDoubleImmediate);
|
| + Abort("ToOperand Unsupported double immediate.");
|
| }
|
| ASSERT(r.IsTagged());
|
| return Operand(constant->handle());
|
| } else if (op->IsRegister()) {
|
| return Operand(ToRegister(op));
|
| } else if (op->IsDoubleRegister()) {
|
| - Abort(kToOperandIsDoubleRegisterUnimplemented);
|
| + Abort("ToOperand IsDoubleRegister unimplemented");
|
| return Operand(0);
|
| }
|
| // Stack slots not implemented, use ToMemOperand instead.
|
| @@ -748,7 +748,7 @@ void LCodeGen::DeoptimizeIf(Condition cc,
|
| Address entry =
|
| Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
|
| if (entry == NULL) {
|
| - Abort(kBailoutWasNotPrepared);
|
| + Abort("bailout was not prepared");
|
| return;
|
| }
|
|
|
| @@ -1057,16 +1057,20 @@ void LCodeGen::DoModI(LModI* instr) {
|
| HValue* left = hmod->left();
|
| HValue* right = hmod->right();
|
| if (hmod->HasPowerOf2Divisor()) {
|
| + const Register scratch = scratch0();
|
| const Register left_reg = ToRegister(instr->left());
|
| + ASSERT(!left_reg.is(scratch));
|
| const Register result_reg = ToRegister(instr->result());
|
|
|
| // Note: The code below even works when right contains kMinInt.
|
| int32_t divisor = Abs(right->GetInteger32Constant());
|
|
|
| + __ mov(scratch, left_reg);
|
| +
|
| Label left_is_not_negative, done;
|
| if (left->CanBeNegative()) {
|
| - __ Branch(left_reg.is(result_reg) ? PROTECT : USE_DELAY_SLOT,
|
| - &left_is_not_negative, ge, left_reg, Operand(zero_reg));
|
| + __ Branch(USE_DELAY_SLOT, &left_is_not_negative,
|
| + ge, left_reg, Operand(zero_reg));
|
| __ subu(result_reg, zero_reg, left_reg);
|
| __ And(result_reg, result_reg, divisor - 1);
|
| if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| @@ -1077,13 +1081,15 @@ void LCodeGen::DoModI(LModI* instr) {
|
| }
|
|
|
| __ bind(&left_is_not_negative);
|
| - __ And(result_reg, left_reg, divisor - 1);
|
| + __ And(result_reg, scratch, divisor - 1);
|
| __ bind(&done);
|
|
|
| } else if (hmod->fixed_right_arg().has_value) {
|
| + const Register scratch = scratch0();
|
| const Register left_reg = ToRegister(instr->left());
|
| const Register result_reg = ToRegister(instr->result());
|
| - const Register right_reg = ToRegister(instr->right());
|
| +
|
| + Register right_reg = EmitLoadRegister(instr->right(), scratch);
|
|
|
| int32_t divisor = hmod->fixed_right_arg().value;
|
| ASSERT(IsPowerOf2(divisor));
|
| @@ -1093,8 +1099,8 @@ void LCodeGen::DoModI(LModI* instr) {
|
|
|
| Label left_is_not_negative, done;
|
| if (left->CanBeNegative()) {
|
| - __ Branch(left_reg.is(result_reg) ? PROTECT : USE_DELAY_SLOT,
|
| - &left_is_not_negative, ge, left_reg, Operand(zero_reg));
|
| + __ Branch(USE_DELAY_SLOT, &left_is_not_negative,
|
| + ge, left_reg, Operand(zero_reg));
|
| __ subu(result_reg, zero_reg, left_reg);
|
| __ And(result_reg, result_reg, divisor - 1);
|
| if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| @@ -1503,11 +1509,7 @@ void LCodeGen::DoBitI(LBitI* instr) {
|
| __ Or(result, left, right);
|
| break;
|
| case Token::BIT_XOR:
|
| - if (right_op->IsConstantOperand() && right.immediate() == int32_t(~0)) {
|
| - __ Nor(result, zero_reg, left);
|
| - } else {
|
| - __ Xor(result, left, right);
|
| - }
|
| + __ Xor(result, left, right);
|
| break;
|
| default:
|
| UNREACHABLE();
|
| @@ -1768,7 +1770,7 @@ void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
|
| static const uint32_t two_byte_seq_type = kSeqStringTag | kTwoByteStringTag;
|
| __ Subu(at, at, Operand(encoding == String::ONE_BYTE_ENCODING
|
| ? one_byte_seq_type : two_byte_seq_type));
|
| - __ Check(eq, kUnexpectedStringType, at, Operand(zero_reg));
|
| + __ Check(eq, "Unexpected string type", at, Operand(zero_reg));
|
| }
|
|
|
| __ Addu(scratch,
|
| @@ -1785,6 +1787,13 @@ void LCodeGen::DoSeqStringSetChar(LSeqStringSetChar* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoBitNotI(LBitNotI* instr) {
|
| + Register input = ToRegister(instr->value());
|
| + Register result = ToRegister(instr->result());
|
| + __ Nor(result, zero_reg, Operand(input));
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoThrow(LThrow* instr) {
|
| Register input_reg = EmitLoadRegister(instr->value(), at);
|
| __ push(input_reg);
|
| @@ -3067,7 +3076,7 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
|
| if (key_is_constant) {
|
| constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
|
| if (constant_key & 0xF0000000) {
|
| - Abort(kArrayIndexConstantValueTooBig);
|
| + Abort("array index constant value too big.");
|
| }
|
| } else {
|
| key = ToRegister(instr->key());
|
| @@ -3153,7 +3162,7 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
|
| if (key_is_constant) {
|
| constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
|
| if (constant_key & 0xF0000000) {
|
| - Abort(kArrayIndexConstantValueTooBig);
|
| + Abort("array index constant value too big.");
|
| }
|
| } else {
|
| key = ToRegister(instr->key());
|
| @@ -3424,7 +3433,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
|
| void LCodeGen::DoPushArgument(LPushArgument* instr) {
|
| LOperand* argument = instr->value();
|
| if (argument->IsDoubleRegister() || argument->IsDoubleStackSlot()) {
|
| - Abort(kDoPushArgumentNotImplementedForDoubleType);
|
| + Abort("DoPushArgument not implemented for double type.");
|
| } else {
|
| Register argument_reg = EmitLoadRegister(argument, at);
|
| __ push(argument_reg);
|
| @@ -3643,7 +3652,7 @@ void LCodeGen::DoMathAbs(LMathAbs* instr) {
|
| FPURegister input = ToDoubleRegister(instr->value());
|
| FPURegister result = ToDoubleRegister(instr->result());
|
| __ abs_d(result, input);
|
| - } else if (r.IsSmiOrInteger32()) {
|
| + } else if (r.IsInteger32()) {
|
| EmitIntegerMathAbs(instr);
|
| } else {
|
| // Representation is tagged.
|
| @@ -4249,7 +4258,7 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
|
| if (key_is_constant) {
|
| constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
|
| if (constant_key & 0xF0000000) {
|
| - Abort(kArrayIndexConstantValueTooBig);
|
| + Abort("array index constant value too big.");
|
| }
|
| } else {
|
| key = ToRegister(instr->key());
|
| @@ -4327,7 +4336,7 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
|
| if (key_is_constant) {
|
| constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
|
| if (constant_key & 0xF0000000) {
|
| - Abort(kArrayIndexConstantValueTooBig);
|
| + Abort("array index constant value too big.");
|
| }
|
| } else {
|
| key = ToRegister(instr->key());
|
| @@ -5184,63 +5193,31 @@ void LCodeGen::DoCheckFunction(LCheckFunction* instr) {
|
| }
|
|
|
|
|
| -void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
|
| - {
|
| - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
|
| - __ push(object);
|
| - CallRuntimeFromDeferred(Runtime::kMigrateInstance, 1, instr);
|
| - __ StoreToSafepointRegisterSlot(v0, scratch0());
|
| - }
|
| - __ And(at, scratch0(), Operand(kSmiTagMask));
|
| - DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
|
| +void LCodeGen::DoCheckMapCommon(Register map_reg,
|
| + Handle<Map> map,
|
| + LEnvironment* env) {
|
| + Label success;
|
| + __ CompareMapAndBranch(map_reg, map, &success, eq, &success);
|
| + DeoptimizeIf(al, env);
|
| + __ bind(&success);
|
| }
|
|
|
|
|
| void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
|
| - class DeferredCheckMaps: public LDeferredCode {
|
| - public:
|
| - DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object)
|
| - : LDeferredCode(codegen), instr_(instr), object_(object) {
|
| - SetExit(check_maps());
|
| - }
|
| - virtual void Generate() {
|
| - codegen()->DoDeferredInstanceMigration(instr_, object_);
|
| - }
|
| - Label* check_maps() { return &check_maps_; }
|
| - virtual LInstruction* instr() { return instr_; }
|
| - private:
|
| - LCheckMaps* instr_;
|
| - Label check_maps_;
|
| - Register object_;
|
| - };
|
| -
|
| if (instr->hydrogen()->CanOmitMapChecks()) return;
|
| Register map_reg = scratch0();
|
| LOperand* input = instr->value();
|
| ASSERT(input->IsRegister());
|
| Register reg = ToRegister(input);
|
| + Label success;
|
| SmallMapList* map_set = instr->hydrogen()->map_set();
|
| __ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
|
| -
|
| - DeferredCheckMaps* deferred = NULL;
|
| - if (instr->hydrogen()->has_migration_target()) {
|
| - deferred = new(zone()) DeferredCheckMaps(this, instr, reg);
|
| - __ bind(deferred->check_maps());
|
| - }
|
| -
|
| - Label success;
|
| for (int i = 0; i < map_set->length() - 1; i++) {
|
| Handle<Map> map = map_set->at(i);
|
| __ CompareMapAndBranch(map_reg, map, &success, eq, &success);
|
| }
|
| Handle<Map> map = map_set->last();
|
| - __ CompareMapAndBranch(map_reg, map, &success, eq, &success);
|
| - if (instr->hydrogen()->has_migration_target()) {
|
| - __ Branch(deferred->entry());
|
| - } else {
|
| - DeoptimizeIf(al, instr->environment());
|
| - }
|
| -
|
| + DoCheckMapCommon(map_reg, map, instr->environment());
|
| __ bind(&success);
|
| }
|
|
|
| @@ -5295,6 +5272,25 @@ 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());
|
| +
|
| + ZoneList<Handle<JSObject> >* prototypes = instr->prototypes();
|
| + ZoneList<Handle<Map> >* maps = instr->maps();
|
| +
|
| + ASSERT(prototypes->length() == maps->length());
|
| +
|
| + 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());
|
| + }
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoAllocate(LAllocate* instr) {
|
| class DeferredAllocate: public LDeferredCode {
|
| public:
|
|
|