#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 {
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
void LCodeGen::FinishCode(Handle<Code> 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);
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();
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);
bool LCodeGen::GeneratePrologue() {
- ASSERT(is_generating());
+ DCHECK(is_generating());
if (info()->IsOptimizing()) {
ProfileEntryHookStub::MaybeCallEntryHook(masm_);
__ b(ne, &ok);
__ ldr(r2, GlobalObjectOperand());
- __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
+ __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalProxyOffset));
__ str(r2, MemOperand(sp, receiver_offset));
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
// 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));
}
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];
__ 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)));
code->Generate();
if (NeedsDeferredFrame()) {
Comment(";;; Destroy frame");
- ASSERT(frame_is_built_);
+ DCHECK(frame_is_built_);
__ pop(ip);
__ PopFixedFrame();
frame_is_built_ = false;
}
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
bool LCodeGen::GenerateSafepointTable() {
- ASSERT(is_done());
+ DCHECK(is_done());
safepoints_.Emit(masm(), GetStackSlotCount());
return !is_aborted();
}
Register LCodeGen::ToRegister(LOperand* op) const {
- ASSERT(op->IsRegister());
+ DCHECK(op->IsRegister());
return ToRegister(op->index());
}
Handle<Object> literal = constant->handle(isolate());
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
- ASSERT(literal->IsNumber());
+ DCHECK(literal->IsNumber());
__ mov(scratch, Operand(static_cast<int32_t>(literal->Number())));
} else if (r.IsDouble()) {
Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
} else {
- ASSERT(r.IsSmiOrTagged());
+ DCHECK(r.IsSmiOrTagged());
__ Move(scratch, literal);
}
return scratch;
DwVfpRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
- ASSERT(op->IsDoubleRegister());
+ DCHECK(op->IsDoubleRegister());
return ToDoubleRegister(op->index());
}
Handle<Object> literal = constant->handle(isolate());
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
- ASSERT(literal->IsNumber());
+ DCHECK(literal->IsNumber());
__ mov(ip, Operand(static_cast<int32_t>(literal->Number())));
__ vmov(flt_scratch, ip);
__ vcvt_f64_s32(dbl_scratch, flt_scratch);
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
HConstant* constant = chunk_->LookupConstant(op);
- ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
+ DCHECK(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged());
return constant->handle(isolate());
}
HConstant* constant = chunk_->LookupConstant(op);
int32_t value = constant->Integer32Value();
if (r.IsInteger32()) return value;
- ASSERT(r.IsSmiOrTagged());
+ DCHECK(r.IsSmiOrTagged());
return reinterpret_cast<int32_t>(Smi::FromInt(value));
}
double LCodeGen::ToDouble(LConstantOperand* op) const {
HConstant* constant = chunk_->LookupConstant(op);
- ASSERT(constant->HasDoubleValue());
+ DCHECK(constant->HasDoubleValue());
return constant->DoubleValue();
}
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));
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 {
MemOperand LCodeGen::ToHighMemOperand(LOperand* op) const {
- ASSERT(op->IsDoubleStackSlot());
+ DCHECK(op->IsDoubleStackSlot());
if (NeedsEagerFrame()) {
return MemOperand(fp, StackSlotOffset(op->index()) + kPointerSize);
} else {
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:
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());
int num_arguments,
LInstruction* instr,
SaveFPRegsMode save_doubles) {
- ASSERT(instr != NULL);
+ DCHECK(instr != NULL);
__ CallRuntime(function, num_arguments, save_doubles);
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) {
__ 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);
__ 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_ &&
int length = deoptimizations_.length();
if (length == 0) return;
Handle<DeoptimizationInputData> data =
- DeoptimizationInputData::New(isolate(), length, TENURED);
+ DeoptimizationInputData::New(isolate(), length, 0, TENURED);
Handle<ByteArray> translations =
translations_.CreateByteArray(isolate()->factory());
void LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() {
- ASSERT(deoptimization_literals_.length() == 0);
+ DCHECK(deoptimization_literals_.length() == 0);
const ZoneList<Handle<JSFunction> >* inlined_closures =
chunk()->inlined_closures();
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);
}
Safepoint::Kind kind,
int arguments,
Safepoint::DeoptMode deopt_mode) {
- ASSERT(expected_safepoint_kind_ == kind);
+ DCHECK(expected_safepoint_kind_ == kind);
const ZoneList<LOperand*>* operands = pointers->GetNormalizedOperands();
Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
}
-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);
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());
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
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());
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
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();
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());
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);
}
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);
}
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());
// 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);
}
} else {
- ASSERT(right_op->IsRegister());
+ DCHECK(right_op->IsRegister());
Register right = ToRegister(right_op);
if (overflow) {
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);
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);
}
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);
}
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);
}
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());
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());
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 {
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);
}
__ 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());
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
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.
__ 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);
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()) {
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->context()).is(cp));
Token::Value op = instr->op();
Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
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;
}
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);
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);
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;
// 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> cell = factory()->NewCell(factory()->the_hole_value());
__ mov(ip, Operand(Handle<Object>(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.
void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
- Label* map_check) {
+ Label* map_check,
+ Label* bool_load) {
InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
flags = static_cast<InstanceofStub::Flags>(
flags | InstanceofStub::kArgsInRegisters);
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,
void LCodeGen::DoCmpT(LCmpT* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->context()).is(cp));
Token::Value op = instr->op();
Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
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<Code> ic = LoadIC::initialize_stub(isolate(), mode);
CallCode(ic, RelocInfo::CODE_TARGET, 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<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
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));
// 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);
}
-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<class T>
-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<Runtime::FunctionId>(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;
} else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
__ vldr(result, scratch0(), base_offset);
}
- } else if (IsFloat32x4ElementsKind(elements_kind)) {
- DoLoadKeyedSIMD128ExternalArray<Float32x4>(instr);
- } else if (IsFloat64x2ElementsKind(elements_kind)) {
- DoLoadKeyedSIMD128ExternalArray<Float64x2>(instr);
- } else if (IsInt32x4ElementsKind(elements_kind)) {
- DoLoadKeyedSIMD128ExternalArray<Int32x4>(instr);
} else {
Register result = ToRegister(instr->result());
MemOperand mem_operand = PrepareKeyedOperand(
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:
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);
}
}
__ 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);
}
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<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
__ 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);
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.
__ b(ne, &loop);
__ bind(&invoke);
- ASSERT(instr->HasPointerMap());
+ DCHECK(instr->HasPointerMap());
LPointerMap* pointers = instr->pointer_map();
SafepointGenerator safepoint_generator(
this, pointers, Safepoint::kLazyDeopt);
__ 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);
}
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();
// 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.
// 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));
}
+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());
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);
MathPowStub stub(isolate(), MathPowStub::INTEGER);
__ CallStub(&stub);
} else {
- ASSERT(exponent_type.IsDouble());
+ DCHECK(exponent_type.IsDouble());
MathPowStub stub(isolate(), MathPowStub::DOUBLE);
__ CallStub(&stub);
}
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<JSFunction> known_function = instr->hydrogen()->known_function();
if (known_function.is_null()) {
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);
LConstantOperand* target = LConstantOperand::cast(instr->target());
Handle<Code> code = Handle<Code>::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();
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()));
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());
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
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);
__ 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;
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<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
}
}
-template<class T>
-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;
} else { // Storing doubles, not floats.
__ vstr(value, address, base_offset);
}
- } else if (IsFloat32x4ElementsKind(elements_kind)) {
- DoStoreKeyedSIMD128ExternalArray<Float32x4>(instr);
- } else if (IsFloat64x2ElementsKind(elements_kind)) {
- DoStoreKeyedSIMD128ExternalArray<Float64x2>(instr);
- } else if (IsInt32x4ElementsKind(elements_kind)) {
- DoStoreKeyedSIMD128ExternalArray<Int32x4>(instr);
} else {
Register value(ToRegister(instr->value()));
MemOperand mem_operand = PrepareKeyedOperand(
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:
// 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;
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<Code> ic = instr->strict_mode() == STRICT
? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
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);
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());
// 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.
__ SmiTag(index);
__ push(index);
}
- CallRuntimeFromDeferred(Runtime::kHiddenStringCharCodeAt, 2, instr,
+ CallRuntimeFromDeferred(Runtime::kStringCharCodeAtRT, 2, instr,
instr->context());
__ AssertSmi(r0);
__ SmiUntag(r0);
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());
// 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());
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();
__ 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));
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));
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.
}
} 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);
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;
};
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);
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);
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 {
void LCodeGen::DoDeferredInstanceMigration(LCheckMaps* instr, Register object) {
{
- PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ PushSafepointRegistersScope scope(this);
__ push(object);
__ mov(cp, Operand::Zero());
__ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance);
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));
flags = static_cast<AllocationFlags>(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<AllocationFlags>(flags | PRETENURE_OLD_POINTER_SPACE);
} else if (instr->hydrogen()->IsOldDataSpaceAllocation()) {
- ASSERT(!instr->hydrogen()->IsNewSpaceAllocation());
+ DCHECK(!instr->hydrogen()->IsNewSpaceAllocation());
flags = static_cast<AllocationFlags>(flags | PRETENURE_OLD_DATA_SPACE);
}
}
} 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));
}
}
// 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 {
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);
__ 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.
__ 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);
__ 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);
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();
__ mov(r1, Operand(pretenure ? factory()->true_value()
: factory()->false_value()));
__ Push(cp, r2, r1);
- CallRuntime(Runtime::kHiddenNewClosure, 3, instr);
+ CallRuntime(Runtime::kNewClosure, 3, instr);
}
}
__ 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);
} 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,
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));
// 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;
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());
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());
}
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.
Handle<Code> 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);
// 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();
Register result,
Register object,
Register index) {
- PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ PushSafepointRegistersScope scope(this);
__ Push(object);
__ Push(index);
__ mov(cp, Operand::Zero());
Handle<ScopeInfo> 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);
}