X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fv8%2Fsrc%2Farm%2Flithium-codegen-arm.cc;h=ff09e287f76cfff73a251e2e92e3f63e2a1e7aa7;hb=4a1a0bdd01eef90b0826a0e761d3379d3715c10f;hp=cf0efe80a6873234d4c3320f8ff2976631a280e8;hpb=b1be5ca53587d23e7aeb77b26861fdc0a181ffd8;p=platform%2Fframework%2Fweb%2Fcrosswalk.git diff --git a/src/v8/src/arm/lithium-codegen-arm.cc b/src/v8/src/arm/lithium-codegen-arm.cc index cf0efe8..ff09e28 100644 --- a/src/v8/src/arm/lithium-codegen-arm.cc +++ b/src/v8/src/arm/lithium-codegen-arm.cc @@ -7,8 +7,8 @@ #include "src/arm/lithium-codegen-arm.h" #include "src/arm/lithium-gap-resolver-arm.h" #include "src/code-stubs.h" -#include "src/stub-cache.h" #include "src/hydrogen-osr.h" +#include "src/stub-cache.h" namespace v8 { namespace internal { @@ -41,7 +41,7 @@ class SafepointGenerator V8_FINAL : public CallWrapper { bool LCodeGen::GenerateCode() { LPhase phase("Z_Code generation", chunk()); - ASSERT(is_unused()); + DCHECK(is_unused()); status_ = GENERATING; // Open a frame scope to indicate that there is a frame on the stack. The @@ -58,7 +58,7 @@ bool LCodeGen::GenerateCode() { void LCodeGen::FinishCode(Handle code) { - ASSERT(is_done()); + DCHECK(is_done()); code->set_stack_slots(GetStackSlotCount()); code->set_safepoint_table_offset(safepoints_.GetCodeOffset()); if (code->is_optimized_code()) RegisterWeakObjectsInOptimizedCode(code); @@ -67,8 +67,8 @@ void LCodeGen::FinishCode(Handle code) { void LCodeGen::SaveCallerDoubles() { - ASSERT(info()->saves_caller_doubles()); - ASSERT(NeedsEagerFrame()); + DCHECK(info()->saves_caller_doubles()); + DCHECK(NeedsEagerFrame()); Comment(";;; Save clobbered callee double registers"); int count = 0; BitVector* doubles = chunk()->allocated_double_registers(); @@ -83,8 +83,8 @@ void LCodeGen::SaveCallerDoubles() { void LCodeGen::RestoreCallerDoubles() { - ASSERT(info()->saves_caller_doubles()); - ASSERT(NeedsEagerFrame()); + DCHECK(info()->saves_caller_doubles()); + DCHECK(NeedsEagerFrame()); Comment(";;; Restore clobbered callee double registers"); BitVector* doubles = chunk()->allocated_double_registers(); BitVector::Iterator save_iterator(doubles); @@ -99,7 +99,7 @@ void LCodeGen::RestoreCallerDoubles() { bool LCodeGen::GeneratePrologue() { - ASSERT(is_generating()); + DCHECK(is_generating()); if (info()->IsOptimizing()) { ProfileEntryHookStub::MaybeCallEntryHook(masm_); @@ -130,7 +130,7 @@ bool LCodeGen::GeneratePrologue() { __ b(ne, &ok); __ ldr(r2, GlobalObjectOperand()); - __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); + __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalProxyOffset)); __ str(r2, MemOperand(sp, receiver_offset)); @@ -188,7 +188,7 @@ bool LCodeGen::GeneratePrologue() { need_write_barrier = false; } else { __ push(r1); - __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1); + __ CallRuntime(Runtime::kNewFunctionContext, 1); } RecordSafepoint(Safepoint::kNoLazyDeopt); // Context is returned in both r0 and cp. It replaces the context @@ -247,7 +247,7 @@ void LCodeGen::GenerateOsrPrologue() { // Adjust the frame size, subsuming the unoptimized frame into the // optimized frame. int slots = GetStackSlotCount() - graph()->osr()->UnoptimizedFrameSlots(); - ASSERT(slots >= 0); + DCHECK(slots >= 0); __ sub(sp, sp, Operand(slots * kPointerSize)); } @@ -263,7 +263,7 @@ void LCodeGen::GenerateBodyInstructionPre(LInstruction* instr) { bool LCodeGen::GenerateDeferredCode() { - ASSERT(is_generating()); + DCHECK(is_generating()); if (deferred_.length() > 0) { for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { LDeferredCode* code = deferred_[i]; @@ -281,8 +281,8 @@ bool LCodeGen::GenerateDeferredCode() { __ bind(code->entry()); if (NeedsDeferredFrame()) { Comment(";;; Build frame"); - ASSERT(!frame_is_built_); - ASSERT(info()->IsStub()); + DCHECK(!frame_is_built_); + DCHECK(info()->IsStub()); frame_is_built_ = true; __ PushFixedFrame(); __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); @@ -293,7 +293,7 @@ bool LCodeGen::GenerateDeferredCode() { code->Generate(); if (NeedsDeferredFrame()) { Comment(";;; Destroy frame"); - ASSERT(frame_is_built_); + DCHECK(frame_is_built_); __ pop(ip); __ PopFixedFrame(); frame_is_built_ = false; @@ -324,48 +324,79 @@ bool LCodeGen::GenerateDeoptJumpTable() { } if (deopt_jump_table_.length() > 0) { + Label needs_frame, call_deopt_entry; + Comment(";;; -------------------- Jump table --------------------"); - } - Label table_start; - __ bind(&table_start); - Label needs_frame; - for (int i = 0; i < deopt_jump_table_.length(); i++) { - __ bind(&deopt_jump_table_[i].label); - Address entry = deopt_jump_table_[i].address; - Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; - int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); - if (id == Deoptimizer::kNotDeoptimizationEntry) { - Comment(";;; jump table entry %d.", i); - } else { + Address base = deopt_jump_table_[0].address; + + Register entry_offset = scratch0(); + + int length = deopt_jump_table_.length(); + for (int i = 0; i < length; i++) { + __ bind(&deopt_jump_table_[i].label); + + Deoptimizer::BailoutType type = deopt_jump_table_[i].bailout_type; + DCHECK(type == deopt_jump_table_[0].bailout_type); + Address entry = deopt_jump_table_[i].address; + int id = Deoptimizer::GetDeoptimizationId(isolate(), entry, type); + DCHECK(id != Deoptimizer::kNotDeoptimizationEntry); Comment(";;; jump table entry %d: deoptimization bailout %d.", i, id); - } - if (deopt_jump_table_[i].needs_frame) { - ASSERT(!info()->saves_caller_doubles()); - __ mov(ip, Operand(ExternalReference::ForDeoptEntry(entry))); - if (needs_frame.is_bound()) { - __ b(&needs_frame); + + // Second-level deopt table entries are contiguous and small, so instead + // of loading the full, absolute address of each one, load an immediate + // offset which will be added to the base address later. + __ mov(entry_offset, Operand(entry - base)); + + if (deopt_jump_table_[i].needs_frame) { + DCHECK(!info()->saves_caller_doubles()); + if (needs_frame.is_bound()) { + __ b(&needs_frame); + } else { + __ bind(&needs_frame); + Comment(";;; call deopt with frame"); + __ PushFixedFrame(); + // This variant of deopt can only be used with stubs. Since we don't + // have a function pointer to install in the stack frame that we're + // building, install a special marker there instead. + DCHECK(info()->IsStub()); + __ mov(ip, Operand(Smi::FromInt(StackFrame::STUB))); + __ push(ip); + __ add(fp, sp, + Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); + __ bind(&call_deopt_entry); + // Add the base address to the offset previously loaded in + // entry_offset. + __ add(entry_offset, entry_offset, + Operand(ExternalReference::ForDeoptEntry(base))); + __ blx(entry_offset); + } + + masm()->CheckConstPool(false, false); } else { - __ bind(&needs_frame); - __ PushFixedFrame(); - // This variant of deopt can only be used with stubs. Since we don't - // have a function pointer to install in the stack frame that we're - // building, install a special marker there instead. - ASSERT(info()->IsStub()); - __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB))); - __ push(scratch0()); - __ add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); - __ mov(lr, Operand(pc), LeaveCC, al); - __ mov(pc, ip); + // The last entry can fall through into `call_deopt_entry`, avoiding a + // branch. + bool need_branch = ((i + 1) != length) || call_deopt_entry.is_bound(); + + if (need_branch) __ b(&call_deopt_entry); + + masm()->CheckConstPool(false, !need_branch); } - } else { + } + + if (!call_deopt_entry.is_bound()) { + Comment(";;; call deopt"); + __ bind(&call_deopt_entry); + if (info()->saves_caller_doubles()) { - ASSERT(info()->IsStub()); + DCHECK(info()->IsStub()); RestoreCallerDoubles(); } - __ mov(lr, Operand(pc), LeaveCC, al); - __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry))); + + // Add the base address to the offset previously loaded in entry_offset. + __ add(entry_offset, entry_offset, + Operand(ExternalReference::ForDeoptEntry(base))); + __ blx(entry_offset); } - masm()->CheckConstPool(false, false); } // Force constant pool emission at the end of the deopt jump table to make @@ -380,7 +411,7 @@ bool LCodeGen::GenerateDeoptJumpTable() { bool LCodeGen::GenerateSafepointTable() { - ASSERT(is_done()); + DCHECK(is_done()); safepoints_.Emit(masm(), GetStackSlotCount()); return !is_aborted(); } @@ -397,7 +428,7 @@ DwVfpRegister LCodeGen::ToDoubleRegister(int index) const { Register LCodeGen::ToRegister(LOperand* op) const { - ASSERT(op->IsRegister()); + DCHECK(op->IsRegister()); return ToRegister(op->index()); } @@ -411,12 +442,12 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) { Handle literal = constant->handle(isolate()); Representation r = chunk_->LookupLiteralRepresentation(const_op); if (r.IsInteger32()) { - ASSERT(literal->IsNumber()); + DCHECK(literal->IsNumber()); __ mov(scratch, Operand(static_cast(literal->Number()))); } else if (r.IsDouble()) { Abort(kEmitLoadRegisterUnsupportedDoubleImmediate); } else { - ASSERT(r.IsSmiOrTagged()); + DCHECK(r.IsSmiOrTagged()); __ Move(scratch, literal); } return scratch; @@ -430,7 +461,7 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) { DwVfpRegister LCodeGen::ToDoubleRegister(LOperand* op) const { - ASSERT(op->IsDoubleRegister()); + DCHECK(op->IsDoubleRegister()); return ToDoubleRegister(op->index()); } @@ -446,7 +477,7 @@ DwVfpRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op, Handle literal = constant->handle(isolate()); Representation r = chunk_->LookupLiteralRepresentation(const_op); if (r.IsInteger32()) { - ASSERT(literal->IsNumber()); + DCHECK(literal->IsNumber()); __ mov(ip, Operand(static_cast(literal->Number()))); __ vmov(flt_scratch, ip); __ vcvt_f64_s32(dbl_scratch, flt_scratch); @@ -470,7 +501,7 @@ DwVfpRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op, Handle LCodeGen::ToHandle(LConstantOperand* op) const { HConstant* constant = chunk_->LookupConstant(op); - ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); + DCHECK(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); return constant->handle(isolate()); } @@ -495,7 +526,7 @@ int32_t LCodeGen::ToRepresentation(LConstantOperand* op, HConstant* constant = chunk_->LookupConstant(op); int32_t value = constant->Integer32Value(); if (r.IsInteger32()) return value; - ASSERT(r.IsSmiOrTagged()); + DCHECK(r.IsSmiOrTagged()); return reinterpret_cast(Smi::FromInt(value)); } @@ -508,7 +539,7 @@ Smi* LCodeGen::ToSmi(LConstantOperand* op) const { double LCodeGen::ToDouble(LConstantOperand* op) const { HConstant* constant = chunk_->LookupConstant(op); - ASSERT(constant->HasDoubleValue()); + DCHECK(constant->HasDoubleValue()); return constant->DoubleValue(); } @@ -519,15 +550,15 @@ Operand LCodeGen::ToOperand(LOperand* op) { HConstant* constant = chunk()->LookupConstant(const_op); Representation r = chunk_->LookupLiteralRepresentation(const_op); if (r.IsSmi()) { - ASSERT(constant->HasSmiValue()); + DCHECK(constant->HasSmiValue()); return Operand(Smi::FromInt(constant->Integer32Value())); } else if (r.IsInteger32()) { - ASSERT(constant->HasInteger32Value()); + DCHECK(constant->HasInteger32Value()); return Operand(constant->Integer32Value()); } else if (r.IsDouble()) { Abort(kToOperandUnsupportedDoubleImmediate); } - ASSERT(r.IsTagged()); + DCHECK(r.IsTagged()); return Operand(constant->handle(isolate())); } else if (op->IsRegister()) { return Operand(ToRegister(op)); @@ -542,15 +573,15 @@ Operand LCodeGen::ToOperand(LOperand* op) { static int ArgumentsOffsetWithoutFrame(int index) { - ASSERT(index < 0); + DCHECK(index < 0); return -(index + 1) * kPointerSize; } MemOperand LCodeGen::ToMemOperand(LOperand* op) const { - ASSERT(!op->IsRegister()); - ASSERT(!op->IsDoubleRegister()); - ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); + DCHECK(!op->IsRegister()); + DCHECK(!op->IsDoubleRegister()); + DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); if (NeedsEagerFrame()) { return MemOperand(fp, StackSlotOffset(op->index())); } else { @@ -562,7 +593,7 @@ MemOperand LCodeGen::ToMemOperand(LOperand* op) const { MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const { - ASSERT(op->IsDoubleStackSlot()); + DCHECK(op->IsDoubleStackSlot()); if (NeedsEagerFrame()) { return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize); } else { @@ -598,13 +629,13 @@ void LCodeGen::WriteTranslation(LEnvironment* environment, translation->BeginConstructStubFrame(closure_id, translation_size); break; case JS_GETTER: - ASSERT(translation_size == 1); - ASSERT(height == 0); + DCHECK(translation_size == 1); + DCHECK(height == 0); translation->BeginGetterStubFrame(closure_id); break; case JS_SETTER: - ASSERT(translation_size == 2); - ASSERT(height == 0); + DCHECK(translation_size == 2); + DCHECK(height == 0); translation->BeginSetterStubFrame(closure_id); break; case STUB: @@ -721,7 +752,7 @@ void LCodeGen::CallCodeGeneric(Handle code, LInstruction* instr, SafepointMode safepoint_mode, TargetAddressStorageMode storage_mode) { - ASSERT(instr != NULL); + DCHECK(instr != NULL); // Block literal pool emission to ensure nop indicating no inlined smi code // is in the correct position. Assembler::BlockConstPoolScope block_const_pool(masm()); @@ -741,7 +772,7 @@ void LCodeGen::CallRuntime(const Runtime::Function* function, int num_arguments, LInstruction* instr, SaveFPRegsMode save_doubles) { - ASSERT(instr != NULL); + DCHECK(instr != NULL); __ CallRuntime(function, num_arguments, save_doubles); @@ -816,9 +847,9 @@ void LCodeGen::DeoptimizeIf(Condition condition, LEnvironment* environment, Deoptimizer::BailoutType bailout_type) { RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); - ASSERT(environment->HasBeenRegistered()); + DCHECK(environment->HasBeenRegistered()); int id = environment->deoptimization_index(); - ASSERT(info()->IsOptimizing() || info()->IsStub()); + DCHECK(info()->IsOptimizing() || info()->IsStub()); Address entry = Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type); if (entry == NULL) { @@ -841,7 +872,7 @@ void LCodeGen::DeoptimizeIf(Condition condition, __ mov(scratch, Operand(count)); __ ldr(r1, MemOperand(scratch)); __ sub(r1, r1, Operand(1), SetCC); - __ movw(r1, FLAG_deopt_every_n_times, eq); + __ mov(r1, Operand(FLAG_deopt_every_n_times), LeaveCC, eq); __ str(r1, MemOperand(scratch)); __ pop(r1); @@ -865,7 +896,7 @@ void LCodeGen::DeoptimizeIf(Condition condition, __ stop("trap_on_deopt", condition); } - ASSERT(info()->IsStub() || frame_is_built_); + DCHECK(info()->IsStub() || frame_is_built_); // Go through jump table if we need to handle condition, build frame, or // restore caller doubles. if (condition == al && frame_is_built_ && @@ -901,7 +932,7 @@ void LCodeGen::PopulateDeoptimizationData(Handle code) { int length = deoptimizations_.length(); if (length == 0) return; Handle data = - DeoptimizationInputData::New(isolate(), length, TENURED); + DeoptimizationInputData::New(isolate(), length, 0, TENURED); Handle translations = translations_.CreateByteArray(isolate()->factory()); @@ -952,7 +983,7 @@ int LCodeGen::DefineDeoptimizationLiteral(Handle literal) { void LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() { - ASSERT(deoptimization_literals_.length() == 0); + DCHECK(deoptimization_literals_.length() == 0); const ZoneList >* inlined_closures = chunk()->inlined_closures(); @@ -972,7 +1003,7 @@ void LCodeGen::RecordSafepointWithLazyDeopt( if (safepoint_mode == RECORD_SIMPLE_SAFEPOINT) { RecordSafepoint(instr->pointer_map(), Safepoint::kLazyDeopt); } else { - ASSERT(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); + DCHECK(safepoint_mode == RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); RecordSafepointWithRegisters( instr->pointer_map(), 0, Safepoint::kLazyDeopt); } @@ -984,7 +1015,7 @@ void LCodeGen::RecordSafepoint( Safepoint::Kind kind, int arguments, Safepoint::DeoptMode deopt_mode) { - ASSERT(expected_safepoint_kind_ == kind); + DCHECK(expected_safepoint_kind_ == kind); const ZoneList* operands = pointers->GetNormalizedOperands(); Safepoint safepoint = safepoints_.DefineSafepoint(masm(), @@ -1024,15 +1055,6 @@ void LCodeGen::RecordSafepointWithRegisters(LPointerMap* pointers, } -void LCodeGen::RecordSafepointWithRegistersAndDoubles( - LPointerMap* pointers, - int arguments, - Safepoint::DeoptMode deopt_mode) { - RecordSafepoint( - pointers, Safepoint::kWithRegistersAndDoubles, arguments, deopt_mode); -} - - void LCodeGen::RecordAndWritePosition(int position) { if (position == RelocInfo::kNoPosition) return; masm()->positions_recorder()->RecordPosition(position); @@ -1086,8 +1108,8 @@ void LCodeGen::DoParameter(LParameter* instr) { void LCodeGen::DoCallStub(LCallStub* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->result()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->result()).is(r0)); switch (instr->hydrogen()->major_key()) { case CodeStub::RegExpExec: { RegExpExecStub stub(isolate()); @@ -1118,7 +1140,7 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { Register dividend = ToRegister(instr->dividend()); int32_t divisor = instr->divisor(); - ASSERT(dividend.is(ToRegister(instr->result()))); + DCHECK(dividend.is(ToRegister(instr->result()))); // Theoretically, a variation of the branch-free code for integer division by // a power of 2 (calculating the remainder via an additional multiplication @@ -1152,7 +1174,7 @@ void LCodeGen::DoModByConstI(LModByConstI* instr) { Register dividend = ToRegister(instr->dividend()); int32_t divisor = instr->divisor(); Register result = ToRegister(instr->result()); - ASSERT(!dividend.is(result)); + DCHECK(!dividend.is(result)); if (divisor == 0) { DeoptimizeIf(al, instr->environment()); @@ -1232,15 +1254,15 @@ void LCodeGen::DoModI(LModI* instr) { Register right_reg = ToRegister(instr->right()); Register result_reg = ToRegister(instr->result()); Register scratch = scratch0(); - ASSERT(!scratch.is(left_reg)); - ASSERT(!scratch.is(right_reg)); - ASSERT(!scratch.is(result_reg)); + DCHECK(!scratch.is(left_reg)); + DCHECK(!scratch.is(right_reg)); + DCHECK(!scratch.is(result_reg)); DwVfpRegister dividend = ToDoubleRegister(instr->temp()); DwVfpRegister divisor = ToDoubleRegister(instr->temp2()); - ASSERT(!divisor.is(dividend)); + DCHECK(!divisor.is(dividend)); LowDwVfpRegister quotient = double_scratch0(); - ASSERT(!quotient.is(dividend)); - ASSERT(!quotient.is(divisor)); + DCHECK(!quotient.is(dividend)); + DCHECK(!quotient.is(divisor)); Label done; // Check for x % 0, we have to deopt in this case because we can't return a @@ -1288,8 +1310,8 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { Register dividend = ToRegister(instr->dividend()); int32_t divisor = instr->divisor(); Register result = ToRegister(instr->result()); - ASSERT(divisor == kMinInt || IsPowerOf2(Abs(divisor))); - ASSERT(!result.is(dividend)); + DCHECK(divisor == kMinInt || IsPowerOf2(Abs(divisor))); + DCHECK(!result.is(dividend)); // Check for (0 / -x) that will produce negative zero. HDiv* hdiv = instr->hydrogen(); @@ -1332,7 +1354,7 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) { Register dividend = ToRegister(instr->dividend()); int32_t divisor = instr->divisor(); Register result = ToRegister(instr->result()); - ASSERT(!dividend.is(result)); + DCHECK(!dividend.is(result)); if (divisor == 0) { DeoptimizeIf(al, instr->environment()); @@ -1426,7 +1448,7 @@ void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { DwVfpRegister multiplicand = ToDoubleRegister(instr->multiplicand()); // This is computed in-place. - ASSERT(addend.is(ToDoubleRegister(instr->result()))); + DCHECK(addend.is(ToDoubleRegister(instr->result()))); __ vmla(addend, multiplier, multiplicand); } @@ -1438,7 +1460,7 @@ void LCodeGen::DoMultiplySubD(LMultiplySubD* instr) { DwVfpRegister multiplicand = ToDoubleRegister(instr->multiplicand()); // This is computed in-place. - ASSERT(minuend.is(ToDoubleRegister(instr->result()))); + DCHECK(minuend.is(ToDoubleRegister(instr->result()))); __ vmls(minuend, multiplier, multiplicand); } @@ -1492,7 +1514,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { Register dividend = ToRegister(instr->dividend()); int32_t divisor = instr->divisor(); Register result = ToRegister(instr->result()); - ASSERT(!dividend.is(result)); + DCHECK(!dividend.is(result)); if (divisor == 0) { DeoptimizeIf(al, instr->environment()); @@ -1518,7 +1540,7 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { // In the general case we may need to adjust before and after the truncating // division to get a flooring division. Register temp = ToRegister(instr->temp()); - ASSERT(!temp.is(dividend) && !temp.is(result)); + DCHECK(!temp.is(dividend) && !temp.is(result)); Label needs_adjustment, done; __ cmp(dividend, Operand::Zero()); __ b(divisor > 0 ? lt : gt, &needs_adjustment); @@ -1668,7 +1690,7 @@ void LCodeGen::DoMulI(LMulI* instr) { } } else { - ASSERT(right_op->IsRegister()); + DCHECK(right_op->IsRegister()); Register right = ToRegister(right_op); if (overflow) { @@ -1707,7 +1729,7 @@ void LCodeGen::DoMulI(LMulI* instr) { void LCodeGen::DoBitI(LBitI* instr) { LOperand* left_op = instr->left(); LOperand* right_op = instr->right(); - ASSERT(left_op->IsRegister()); + DCHECK(left_op->IsRegister()); Register left = ToRegister(left_op); Register result = ToRegister(instr->result()); Operand right(no_reg); @@ -1715,7 +1737,7 @@ void LCodeGen::DoBitI(LBitI* instr) { if (right_op->IsStackSlot()) { right = Operand(EmitLoadRegister(right_op, ip)); } else { - ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); + DCHECK(right_op->IsRegister() || right_op->IsConstantOperand()); right = ToOperand(right_op); } @@ -1839,7 +1861,7 @@ void LCodeGen::DoSubI(LSubI* instr) { Register right_reg = EmitLoadRegister(right, ip); __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); } else { - ASSERT(right->IsRegister() || right->IsConstantOperand()); + DCHECK(right->IsRegister() || right->IsConstantOperand()); __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); } @@ -1860,7 +1882,7 @@ void LCodeGen::DoRSubI(LRSubI* instr) { Register right_reg = EmitLoadRegister(right, ip); __ rsb(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); } else { - ASSERT(right->IsRegister() || right->IsConstantOperand()); + DCHECK(right->IsRegister() || right->IsConstantOperand()); __ rsb(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); } @@ -1881,7 +1903,7 @@ void LCodeGen::DoConstantS(LConstantS* instr) { void LCodeGen::DoConstantD(LConstantD* instr) { - ASSERT(instr->result()->IsDoubleRegister()); + DCHECK(instr->result()->IsDoubleRegister()); DwVfpRegister result = ToDoubleRegister(instr->result()); double v = instr->value(); __ Vmov(result, v, scratch0()); @@ -1913,10 +1935,10 @@ void LCodeGen::DoDateField(LDateField* instr) { Register scratch = ToRegister(instr->temp()); Smi* index = instr->index(); Label runtime, done; - ASSERT(object.is(result)); - ASSERT(object.is(r0)); - ASSERT(!scratch.is(scratch0())); - ASSERT(!scratch.is(object)); + DCHECK(object.is(result)); + DCHECK(object.is(r0)); + DCHECK(!scratch.is(scratch0())); + DCHECK(!scratch.is(object)); __ SmiTst(object); DeoptimizeIf(eq, instr->environment()); @@ -1958,8 +1980,8 @@ MemOperand LCodeGen::BuildSeqStringOperand(Register string, return FieldMemOperand(string, SeqString::kHeaderSize + offset); } Register scratch = scratch0(); - ASSERT(!scratch.is(string)); - ASSERT(!scratch.is(ToRegister(index))); + DCHECK(!scratch.is(string)); + DCHECK(!scratch.is(ToRegister(index))); if (encoding == String::ONE_BYTE_ENCODING) { __ add(scratch, string, Operand(ToRegister(index))); } else { @@ -2033,7 +2055,7 @@ void LCodeGen::DoAddI(LAddI* instr) { Register right_reg = EmitLoadRegister(right, ip); __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); } else { - ASSERT(right->IsRegister() || right->IsConstantOperand()); + DCHECK(right->IsRegister() || right->IsConstantOperand()); __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); } @@ -2058,7 +2080,7 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) { __ Move(result_reg, left_reg, condition); __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); } else { - ASSERT(instr->hydrogen()->representation().IsDouble()); + DCHECK(instr->hydrogen()->representation().IsDouble()); DwVfpRegister left_reg = ToDoubleRegister(left); DwVfpRegister right_reg = ToDoubleRegister(right); DwVfpRegister result_reg = ToDoubleRegister(instr->result()); @@ -2145,10 +2167,10 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { void LCodeGen::DoArithmeticT(LArithmeticT* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->left()).is(r1)); - ASSERT(ToRegister(instr->right()).is(r0)); - ASSERT(ToRegister(instr->result()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->left()).is(r1)); + DCHECK(ToRegister(instr->right()).is(r0)); + DCHECK(ToRegister(instr->result()).is(r0)); BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE); // Block literal pool emission to ensure nop indicating no inlined smi code @@ -2193,34 +2215,34 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) { void LCodeGen::DoBranch(LBranch* instr) { Representation r = instr->hydrogen()->value()->representation(); if (r.IsInteger32() || r.IsSmi()) { - ASSERT(!info()->IsStub()); + DCHECK(!info()->IsStub()); Register reg = ToRegister(instr->value()); __ cmp(reg, Operand::Zero()); EmitBranch(instr, ne); } else if (r.IsDouble()) { - ASSERT(!info()->IsStub()); + DCHECK(!info()->IsStub()); DwVfpRegister reg = ToDoubleRegister(instr->value()); // Test the double value. Zero and NaN are false. __ VFPCompareAndSetFlags(reg, 0.0); __ cmp(r0, r0, vs); // If NaN, set the Z flag. (NaN -> false) EmitBranch(instr, ne); } else { - ASSERT(r.IsTagged()); + DCHECK(r.IsTagged()); Register reg = ToRegister(instr->value()); HType type = instr->hydrogen()->value()->type(); if (type.IsBoolean()) { - ASSERT(!info()->IsStub()); + DCHECK(!info()->IsStub()); __ CompareRoot(reg, Heap::kTrueValueRootIndex); EmitBranch(instr, eq); } else if (type.IsSmi()) { - ASSERT(!info()->IsStub()); + DCHECK(!info()->IsStub()); __ cmp(reg, Operand::Zero()); EmitBranch(instr, ne); } else if (type.IsJSArray()) { - ASSERT(!info()->IsStub()); + DCHECK(!info()->IsStub()); EmitBranch(instr, al); } else if (type.IsHeapNumber()) { - ASSERT(!info()->IsStub()); + DCHECK(!info()->IsStub()); DwVfpRegister dbl_scratch = double_scratch0(); __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); // Test the double value. Zero and NaN are false. @@ -2228,7 +2250,7 @@ void LCodeGen::DoBranch(LBranch* instr) { __ cmp(r0, r0, vs); // If NaN, set the Z flag. (NaN) EmitBranch(instr, ne); } else if (type.IsString()) { - ASSERT(!info()->IsStub()); + DCHECK(!info()->IsStub()); __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); __ cmp(ip, Operand::Zero()); EmitBranch(instr, ne); @@ -2450,7 +2472,7 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) { void LCodeGen::DoCompareMinusZeroAndBranch(LCompareMinusZeroAndBranch* instr) { Representation rep = instr->hydrogen()->value()->representation(); - ASSERT(!rep.IsInteger32()); + DCHECK(!rep.IsInteger32()); Register scratch = ToRegister(instr->temp()); if (rep.IsDouble()) { @@ -2583,7 +2605,7 @@ static Condition ComputeCompareCondition(Token::Value op) { void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->context()).is(cp)); Token::Value op = instr->op(); Handle ic = CompareIC::GetUninitialized(isolate(), op); @@ -2601,7 +2623,7 @@ static InstanceType TestType(HHasInstanceTypeAndBranch* instr) { InstanceType from = instr->from(); InstanceType to = instr->to(); if (from == FIRST_TYPE) return to; - ASSERT(from == to || to == LAST_TYPE); + DCHECK(from == to || to == LAST_TYPE); return from; } @@ -2661,9 +2683,9 @@ void LCodeGen::EmitClassOfTest(Label* is_true, Register input, Register temp, Register temp2) { - ASSERT(!input.is(temp)); - ASSERT(!input.is(temp2)); - ASSERT(!temp.is(temp2)); + DCHECK(!input.is(temp)); + DCHECK(!input.is(temp2)); + DCHECK(!temp.is(temp2)); __ JumpIfSmi(input, is_false); @@ -2744,9 +2766,9 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { void LCodeGen::DoInstanceOf(LInstanceOf* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->left()).is(r0)); // Object is in r0. - ASSERT(ToRegister(instr->right()).is(r1)); // Function is in r1. + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->left()).is(r0)); // Object is in r0. + DCHECK(ToRegister(instr->right()).is(r1)); // Function is in r1. InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters); CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); @@ -2764,13 +2786,17 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { LInstanceOfKnownGlobal* instr) : LDeferredCode(codegen), instr_(instr) { } virtual void Generate() V8_OVERRIDE { - codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); + codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_, + &load_bool_); } virtual LInstruction* instr() V8_OVERRIDE { return instr_; } Label* map_check() { return &map_check_; } + Label* load_bool() { return &load_bool_; } + private: LInstanceOfKnownGlobal* instr_; Label map_check_; + Label load_bool_; }; DeferredInstanceOfKnownGlobal* deferred; @@ -2798,12 +2824,12 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { // We use Factory::the_hole_value() on purpose instead of loading from the // root array to force relocation to be able to later patch with // the cached map. - PredictableCodeSizeScope predictable(masm_, 5 * Assembler::kInstrSize); Handle cell = factory()->NewCell(factory()->the_hole_value()); __ mov(ip, Operand(Handle(cell))); __ ldr(ip, FieldMemOperand(ip, PropertyCell::kValueOffset)); __ cmp(map, Operand(ip)); __ b(ne, &cache_miss); + __ bind(deferred->load_bool()); // Label for calculating code patching. // We use Factory::the_hole_value() on purpose instead of loading from the // root array to force relocation to be able to later patch // with true or false. @@ -2837,7 +2863,8 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, - Label* map_check) { + Label* map_check, + Label* bool_load) { InstanceofStub::Flags flags = InstanceofStub::kNoFlags; flags = static_cast( flags | InstanceofStub::kArgsInRegisters); @@ -2847,25 +2874,39 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, flags | InstanceofStub::kReturnTrueFalseObject); InstanceofStub stub(isolate(), flags); - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); LoadContextFromDeferred(instr->context()); __ Move(InstanceofStub::right(), instr->function()); - static const int kAdditionalDelta = 4; + + int call_size = CallCodeSize(stub.GetCode(), RelocInfo::CODE_TARGET); + int additional_delta = (call_size / Assembler::kInstrSize) + 4; // Make sure that code size is predicable, since we use specific constants // offsets in the code to find embedded values.. - PredictableCodeSizeScope predictable(masm_, 5 * Assembler::kInstrSize); - int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta; - Label before_push_delta; - __ bind(&before_push_delta); - __ BlockConstPoolFor(kAdditionalDelta); - // r5 is used to communicate the offset to the location of the map check. - __ mov(r5, Operand(delta * kPointerSize)); - // The mov above can generate one or two instructions. The delta was computed - // for two instructions, so we need to pad here in case of one instruction. - if (masm_->InstructionsGeneratedSince(&before_push_delta) != 2) { - ASSERT_EQ(1, masm_->InstructionsGeneratedSince(&before_push_delta)); - __ nop(); + PredictableCodeSizeScope predictable( + masm_, (additional_delta + 1) * Assembler::kInstrSize); + // Make sure we don't emit any additional entries in the constant pool before + // the call to ensure that the CallCodeSize() calculated the correct number of + // instructions for the constant pool load. + { + ConstantPoolUnavailableScope constant_pool_unavailable(masm_); + int map_check_delta = + masm_->InstructionsGeneratedSince(map_check) + additional_delta; + int bool_load_delta = + masm_->InstructionsGeneratedSince(bool_load) + additional_delta; + Label before_push_delta; + __ bind(&before_push_delta); + __ BlockConstPoolFor(additional_delta); + // r5 is used to communicate the offset to the location of the map check. + __ mov(r5, Operand(map_check_delta * kPointerSize)); + // r6 is used to communicate the offset to the location of the bool load. + __ mov(r6, Operand(bool_load_delta * kPointerSize)); + // The mov above can generate one or two instructions. The delta was + // computed for two instructions, so we need to pad here in case of one + // instruction. + while (masm_->InstructionsGeneratedSince(&before_push_delta) != 4) { + __ nop(); + } } CallCodeGeneric(stub.GetCode(), RelocInfo::CODE_TARGET, @@ -2880,7 +2921,7 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, void LCodeGen::DoCmpT(LCmpT* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->context()).is(cp)); Token::Value op = instr->op(); Handle ic = CompareIC::GetUninitialized(isolate(), op); @@ -2949,11 +2990,20 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->global_object()).is(r0)); - ASSERT(ToRegister(instr->result()).is(r0)); - - __ mov(r2, Operand(instr->name())); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister())); + DCHECK(ToRegister(instr->result()).is(r0)); + + __ mov(LoadIC::NameRegister(), Operand(instr->name())); + if (FLAG_vector_ics) { + Register vector = ToRegister(instr->temp_vector()); + DCHECK(vector.is(LoadIC::VectorRegister())); + __ Move(vector, instr->hydrogen()->feedback_vector()); + // No need to allocate this register. + DCHECK(LoadIC::SlotRegister().is(r0)); + __ mov(LoadIC::SlotRegister(), + Operand(Smi::FromInt(instr->hydrogen()->slot()))); + } ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; Handle ic = LoadIC::initialize_stub(isolate(), mode); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -3068,12 +3118,21 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(r0)); - ASSERT(ToRegister(instr->result()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); + DCHECK(ToRegister(instr->result()).is(r0)); // Name is always in r2. - __ mov(r2, Operand(instr->name())); + __ mov(LoadIC::NameRegister(), Operand(instr->name())); + if (FLAG_vector_ics) { + Register vector = ToRegister(instr->temp_vector()); + DCHECK(vector.is(LoadIC::VectorRegister())); + __ Move(vector, instr->hydrogen()->feedback_vector()); + // No need to allocate this register. + DCHECK(LoadIC::SlotRegister().is(r0)); + __ mov(LoadIC::SlotRegister(), + Operand(Smi::FromInt(instr->hydrogen()->slot()))); + } Handle ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); } @@ -3084,17 +3143,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { Register function = ToRegister(instr->function()); Register result = ToRegister(instr->result()); - // Check that the function really is a function. Load map into the - // result register. - __ CompareObjectType(function, result, scratch, JS_FUNCTION_TYPE); - DeoptimizeIf(ne, instr->environment()); - - // Make sure that the function has an instance prototype. - Label non_instance; - __ ldrb(scratch, FieldMemOperand(result, Map::kBitFieldOffset)); - __ tst(scratch, Operand(1 << Map::kHasNonInstancePrototype)); - __ b(ne, &non_instance); - // Get the prototype or initial map from the function. __ ldr(result, FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); @@ -3111,12 +3159,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { // Get the prototype from the initial map. __ ldr(result, FieldMemOperand(result, Map::kPrototypeOffset)); - __ jmp(&done); - - // Non-instance prototype: Fetch prototype from constructor field - // in initial map. - __ bind(&non_instance); - __ ldr(result, FieldMemOperand(result, Map::kConstructorOffset)); // All done. __ bind(&done); @@ -3165,93 +3207,6 @@ void LCodeGen::DoAccessArgumentsAt(LAccessArgumentsAt* instr) { } -void LCodeGen::DoDeferredSIMD128ToTagged(LInstruction* instr, - Runtime::FunctionId id) { - // TODO(3095996): Get rid of this. For now, we need to make the - // result register contain a valid pointer because it is already - // contained in the register pointer map. - Register reg = ToRegister(instr->result()); - __ mov(reg, Operand::Zero()); - - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); - __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - __ CallRuntimeSaveDoubles(id); - RecordSafepointWithRegisters( - instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); - __ sub(r0, r0, Operand(kHeapObjectTag)); - __ StoreToSafepointRegisterSlot(r0, reg); -} - - -template -void LCodeGen::DoLoadKeyedSIMD128ExternalArray(LLoadKeyed* instr) { - class DeferredSIMD128ToTagged V8_FINAL : public LDeferredCode { - public: - DeferredSIMD128ToTagged(LCodeGen* codegen, LInstruction* instr, - Runtime::FunctionId id) - : LDeferredCode(codegen), instr_(instr), id_(id) { } - virtual void Generate() V8_OVERRIDE { - codegen()->DoDeferredSIMD128ToTagged(instr_, id_); - } - virtual LInstruction* instr() V8_OVERRIDE { return instr_; } - private: - LInstruction* instr_; - Runtime::FunctionId id_; - }; - - // Allocate a SIMD128 object on the heap. - Register reg = ToRegister(instr->result()); - Register temp = ToRegister(instr->temp()); - Register temp2 = ToRegister(instr->temp2()); - Register scratch = scratch0(); - - DeferredSIMD128ToTagged* deferred = new(zone()) DeferredSIMD128ToTagged( - this, instr, static_cast(T::kRuntimeAllocatorId())); - __ jmp(deferred->entry()); - __ bind(deferred->exit()); - - // Copy the SIMD128 value from the external array to the heap object. - STATIC_ASSERT(T::kValueSize % kPointerSize == 0); - Register external_pointer = ToRegister(instr->elements()); - Register key = no_reg; - ElementsKind elements_kind = instr->elements_kind(); - bool key_is_constant = instr->key()->IsConstantOperand(); - int constant_key = 0; - if (key_is_constant) { - constant_key = ToInteger32(LConstantOperand::cast(instr->key())); - if (constant_key & 0xF0000000) { - Abort(kArrayIndexConstantValueTooBig); - } - } else { - key = ToRegister(instr->key()); - } - int element_size_shift = ElementsKindToShiftSize(elements_kind); - int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) - ? (element_size_shift - kSmiTagSize) : element_size_shift; - int base_offset = instr->base_offset(); - Operand operand = key_is_constant - ? Operand(constant_key << element_size_shift) - : Operand(key, LSL, shift_size); - - __ add(scratch, external_pointer, operand); - - // Load the inner FixedTypedArray. - __ ldr(temp2, MemOperand(reg, T::kValueOffset)); - - for (int offset = 0; offset < T::kValueSize; offset += kPointerSize) { - __ ldr(temp, MemOperand(scratch, base_offset + offset)); - __ str( - temp, - MemOperand( - temp2, - FixedTypedArrayBase::kDataOffset - kHeapObjectTag + offset)); - } - - // Now that we have finished with the object's real address tag it - __ add(reg, reg, Operand(kHeapObjectTag)); -} - - void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { Register external_pointer = ToRegister(instr->elements()); Register key = no_reg; @@ -3288,12 +3243,6 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS __ vldr(result, scratch0(), base_offset); } - } else if (IsFloat32x4ElementsKind(elements_kind)) { - DoLoadKeyedSIMD128ExternalArray(instr); - } else if (IsFloat64x2ElementsKind(elements_kind)) { - DoLoadKeyedSIMD128ExternalArray(instr); - } else if (IsInt32x4ElementsKind(elements_kind)) { - DoLoadKeyedSIMD128ExternalArray(instr); } else { Register result = ToRegister(instr->result()); MemOperand mem_operand = PrepareKeyedOperand( @@ -3334,12 +3283,6 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { case FLOAT64_ELEMENTS: case EXTERNAL_FLOAT32_ELEMENTS: case EXTERNAL_FLOAT64_ELEMENTS: - case FLOAT32x4_ELEMENTS: - case FLOAT64x2_ELEMENTS: - case INT32x4_ELEMENTS: - case EXTERNAL_FLOAT32x4_ELEMENTS: - case EXTERNAL_FLOAT64x2_ELEMENTS: - case EXTERNAL_INT32x4_ELEMENTS: case FAST_HOLEY_DOUBLE_ELEMENTS: case FAST_HOLEY_ELEMENTS: case FAST_HOLEY_SMI_ELEMENTS: @@ -3456,7 +3399,7 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key, if (shift_size >= 0) { return MemOperand(base, key, LSL, shift_size); } else { - ASSERT_EQ(-1, shift_size); + DCHECK_EQ(-1, shift_size); return MemOperand(base, key, LSR, 1); } } @@ -3465,7 +3408,7 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key, __ add(scratch0(), base, Operand(key, LSL, shift_size)); return MemOperand(scratch0(), base_offset); } else { - ASSERT_EQ(-1, shift_size); + DCHECK_EQ(-1, shift_size); __ add(scratch0(), base, Operand(key, ASR, 1)); return MemOperand(scratch0(), base_offset); } @@ -3473,9 +3416,19 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key, void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(r1)); - ASSERT(ToRegister(instr->key()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->object()).is(LoadIC::ReceiverRegister())); + DCHECK(ToRegister(instr->key()).is(LoadIC::NameRegister())); + + if (FLAG_vector_ics) { + Register vector = ToRegister(instr->temp_vector()); + DCHECK(vector.is(LoadIC::VectorRegister())); + __ Move(vector, instr->hydrogen()->feedback_vector()); + // No need to allocate this register. + DCHECK(LoadIC::SlotRegister().is(r0)); + __ mov(LoadIC::SlotRegister(), + Operand(Smi::FromInt(instr->hydrogen()->slot()))); + } Handle ic = isolate()->builtins()->KeyedLoadIC_Initialize(); CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); @@ -3571,8 +3524,7 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) { __ ldr(result, FieldMemOperand(function, JSFunction::kContextOffset)); __ ldr(result, ContextOperand(result, Context::GLOBAL_OBJECT_INDEX)); - __ ldr(result, - FieldMemOperand(result, GlobalObject::kGlobalReceiverOffset)); + __ ldr(result, FieldMemOperand(result, GlobalObject::kGlobalProxyOffset)); if (result.is(receiver)) { __ bind(&result_in_receiver); @@ -3592,9 +3544,9 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { Register length = ToRegister(instr->length()); Register elements = ToRegister(instr->elements()); Register scratch = scratch0(); - ASSERT(receiver.is(r0)); // Used for parameter count. - ASSERT(function.is(r1)); // Required by InvokeFunction. - ASSERT(ToRegister(instr->result()).is(r0)); + DCHECK(receiver.is(r0)); // Used for parameter count. + DCHECK(function.is(r1)); // Required by InvokeFunction. + DCHECK(ToRegister(instr->result()).is(r0)); // Copy the arguments to this function possibly from the // adaptor frame below it. @@ -3622,7 +3574,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { __ b(ne, &loop); __ bind(&invoke); - ASSERT(instr->HasPointerMap()); + DCHECK(instr->HasPointerMap()); LPointerMap* pointers = instr->pointer_map(); SafepointGenerator safepoint_generator( this, pointers, Safepoint::kLazyDeopt); @@ -3662,19 +3614,19 @@ void LCodeGen::DoContext(LContext* instr) { __ ldr(result, MemOperand(fp, StandardFrameConstants::kContextOffset)); } else { // If there is no frame, the context must be in cp. - ASSERT(result.is(cp)); + DCHECK(result.is(cp)); } } void LCodeGen::DoDeclareGlobals(LDeclareGlobals* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->context()).is(cp)); __ push(cp); // The context is the first argument. __ Move(scratch0(), instr->hydrogen()->pairs()); __ push(scratch0()); __ mov(scratch0(), Operand(Smi::FromInt(instr->hydrogen()->flags()))); __ push(scratch0()); - CallRuntime(Runtime::kHiddenDeclareGlobals, 3, instr); + CallRuntime(Runtime::kDeclareGlobals, 3, instr); } @@ -3720,8 +3672,8 @@ void LCodeGen::CallKnownFunction(Handle function, void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { - ASSERT(instr->context() != NULL); - ASSERT(ToRegister(instr->context()).is(cp)); + DCHECK(instr->context() != NULL); + DCHECK(ToRegister(instr->context()).is(cp)); Register input = ToRegister(instr->value()); Register result = ToRegister(instr->result()); Register scratch = scratch0(); @@ -3746,7 +3698,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { // Input is negative. Reverse its sign. // Preserve the value of all registers. { - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); // Registers were saved at the safepoint, so we can use // many scratch registers. @@ -3765,7 +3717,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr) { // Slow case: Call the runtime system to do the number allocation. __ bind(&slow); - CallRuntimeFromDeferred(Runtime::kHiddenAllocateHeapNumber, 0, instr, + CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr, instr->context()); // Set the pointer to the new heap number in tmp. if (!tmp1.is(r0)) __ mov(tmp1, Operand(r0)); @@ -3896,6 +3848,15 @@ void LCodeGen::DoMathRound(LMathRound* instr) { } +void LCodeGen::DoMathFround(LMathFround* instr) { + DwVfpRegister input_reg = ToDoubleRegister(instr->value()); + DwVfpRegister output_reg = ToDoubleRegister(instr->result()); + LowDwVfpRegister scratch = double_scratch0(); + __ vcvt_f32_f64(scratch.low(), input_reg); + __ vcvt_f64_f32(output_reg, scratch.low()); +} + + void LCodeGen::DoMathSqrt(LMathSqrt* instr) { DwVfpRegister input = ToDoubleRegister(instr->value()); DwVfpRegister result = ToDoubleRegister(instr->result()); @@ -3928,12 +3889,12 @@ void LCodeGen::DoPower(LPower* instr) { Representation exponent_type = instr->hydrogen()->right()->representation(); // Having marked this as a call, we can use any registers. // Just make sure that the input/output registers are the expected ones. - ASSERT(!instr->right()->IsDoubleRegister() || + DCHECK(!instr->right()->IsDoubleRegister() || ToDoubleRegister(instr->right()).is(d1)); - ASSERT(!instr->right()->IsRegister() || + DCHECK(!instr->right()->IsRegister() || ToRegister(instr->right()).is(r2)); - ASSERT(ToDoubleRegister(instr->left()).is(d0)); - ASSERT(ToDoubleRegister(instr->result()).is(d2)); + DCHECK(ToDoubleRegister(instr->left()).is(d0)); + DCHECK(ToDoubleRegister(instr->result()).is(d2)); if (exponent_type.IsSmi()) { MathPowStub stub(isolate(), MathPowStub::TAGGED); @@ -3952,7 +3913,7 @@ void LCodeGen::DoPower(LPower* instr) { MathPowStub stub(isolate(), MathPowStub::INTEGER); __ CallStub(&stub); } else { - ASSERT(exponent_type.IsDouble()); + DCHECK(exponent_type.IsDouble()); MathPowStub stub(isolate(), MathPowStub::DOUBLE); __ CallStub(&stub); } @@ -3990,9 +3951,9 @@ void LCodeGen::DoMathClz32(LMathClz32* instr) { void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->function()).is(r1)); - ASSERT(instr->HasPointerMap()); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->function()).is(r1)); + DCHECK(instr->HasPointerMap()); Handle known_function = instr->hydrogen()->known_function(); if (known_function.is_null()) { @@ -4011,7 +3972,7 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) { void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { - ASSERT(ToRegister(instr->result()).is(r0)); + DCHECK(ToRegister(instr->result()).is(r0)); LPointerMap* pointers = instr->pointer_map(); SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt); @@ -4020,15 +3981,21 @@ void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { LConstantOperand* target = LConstantOperand::cast(instr->target()); Handle code = Handle::cast(ToHandle(target)); generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET)); - PlatformCallInterfaceDescriptor* call_descriptor = + PlatformInterfaceDescriptor* call_descriptor = instr->descriptor()->platform_specific_descriptor(); __ Call(code, RelocInfo::CODE_TARGET, TypeFeedbackId::None(), al, call_descriptor->storage_mode()); } else { - ASSERT(instr->target()->IsRegister()); + DCHECK(instr->target()->IsRegister()); Register target = ToRegister(instr->target()); generator.BeforeCall(__ CallSize(target)); - __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); + // Make sure we don't emit any additional entries in the constant pool + // before the call to ensure that the CallCodeSize() calculated the correct + // number of instructions for the constant pool load. + { + ConstantPoolUnavailableScope constant_pool_unavailable(masm_); + __ add(target, target, Operand(Code::kHeaderSize - kHeapObjectTag)); + } __ Call(target); } generator.AfterCall(); @@ -4036,8 +4003,8 @@ void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) { void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { - ASSERT(ToRegister(instr->function()).is(r1)); - ASSERT(ToRegister(instr->result()).is(r0)); + DCHECK(ToRegister(instr->function()).is(r1)); + DCHECK(ToRegister(instr->result()).is(r0)); if (instr->hydrogen()->pass_argument_count()) { __ mov(r0, Operand(instr->arity())); @@ -4055,9 +4022,9 @@ void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) { void LCodeGen::DoCallFunction(LCallFunction* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->function()).is(r1)); - ASSERT(ToRegister(instr->result()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->function()).is(r1)); + DCHECK(ToRegister(instr->result()).is(r0)); int arity = instr->arity(); CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags()); @@ -4066,9 +4033,9 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { void LCodeGen::DoCallNew(LCallNew* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->constructor()).is(r1)); - ASSERT(ToRegister(instr->result()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->constructor()).is(r1)); + DCHECK(ToRegister(instr->result()).is(r0)); __ mov(r0, Operand(instr->arity())); // No cell in r2 for construct type feedback in optimized code @@ -4079,9 +4046,9 @@ void LCodeGen::DoCallNew(LCallNew* instr) { void LCodeGen::DoCallNewArray(LCallNewArray* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->constructor()).is(r1)); - ASSERT(ToRegister(instr->result()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->constructor()).is(r1)); + DCHECK(ToRegister(instr->result()).is(r0)); __ mov(r0, Operand(instr->arity())); __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); @@ -4167,13 +4134,13 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { __ AssertNotSmi(object); - ASSERT(!representation.IsSmi() || + DCHECK(!representation.IsSmi() || !instr->value()->IsConstantOperand() || IsSmi(LConstantOperand::cast(instr->value()))); if (representation.IsDouble()) { - ASSERT(access.IsInobject()); - ASSERT(!instr->hydrogen()->has_transition()); - ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); + DCHECK(access.IsInobject()); + DCHECK(!instr->hydrogen()->has_transition()); + DCHECK(!instr->hydrogen()->NeedsWriteBarrier()); DwVfpRegister value = ToDoubleRegister(instr->value()); __ vstr(value, FieldMemOperand(object, offset)); return; @@ -4234,12 +4201,11 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(r1)); - ASSERT(ToRegister(instr->value()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->object()).is(StoreIC::ReceiverRegister())); + DCHECK(ToRegister(instr->value()).is(StoreIC::ValueRegister())); - // Name is always in r2. - __ mov(r2, Operand(instr->name())); + __ mov(StoreIC::NameRegister(), Operand(instr->name())); Handle ic = StoreIC::initialize_stub(isolate(), instr->strict_mode()); CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); } @@ -4268,58 +4234,6 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { } -template -void LCodeGen::DoStoreKeyedSIMD128ExternalArray(LStoreKeyed* instr) { - ASSERT(instr->value()->IsRegister()); - Register temp = ToRegister(instr->temp()); - Register temp2 = ToRegister(instr->temp2()); - Register input_reg = ToRegister(instr->value()); - __ SmiTst(input_reg); - DeoptimizeIf(eq, instr->environment()); - __ CompareObjectType(input_reg, temp, no_reg, T::kInstanceType); - DeoptimizeIf(ne, instr->environment()); - - STATIC_ASSERT(T::kValueSize % kPointerSize == 0); - Register external_pointer = ToRegister(instr->elements()); - Register key = no_reg; - ElementsKind elements_kind = instr->elements_kind(); - bool key_is_constant = instr->key()->IsConstantOperand(); - int constant_key = 0; - if (key_is_constant) { - constant_key = ToInteger32(LConstantOperand::cast(instr->key())); - if (constant_key & 0xF0000000) { - Abort(kArrayIndexConstantValueTooBig); - } - } else { - key = ToRegister(instr->key()); - } - int element_size_shift = ElementsKindToShiftSize(elements_kind); - int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) - ? (element_size_shift - kSmiTagSize) : element_size_shift; - int base_offset = instr->base_offset(); - Register address = scratch0(); - if (key_is_constant) { - if (constant_key != 0) { - __ add(address, external_pointer, - Operand(constant_key << element_size_shift)); - } else { - address = external_pointer; - } - } else { - __ add(address, external_pointer, Operand(key, LSL, shift_size)); - } - - // Load the inner FixedTypedArray. - __ ldr(temp2, MemOperand(input_reg, T::kValueOffset - kHeapObjectTag)); - - for (int offset = 0; offset < T::kValueSize; offset += kPointerSize) { - __ ldr(temp, MemOperand(temp2, - FixedTypedArrayBase::kDataOffset - kHeapObjectTag + offset)); - __ str(temp, MemOperand(address, base_offset + offset)); - } -} - - void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { Register external_pointer = ToRegister(instr->elements()); Register key = no_reg; @@ -4362,12 +4276,6 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { } else { // Storing doubles, not floats. __ vstr(value, address, base_offset); } - } else if (IsFloat32x4ElementsKind(elements_kind)) { - DoStoreKeyedSIMD128ExternalArray(instr); - } else if (IsFloat64x2ElementsKind(elements_kind)) { - DoStoreKeyedSIMD128ExternalArray(instr); - } else if (IsInt32x4ElementsKind(elements_kind)) { - DoStoreKeyedSIMD128ExternalArray(instr); } else { Register value(ToRegister(instr->value())); MemOperand mem_operand = PrepareKeyedOperand( @@ -4399,12 +4307,6 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { case FLOAT64_ELEMENTS: case EXTERNAL_FLOAT32_ELEMENTS: case EXTERNAL_FLOAT64_ELEMENTS: - case FLOAT32x4_ELEMENTS: - case FLOAT64x2_ELEMENTS: - case INT32x4_ELEMENTS: - case EXTERNAL_FLOAT32x4_ELEMENTS: - case EXTERNAL_FLOAT64x2_ELEMENTS: - case EXTERNAL_INT32x4_ELEMENTS: case FAST_DOUBLE_ELEMENTS: case FAST_ELEMENTS: case FAST_SMI_ELEMENTS: @@ -4472,7 +4374,7 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { // Do the store. if (instr->key()->IsConstantOperand()) { - ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); + DCHECK(!instr->hydrogen()->NeedsWriteBarrier()); LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); offset += ToInteger32(const_operand) * kPointerSize; store_base = elements; @@ -4520,10 +4422,10 @@ void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->object()).is(r2)); - ASSERT(ToRegister(instr->key()).is(r1)); - ASSERT(ToRegister(instr->value()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->object()).is(KeyedStoreIC::ReceiverRegister())); + DCHECK(ToRegister(instr->key()).is(KeyedStoreIC::NameRegister())); + DCHECK(ToRegister(instr->value()).is(KeyedStoreIC::ValueRegister())); Handle ic = instr->strict_mode() == STRICT ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() @@ -4557,15 +4459,14 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) { GetLinkRegisterState(), kDontSaveFPRegs); } else { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(object_reg.is(r0)); - PushSafepointRegistersScope scope( - this, Safepoint::kWithRegistersAndDoubles); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(object_reg.is(r0)); + PushSafepointRegistersScope scope(this); __ Move(r1, to_map); bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE; TransitionElementsKindStub stub(isolate(), from_kind, to_kind, is_js_array); __ CallStub(&stub); - RecordSafepointWithRegistersAndDoubles( + RecordSafepointWithRegisters( instr->pointer_map(), 0, Safepoint::kLazyDeopt); } __ bind(¬_applicable); @@ -4583,9 +4484,9 @@ void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) { void LCodeGen::DoStringAdd(LStringAdd* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); - ASSERT(ToRegister(instr->left()).is(r1)); - ASSERT(ToRegister(instr->right()).is(r0)); + DCHECK(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->left()).is(r1)); + DCHECK(ToRegister(instr->right()).is(r0)); StringAddStub stub(isolate(), instr->hydrogen()->flags(), instr->hydrogen()->pretenure_flag()); @@ -4628,7 +4529,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { // contained in the register pointer map. __ mov(result, Operand::Zero()); - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); __ push(string); // Push the index as a smi. This is safe because of the checks in // DoStringCharCodeAt above. @@ -4641,7 +4542,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) { __ SmiTag(index); __ push(index); } - CallRuntimeFromDeferred(Runtime::kHiddenStringCharCodeAt, 2, instr, + CallRuntimeFromDeferred(Runtime::kStringCharCodeAtRT, 2, instr, instr->context()); __ AssertSmi(r0); __ SmiUntag(r0); @@ -4665,10 +4566,10 @@ void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { DeferredStringCharFromCode* deferred = new(zone()) DeferredStringCharFromCode(this, instr); - ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); + DCHECK(instr->hydrogen()->value()->representation().IsInteger32()); Register char_code = ToRegister(instr->char_code()); Register result = ToRegister(instr->result()); - ASSERT(!char_code.is(result)); + DCHECK(!char_code.is(result)); __ cmp(char_code, Operand(String::kMaxOneByteCharCode)); __ b(hi, deferred->entry()); @@ -4691,7 +4592,7 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { // contained in the register pointer map. __ mov(result, Operand::Zero()); - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); __ SmiTag(char_code); __ push(char_code); CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context()); @@ -4701,9 +4602,9 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) { void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { LOperand* input = instr->value(); - ASSERT(input->IsRegister() || input->IsStackSlot()); + DCHECK(input->IsRegister() || input->IsStackSlot()); LOperand* output = instr->result(); - ASSERT(output->IsDoubleRegister()); + DCHECK(output->IsDoubleRegister()); SwVfpRegister single_scratch = double_scratch0().low(); if (input->IsStackSlot()) { Register scratch = scratch0(); @@ -4824,15 +4725,15 @@ void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr, __ mov(dst, Operand::Zero()); // Preserve the value of all registers. - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); // NumberTagI and NumberTagD use the context from the frame, rather than // the environment's HContext or HInlinedContext value. - // They only call Runtime::kHiddenAllocateHeapNumber. + // They only call Runtime::kAllocateHeapNumber. // The corresponding HChange instructions are added in a phase that does // not have easy access to the local context. __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - __ CallRuntimeSaveDoubles(Runtime::kHiddenAllocateHeapNumber); + __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); RecordSafepointWithRegisters( instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); __ sub(r0, r0, Operand(kHeapObjectTag)); @@ -4889,14 +4790,14 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { Register reg = ToRegister(instr->result()); __ mov(reg, Operand::Zero()); - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); // NumberTagI and NumberTagD use the context from the frame, rather than // the environment's HContext or HInlinedContext value. - // They only call Runtime::kHiddenAllocateHeapNumber. + // They only call Runtime::kAllocateHeapNumber. // The corresponding HChange instructions are added in a phase that does // not have easy access to the local context. __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - __ CallRuntimeSaveDoubles(Runtime::kHiddenAllocateHeapNumber); + __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); RecordSafepointWithRegisters( instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); __ sub(r0, r0, Operand(kHeapObjectTag)); @@ -4945,7 +4846,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, NumberUntagDMode mode) { Register scratch = scratch0(); SwVfpRegister flt_scratch = double_scratch0().low(); - ASSERT(!result_reg.is(double_scratch0())); + DCHECK(!result_reg.is(double_scratch0())); Label convert, load_smi, done; if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) { // Smi check. @@ -4982,7 +4883,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, } } else { __ SmiUntag(scratch, input_reg); - ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); + DCHECK(mode == NUMBER_CANDIDATE_IS_SMI); } // Smi to double register conversion __ bind(&load_smi); @@ -5000,8 +4901,8 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { LowDwVfpRegister double_scratch = double_scratch0(); DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp2()); - ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2)); - ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1)); + DCHECK(!scratch1.is(input_reg) && !scratch1.is(scratch2)); + DCHECK(!scratch2.is(input_reg) && !scratch2.is(scratch1)); Label done; @@ -5081,8 +4982,8 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) { }; LOperand* input = instr->value(); - ASSERT(input->IsRegister()); - ASSERT(input->Equals(instr->result())); + DCHECK(input->IsRegister()); + DCHECK(input->Equals(instr->result())); Register input_reg = ToRegister(input); @@ -5104,9 +5005,9 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) { void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { LOperand* input = instr->value(); - ASSERT(input->IsRegister()); + DCHECK(input->IsRegister()); LOperand* result = instr->result(); - ASSERT(result->IsDoubleRegister()); + DCHECK(result->IsDoubleRegister()); Register input_reg = ToRegister(input); DwVfpRegister result_reg = ToDoubleRegister(result); @@ -5222,7 +5123,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag); if (IsPowerOf2(mask)) { - ASSERT(tag == 0 || IsPowerOf2(tag)); + DCHECK(tag == 0 || IsPowerOf2(tag)); __ tst(scratch, Operand(mask)); DeoptimizeIf(tag == 0 ? ne : eq, instr->environment()); } else { @@ -5253,7 +5154,7 @@ void LCodeGen::DoCheckValue(LCheckValue* instr) { void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) { { - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); __ push(object); __ mov(cp, Operand::Zero()); __ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance); @@ -5295,7 +5196,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) { Register map_reg = scratch0(); LOperand* input = instr->value(); - ASSERT(input->IsRegister()); + DCHECK(input->IsRegister()); Register reg = ToRegister(input); __ ldr(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset)); @@ -5422,11 +5323,11 @@ void LCodeGen::DoAllocate(LAllocate* instr) { flags = static_cast(flags | DOUBLE_ALIGNMENT); } if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { - ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); - ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); + DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation()); + DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); flags = static_cast(flags | PRETENURE_OLD_POINTER_SPACE); } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { - ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); + DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); flags = static_cast(flags | PRETENURE_OLD_DATA_SPACE); } @@ -5439,33 +5340,25 @@ void LCodeGen::DoAllocate(LAllocate* instr) { } } else { Register size = ToRegister(instr->size()); - __ Allocate(size, - result, - scratch, - scratch2, - deferred->entry(), - flags); + __ Allocate(size, result, scratch, scratch2, deferred->entry(), flags); } __ bind(deferred->exit()); if (instr->hydrogen()->MustPrefillWithFiller()) { + STATIC_ASSERT(kHeapObjectTag == 1); if (instr->size()->IsConstantOperand()) { int32_t size = ToInteger32(LConstantOperand::cast(instr->size())); - __ mov(scratch, Operand(size)); + __ mov(scratch, Operand(size - kHeapObjectTag)); } else { - scratch = ToRegister(instr->size()); + __ sub(scratch, ToRegister(instr->size()), Operand(kHeapObjectTag)); } - __ sub(scratch, scratch, Operand(kPointerSize)); - __ sub(result, result, Operand(kHeapObjectTag)); + __ mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); Label loop; __ bind(&loop); - __ mov(scratch2, Operand(isolate()->factory()->one_pointer_filler_map())); + __ sub(scratch, scratch, Operand(kPointerSize), SetCC); __ str(scratch2, MemOperand(result, scratch)); - __ sub(scratch, scratch, Operand(kPointerSize)); - __ cmp(scratch, Operand(0)); __ b(ge, &loop); - __ add(result, result, Operand(kHeapObjectTag)); } } @@ -5478,10 +5371,10 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) { // contained in the register pointer map. __ mov(result, Operand(Smi::FromInt(0))); - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); if (instr->size()->IsRegister()) { Register size = ToRegister(instr->size()); - ASSERT(!size.is(result)); + DCHECK(!size.is(result)); __ SmiTag(size); __ push(size); } else { @@ -5498,11 +5391,11 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) { int flags = AllocateDoubleAlignFlag::encode( instr->hydrogen()->MustAllocateDoubleAligned()); if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { - ASSERT(!instr->hydrogen()->IsOldDataSpaceAllocation()); - ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); + DCHECK(!instr->hydrogen()->IsOldDataSpaceAllocation()); + DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); flags = AllocateTargetSpace::update(flags, OLD_POINTER_SPACE); } else if (instr->hydrogen()->IsOldDataSpaceAllocation()) { - ASSERT(!instr->hydrogen()->IsNewSpaceAllocation()); + DCHECK(!instr->hydrogen()->IsNewSpaceAllocation()); flags = AllocateTargetSpace::update(flags, OLD_DATA_SPACE); } else { flags = AllocateTargetSpace::update(flags, NEW_SPACE); @@ -5510,20 +5403,20 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) { __ Push(Smi::FromInt(flags)); CallRuntimeFromDeferred( - Runtime::kHiddenAllocateInTargetSpace, 2, instr, instr->context()); + Runtime::kAllocateInTargetSpace, 2, instr, instr->context()); __ StoreToSafepointRegisterSlot(r0, result); } void LCodeGen::DoToFastProperties(LToFastProperties* instr) { - ASSERT(ToRegister(instr->value()).is(r0)); + DCHECK(ToRegister(instr->value()).is(r0)); __ push(r0); CallRuntime(Runtime::kToFastProperties, 1, instr); } void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->context()).is(cp)); Label materialized; // Registers will be used as follows: // r6 = literals array. @@ -5544,7 +5437,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { __ mov(r4, Operand(instr->hydrogen()->pattern())); __ mov(r3, Operand(instr->hydrogen()->flags())); __ Push(r6, r5, r4, r3); - CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4, instr); + CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr); __ mov(r1, r0); __ bind(&materialized); @@ -5557,7 +5450,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { __ bind(&runtime_allocate); __ mov(r0, Operand(Smi::FromInt(size))); __ Push(r1, r0); - CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1, instr); + CallRuntime(Runtime::kAllocateInNewSpace, 1, instr); __ pop(r1); __ bind(&allocated); @@ -5567,7 +5460,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) { void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { - ASSERT(ToRegister(instr->context()).is(cp)); + DCHECK(ToRegister(instr->context()).is(cp)); // Use the fast case closure allocation code that allocates in new // space for nested functions that don't need literals cloning. bool pretenure = instr->hydrogen()->pretenure(); @@ -5582,7 +5475,7 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { __ mov(r1, Operand(pretenure ? factory()->true_value() : factory()->false_value())); __ Push(cp, r2, r1); - CallRuntime(Runtime::kHiddenNewClosure, 3, instr); + CallRuntime(Runtime::kNewClosure, 3, instr); } } @@ -5639,11 +5532,6 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, __ CompareRoot(input, Heap::kFalseValueRootIndex); final_branch_condition = eq; - } else if (FLAG_harmony_typeof && - String::Equals(type_name, factory->null_string())) { - __ CompareRoot(input, Heap::kNullValueRootIndex); - final_branch_condition = eq; - } else if (String::Equals(type_name, factory->undefined_string())) { __ CompareRoot(input, Heap::kUndefinedValueRootIndex); __ b(eq, true_label); @@ -5666,10 +5554,8 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, } else if (String::Equals(type_name, factory->object_string())) { Register map = scratch; __ JumpIfSmi(input, false_label); - if (!FLAG_harmony_typeof) { - __ CompareRoot(input, Heap::kNullValueRootIndex); - __ b(eq, true_label); - } + __ CompareRoot(input, Heap::kNullValueRootIndex); + __ b(eq, true_label); __ CheckObjectTypeRange(input, map, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, @@ -5697,7 +5583,7 @@ void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { void LCodeGen::EmitIsConstructCall(Register temp1, Register temp2) { - ASSERT(!temp1.is(temp2)); + DCHECK(!temp1.is(temp2)); // Get the frame pointer for the calling frame. __ ldr(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); @@ -5721,7 +5607,7 @@ void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { // Block literal pool emission for duration of padding. Assembler::BlockConstPoolScope block_const_pool(masm()); int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; - ASSERT_EQ(0, padding_size % Assembler::kInstrSize); + DCHECK_EQ(0, padding_size % Assembler::kInstrSize); while (padding_size > 0) { __ nop(); padding_size -= Assembler::kInstrSize; @@ -5734,7 +5620,7 @@ void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) { void LCodeGen::DoLazyBailout(LLazyBailout* instr) { last_lazy_deopt_pc_ = masm()->pc_offset(); - ASSERT(instr->HasEnvironment()); + DCHECK(instr->HasEnvironment()); LEnvironment* env = instr->environment(); RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); @@ -5767,12 +5653,12 @@ void LCodeGen::DoDummyUse(LDummyUse* instr) { void LCodeGen::DoDeferredStackCheck(LStackCheck* instr) { - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); LoadContextFromDeferred(instr->context()); - __ CallRuntimeSaveDoubles(Runtime::kHiddenStackGuard); + __ CallRuntimeSaveDoubles(Runtime::kStackGuard); RecordSafepointWithLazyDeopt( instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); - ASSERT(instr->HasEnvironment()); + DCHECK(instr->HasEnvironment()); LEnvironment* env = instr->environment(); safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); } @@ -5791,7 +5677,7 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) { LStackCheck* instr_; }; - ASSERT(instr->HasEnvironment()); + DCHECK(instr->HasEnvironment()); LEnvironment* env = instr->environment(); // There is no LLazyBailout instruction for stack-checks. We have to // prepare for lazy deoptimization explicitly here. @@ -5804,12 +5690,12 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) { Handle stack_check = isolate()->builtins()->StackCheck(); PredictableCodeSizeScope predictable(masm(), CallCodeSize(stack_check, RelocInfo::CODE_TARGET)); - ASSERT(instr->context()->IsRegister()); - ASSERT(ToRegister(instr->context()).is(cp)); + DCHECK(instr->context()->IsRegister()); + DCHECK(ToRegister(instr->context()).is(cp)); CallCode(stack_check, RelocInfo::CODE_TARGET, instr); __ bind(&done); } else { - ASSERT(instr->hydrogen()->is_backwards_branch()); + DCHECK(instr->hydrogen()->is_backwards_branch()); // Perform stack overflow check if this goto needs it before jumping. DeferredStackCheck* deferred_stack_check = new(zone()) DeferredStackCheck(this, instr); @@ -5835,7 +5721,7 @@ void LCodeGen::DoOsrEntry(LOsrEntry* instr) { // If the environment were already registered, we would have no way of // backpatching it with the spill slot operands. - ASSERT(!environment->HasBeenRegistered()); + DCHECK(!environment->HasBeenRegistered()); RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); GenerateOsrPrologue(); @@ -5914,7 +5800,7 @@ void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, Register result, Register object, Register index) { - PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); + PushSafepointRegistersScope scope(this); __ Push(object); __ Push(index); __ mov(cp, Operand::Zero()); @@ -5995,7 +5881,7 @@ void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) { Handle scope_info = instr->scope_info(); __ Push(scope_info); __ push(ToRegister(instr->function())); - CallRuntime(Runtime::kHiddenPushBlockContext, 2, instr); + CallRuntime(Runtime::kPushBlockContext, 2, instr); RecordSafepoint(Safepoint::kNoLazyDeopt); }