summaryrefslogtreecommitdiff
path: root/deps/v8/src/mips/lithium-codegen-mips.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/mips/lithium-codegen-mips.cc')
-rw-r--r--deps/v8/src/mips/lithium-codegen-mips.cc936
1 files changed, 477 insertions, 459 deletions
diff --git a/deps/v8/src/mips/lithium-codegen-mips.cc b/deps/v8/src/mips/lithium-codegen-mips.cc
index fe3e349c2..8cf77607a 100644
--- a/deps/v8/src/mips/lithium-codegen-mips.cc
+++ b/deps/v8/src/mips/lithium-codegen-mips.cc
@@ -25,13 +25,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "v8.h"
+#include "src/v8.h"
-#include "mips/lithium-codegen-mips.h"
-#include "mips/lithium-gap-resolver-mips.h"
-#include "code-stubs.h"
-#include "stub-cache.h"
-#include "hydrogen-osr.h"
+#include "src/code-stubs.h"
+#include "src/hydrogen-osr.h"
+#include "src/mips/lithium-codegen-mips.h"
+#include "src/mips/lithium-gap-resolver-mips.h"
+#include "src/stub-cache.h"
namespace v8 {
namespace internal {
@@ -64,7 +64,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
@@ -81,7 +81,7 @@ bool LCodeGen::GenerateCode() {
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);
@@ -90,8 +90,8 @@ void LCodeGen::FinishCode(Handle<Code> 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();
@@ -106,8 +106,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);
@@ -122,7 +122,7 @@ void LCodeGen::RestoreCallerDoubles() {
bool LCodeGen::GeneratePrologue() {
- ASSERT(is_generating());
+ DCHECK(is_generating());
if (info()->IsOptimizing()) {
ProfileEntryHookStub::MaybeCallEntryHook(masm_);
@@ -152,7 +152,7 @@ bool LCodeGen::GeneratePrologue() {
__ Branch(&ok, ne, a2, Operand(at));
__ lw(a2, GlobalObjectOperand());
- __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset));
+ __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalProxyOffset));
__ sw(a2, MemOperand(sp, receiver_offset));
@@ -162,7 +162,11 @@ bool LCodeGen::GeneratePrologue() {
info()->set_prologue_offset(masm_->pc_offset());
if (NeedsEagerFrame()) {
- __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
+ if (info()->IsStub()) {
+ __ StubPrologue();
+ } else {
+ __ Prologue(info()->IsCodePreAgingActive());
+ }
frame_is_built_ = true;
info_->AddNoFrameRange(0, masm_->pc_offset());
}
@@ -194,13 +198,16 @@ bool LCodeGen::GeneratePrologue() {
int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
if (heap_slots > 0) {
Comment(";;; Allocate local context");
+ bool need_write_barrier = true;
// Argument to NewContext is the function, which is in a1.
if (heap_slots <= FastNewContextStub::kMaximumSlots) {
FastNewContextStub stub(isolate(), heap_slots);
__ CallStub(&stub);
+ // Result of FastNewContextStub is always in new space.
+ need_write_barrier = false;
} else {
__ push(a1);
- __ CallRuntime(Runtime::kHiddenNewFunctionContext, 1);
+ __ CallRuntime(Runtime::kNewFunctionContext, 1);
}
RecordSafepoint(Safepoint::kNoLazyDeopt);
// Context is returned in both v0. It replaces the context passed to us.
@@ -220,8 +227,15 @@ bool LCodeGen::GeneratePrologue() {
MemOperand target = ContextOperand(cp, var->index());
__ sw(a0, target);
// Update the write barrier. This clobbers a3 and a0.
- __ RecordWriteContextSlot(
- cp, target.offset(), a0, a3, GetRAState(), kSaveFPRegs);
+ if (need_write_barrier) {
+ __ RecordWriteContextSlot(
+ cp, target.offset(), a0, a3, GetRAState(), kSaveFPRegs);
+ } else if (FLAG_debug_code) {
+ Label done;
+ __ JumpIfInNewSpace(cp, a0, &done);
+ __ Abort(kExpectedNewSpaceObject);
+ __ bind(&done);
+ }
}
}
Comment(";;; End allocate local context");
@@ -247,7 +261,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);
__ Subu(sp, sp, Operand(slots * kPointerSize));
}
@@ -263,7 +277,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 +295,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;
__ MultiPush(cp.bit() | fp.bit() | ra.bit());
__ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
@@ -293,7 +307,7 @@ bool LCodeGen::GenerateDeferredCode() {
code->Generate();
if (NeedsDeferredFrame()) {
Comment(";;; Destroy frame");
- ASSERT(frame_is_built_);
+ DCHECK(frame_is_built_);
__ pop(at);
__ MultiPop(cp.bit() | fp.bit() | ra.bit());
frame_is_built_ = false;
@@ -310,45 +324,74 @@ bool LCodeGen::GenerateDeferredCode() {
bool LCodeGen::GenerateDeoptJumpTable() {
if (deopt_jump_table_.length() > 0) {
+ Label needs_frame, call_deopt_entry;
+
Comment(";;; -------------------- Jump table --------------------");
- }
- Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
- 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 = t9;
+
+ 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);
- }
- __ li(t9, Operand(ExternalReference::ForDeoptEntry(entry)));
- if (deopt_jump_table_[i].needs_frame) {
- ASSERT(!info()->saves_caller_doubles());
- if (needs_frame.is_bound()) {
- __ Branch(&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.
+ __ li(entry_offset, Operand(entry - base));
+
+ if (deopt_jump_table_[i].needs_frame) {
+ DCHECK(!info()->saves_caller_doubles());
+ if (needs_frame.is_bound()) {
+ __ Branch(&needs_frame);
+ } else {
+ __ bind(&needs_frame);
+ Comment(";;; call deopt with frame");
+ __ MultiPush(cp.bit() | fp.bit() | ra.bit());
+ // 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());
+ __ li(at, Operand(Smi::FromInt(StackFrame::STUB)));
+ __ push(at);
+ __ Addu(fp, sp,
+ Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
+ __ bind(&call_deopt_entry);
+ // Add the base address to the offset previously loaded in
+ // entry_offset.
+ __ Addu(entry_offset, entry_offset,
+ Operand(ExternalReference::ForDeoptEntry(base)));
+ __ Call(entry_offset);
+ }
} else {
- __ bind(&needs_frame);
- __ MultiPush(cp.bit() | fp.bit() | ra.bit());
- // 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());
- __ li(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
- __ push(scratch0());
- __ Addu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
- __ Call(t9);
+ // 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) __ Branch(&call_deopt_entry);
}
- } 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();
}
- __ Call(t9);
+
+ // Add the base address to the offset previously loaded in entry_offset.
+ __ Addu(entry_offset, entry_offset,
+ Operand(ExternalReference::ForDeoptEntry(base)));
+ __ Call(entry_offset);
}
}
__ RecordComment("]");
@@ -361,7 +404,7 @@ bool LCodeGen::GenerateDeoptJumpTable() {
bool LCodeGen::GenerateSafepointTable() {
- ASSERT(is_done());
+ DCHECK(is_done());
safepoints_.Emit(masm(), GetStackSlotCount());
return !is_aborted();
}
@@ -378,7 +421,7 @@ DoubleRegister LCodeGen::ToDoubleRegister(int index) const {
Register LCodeGen::ToRegister(LOperand* op) const {
- ASSERT(op->IsRegister());
+ DCHECK(op->IsRegister());
return ToRegister(op->index());
}
@@ -392,15 +435,15 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
Handle<Object> literal = constant->handle(isolate());
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
- ASSERT(literal->IsNumber());
+ DCHECK(literal->IsNumber());
__ li(scratch, Operand(static_cast<int32_t>(literal->Number())));
} else if (r.IsSmi()) {
- ASSERT(constant->HasSmiValue());
+ DCHECK(constant->HasSmiValue());
__ li(scratch, Operand(Smi::FromInt(constant->Integer32Value())));
} else if (r.IsDouble()) {
Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
} else {
- ASSERT(r.IsSmiOrTagged());
+ DCHECK(r.IsSmiOrTagged());
__ li(scratch, literal);
}
return scratch;
@@ -414,7 +457,7 @@ Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
DoubleRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
- ASSERT(op->IsDoubleRegister());
+ DCHECK(op->IsDoubleRegister());
return ToDoubleRegister(op->index());
}
@@ -430,7 +473,7 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
Handle<Object> literal = constant->handle(isolate());
Representation r = chunk_->LookupLiteralRepresentation(const_op);
if (r.IsInteger32()) {
- ASSERT(literal->IsNumber());
+ DCHECK(literal->IsNumber());
__ li(at, Operand(static_cast<int32_t>(literal->Number())));
__ mtc1(at, flt_scratch);
__ cvt_d_w(dbl_scratch, flt_scratch);
@@ -452,7 +495,7 @@ DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
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());
}
@@ -477,7 +520,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<int32_t>(Smi::FromInt(value));
}
@@ -490,7 +533,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();
}
@@ -501,15 +544,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));
@@ -524,15 +567,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 {
@@ -544,7 +587,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 {
@@ -580,13 +623,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:
@@ -691,7 +734,7 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code,
RelocInfo::Mode mode,
LInstruction* instr,
SafepointMode safepoint_mode) {
- ASSERT(instr != NULL);
+ DCHECK(instr != NULL);
__ Call(code, mode);
RecordSafepointWithLazyDeopt(instr, safepoint_mode);
}
@@ -701,7 +744,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);
@@ -778,9 +821,9 @@ void LCodeGen::DeoptimizeIf(Condition condition,
Register src1,
const Operand& src2) {
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) {
@@ -816,7 +859,7 @@ void LCodeGen::DeoptimizeIf(Condition condition,
__ bind(&skip);
}
- 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_ &&
@@ -854,7 +897,7 @@ void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
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());
@@ -905,7 +948,7 @@ int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) {
void LCodeGen::PopulateDeoptimizationLiteralsWithInlinedFunctions() {
- ASSERT(deoptimization_literals_.length() == 0);
+ DCHECK(deoptimization_literals_.length() == 0);
const ZoneList<Handle<JSFunction> >* inlined_closures =
chunk()->inlined_closures();
@@ -925,7 +968,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);
}
@@ -937,7 +980,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<LOperand*>* operands = pointers->GetNormalizedOperands();
Safepoint safepoint = safepoints_.DefineSafepoint(masm(),
@@ -973,15 +1016,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);
@@ -1035,8 +1069,8 @@ void LCodeGen::DoParameter(LParameter* instr) {
void LCodeGen::DoCallStub(LCallStub* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->result()).is(v0));
switch (instr->hydrogen()->major_key()) {
case CodeStub::RegExpExec: {
RegExpExecStub stub(isolate());
@@ -1067,7 +1101,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
@@ -1101,7 +1135,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());
@@ -1168,8 +1202,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();
@@ -1212,7 +1246,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());
@@ -1285,7 +1319,7 @@ void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
DoubleRegister multiplicand = ToDoubleRegister(instr->multiplicand());
// This is computed in-place.
- ASSERT(addend.is(ToDoubleRegister(instr->result())));
+ DCHECK(addend.is(ToDoubleRegister(instr->result())));
__ madd_d(addend, addend, multiplier, multiplicand);
}
@@ -1295,12 +1329,17 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
Register dividend = ToRegister(instr->dividend());
Register result = ToRegister(instr->result());
int32_t divisor = instr->divisor();
- Register scratch = scratch0();
- ASSERT(!scratch.is(dividend));
+ Register scratch = result.is(dividend) ? scratch0() : dividend;
+ DCHECK(!result.is(dividend) || !scratch.is(dividend));
+
+ // If the divisor is 1, return the dividend.
+ if (divisor == 1) {
+ __ Move(result, dividend);
+ return;
+ }
// If the divisor is positive, things are easy: There can be no deopts and we
// can simply do an arithmetic right shift.
- if (divisor == 1) return;
uint16_t shift = WhichPowerOf2Abs(divisor);
if (divisor > 1) {
__ sra(result, dividend, shift);
@@ -1308,33 +1347,37 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
}
// If the divisor is negative, we have to negate and handle edge cases.
- if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
- __ Move(scratch, dividend);
- }
+
+ // dividend can be the same register as result so save the value of it
+ // for checking overflow.
+ __ Move(scratch, dividend);
+
__ Subu(result, zero_reg, dividend);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg));
}
- // If the negation could not overflow, simply shifting is OK.
- if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
- __ sra(result, dividend, shift);
+ // Dividing by -1 is basically negation, unless we overflow.
+ __ Xor(scratch, scratch, result);
+ if (divisor == -1) {
+ if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
+ DeoptimizeIf(ge, instr->environment(), scratch, Operand(zero_reg));
+ }
return;
}
- // Dividing by -1 is basically negation, unless we overflow.
- __ Xor(at, scratch, result);
- if (divisor == -1) {
- DeoptimizeIf(ge, instr->environment(), at, Operand(zero_reg));
+ // If the negation could not overflow, simply shifting is OK.
+ if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
+ __ sra(result, result, shift);
return;
}
Label no_overflow, done;
- __ Branch(&no_overflow, lt, at, Operand(zero_reg));
+ __ Branch(&no_overflow, lt, scratch, Operand(zero_reg));
__ li(result, Operand(kMinInt / divisor));
__ Branch(&done);
__ bind(&no_overflow);
- __ sra(result, dividend, shift);
+ __ sra(result, result, shift);
__ bind(&done);
}
@@ -1343,7 +1386,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());
@@ -1368,7 +1411,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;
__ Branch(&needs_adjustment, divisor > 0 ? lt : gt,
dividend, Operand(zero_reg));
@@ -1503,7 +1546,7 @@ void LCodeGen::DoMulI(LMulI* instr) {
}
} else {
- ASSERT(right_op->IsRegister());
+ DCHECK(right_op->IsRegister());
Register right = ToRegister(right_op);
if (overflow) {
@@ -1547,7 +1590,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);
@@ -1555,7 +1598,7 @@ void LCodeGen::DoBitI(LBitI* instr) {
if (right_op->IsStackSlot()) {
right = Operand(EmitLoadRegister(right_op, at));
} else {
- ASSERT(right_op->IsRegister() || right_op->IsConstantOperand());
+ DCHECK(right_op->IsRegister() || right_op->IsConstantOperand());
right = ToOperand(right_op);
}
@@ -1678,7 +1721,7 @@ void LCodeGen::DoSubI(LSubI* instr) {
Register right_reg = EmitLoadRegister(right, at);
__ Subu(ToRegister(result), ToRegister(left), Operand(right_reg));
} else {
- ASSERT(right->IsRegister() || right->IsConstantOperand());
+ DCHECK(right->IsRegister() || right->IsConstantOperand());
__ Subu(ToRegister(result), ToRegister(left), ToOperand(right));
}
} else { // can_overflow.
@@ -1691,7 +1734,7 @@ void LCodeGen::DoSubI(LSubI* instr) {
right_reg,
overflow); // Reg at also used as scratch.
} else {
- ASSERT(right->IsRegister());
+ DCHECK(right->IsRegister());
// Due to overflow check macros not supporting constant operands,
// handling the IsConstantOperand case was moved to prev if clause.
__ SubuAndCheckForOverflow(ToRegister(result),
@@ -1715,7 +1758,7 @@ void LCodeGen::DoConstantS(LConstantS* instr) {
void LCodeGen::DoConstantD(LConstantD* instr) {
- ASSERT(instr->result()->IsDoubleRegister());
+ DCHECK(instr->result()->IsDoubleRegister());
DoubleRegister result = ToDoubleRegister(instr->result());
double v = instr->value();
__ Move(result, v);
@@ -1730,13 +1773,6 @@ void LCodeGen::DoConstantE(LConstantE* instr) {
void LCodeGen::DoConstantT(LConstantT* instr) {
Handle<Object> object = instr->value(isolate());
AllowDeferredHandleDereference smi_check;
- if (instr->hydrogen()->HasObjectMap()) {
- Handle<Map> object_map = instr->hydrogen()->ObjectMap().handle();
- ASSERT(object->IsHeapObject());
- ASSERT(!object_map->is_stable() ||
- *object_map == Handle<HeapObject>::cast(object)->map());
- USE(object_map);
- }
__ li(ToRegister(instr->result()), object);
}
@@ -1754,10 +1790,10 @@ void LCodeGen::DoDateField(LDateField* instr) {
Register scratch = ToRegister(instr->temp());
Smi* index = instr->index();
Label runtime, done;
- ASSERT(object.is(a0));
- ASSERT(result.is(v0));
- ASSERT(!scratch.is(scratch0()));
- ASSERT(!scratch.is(object));
+ DCHECK(object.is(a0));
+ DCHECK(result.is(v0));
+ DCHECK(!scratch.is(scratch0()));
+ DCHECK(!scratch.is(object));
__ SmiTst(object, at);
DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
@@ -1798,8 +1834,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) {
__ Addu(scratch, string, ToRegister(index));
} else {
@@ -1875,7 +1911,7 @@ void LCodeGen::DoAddI(LAddI* instr) {
Register right_reg = EmitLoadRegister(right, at);
__ Addu(ToRegister(result), ToRegister(left), Operand(right_reg));
} else {
- ASSERT(right->IsRegister() || right->IsConstantOperand());
+ DCHECK(right->IsRegister() || right->IsConstantOperand());
__ Addu(ToRegister(result), ToRegister(left), ToOperand(right));
}
} else { // can_overflow.
@@ -1889,7 +1925,7 @@ void LCodeGen::DoAddI(LAddI* instr) {
right_reg,
overflow); // Reg at also used as scratch.
} else {
- ASSERT(right->IsRegister());
+ DCHECK(right->IsRegister());
// Due to overflow check macros not supporting constant operands,
// handling the IsConstantOperand case was moved to prev if clause.
__ AdduAndCheckForOverflow(ToRegister(result),
@@ -1909,22 +1945,21 @@ void LCodeGen::DoMathMinMax(LMathMinMax* instr) {
Condition condition = (operation == HMathMinMax::kMathMin) ? le : ge;
if (instr->hydrogen()->representation().IsSmiOrInteger32()) {
Register left_reg = ToRegister(left);
- Operand right_op = (right->IsRegister() || right->IsConstantOperand())
- ? ToOperand(right)
- : Operand(EmitLoadRegister(right, at));
+ Register right_reg = EmitLoadRegister(right, scratch0());
Register result_reg = ToRegister(instr->result());
Label return_right, done;
- if (!result_reg.is(left_reg)) {
- __ Branch(&return_right, NegateCondition(condition), left_reg, right_op);
- __ mov(result_reg, left_reg);
- __ Branch(&done);
+ Register scratch = scratch1();
+ __ Slt(scratch, left_reg, Operand(right_reg));
+ if (condition == ge) {
+ __ Movz(result_reg, left_reg, scratch);
+ __ Movn(result_reg, right_reg, scratch);
+ } else {
+ DCHECK(condition == le);
+ __ Movn(result_reg, left_reg, scratch);
+ __ Movz(result_reg, right_reg, scratch);
}
- __ Branch(&done, condition, left_reg, right_op);
- __ bind(&return_right);
- __ Addu(result_reg, zero_reg, right_op);
- __ bind(&done);
} else {
- ASSERT(instr->hydrogen()->representation().IsDouble());
+ DCHECK(instr->hydrogen()->representation().IsDouble());
FPURegister left_reg = ToDoubleRegister(left);
FPURegister right_reg = ToDoubleRegister(right);
FPURegister result_reg = ToDoubleRegister(instr->result());
@@ -2006,10 +2041,10 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->left()).is(a1));
- ASSERT(ToRegister(instr->right()).is(a0));
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->left()).is(a1));
+ DCHECK(ToRegister(instr->right()).is(a0));
+ DCHECK(ToRegister(instr->result()).is(v0));
BinaryOpICStub stub(isolate(), instr->op(), NO_OVERWRITE);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
@@ -2096,36 +2131,36 @@ 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());
EmitBranch(instr, ne, reg, Operand(zero_reg));
} else if (r.IsDouble()) {
- ASSERT(!info()->IsStub());
+ DCHECK(!info()->IsStub());
DoubleRegister reg = ToDoubleRegister(instr->value());
// Test the double value. Zero and NaN are false.
EmitBranchF(instr, nue, reg, kDoubleRegZero);
} 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());
__ LoadRoot(at, Heap::kTrueValueRootIndex);
EmitBranch(instr, eq, reg, Operand(at));
} else if (type.IsSmi()) {
- ASSERT(!info()->IsStub());
+ DCHECK(!info()->IsStub());
EmitBranch(instr, ne, reg, Operand(zero_reg));
} else if (type.IsJSArray()) {
- ASSERT(!info()->IsStub());
+ DCHECK(!info()->IsStub());
EmitBranch(instr, al, zero_reg, Operand(zero_reg));
} else if (type.IsHeapNumber()) {
- ASSERT(!info()->IsStub());
+ DCHECK(!info()->IsStub());
DoubleRegister dbl_scratch = double_scratch0();
__ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
// Test the double value. Zero and NaN are false.
EmitBranchF(instr, nue, dbl_scratch, kDoubleRegZero);
} else if (type.IsString()) {
- ASSERT(!info()->IsStub());
+ DCHECK(!info()->IsStub());
__ lw(at, FieldMemOperand(reg, String::kLengthOffset));
EmitBranch(instr, ne, at, Operand(zero_reg));
} else {
@@ -2268,7 +2303,10 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
- Condition cond = TokenToCondition(instr->op(), false);
+ bool is_unsigned =
+ instr->hydrogen()->left()->CheckFlag(HInstruction::kUint32) ||
+ instr->hydrogen()->right()->CheckFlag(HInstruction::kUint32);
+ Condition cond = TokenToCondition(instr->op(), is_unsigned);
if (left->IsConstantOperand() && right->IsConstantOperand()) {
// We can statically evaluate the comparison.
@@ -2312,8 +2350,8 @@ void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
cmp_left = ToRegister(right);
cmp_right = Operand(value);
}
- // We transposed the operands. Reverse the condition.
- cond = ReverseCondition(cond);
+ // We commuted the operands, so commute the condition.
+ cond = CommuteCondition(cond);
} else {
cmp_left = ToRegister(left);
cmp_right = Operand(ToRegister(right));
@@ -2352,7 +2390,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()) {
@@ -2434,7 +2472,7 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
Register temp1 = ToRegister(instr->temp());
SmiCheck check_needed =
- instr->hydrogen()->value()->IsHeapObject()
+ instr->hydrogen()->value()->type().IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
Condition true_cond =
EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed);
@@ -2455,7 +2493,7 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
Register input = ToRegister(instr->value());
Register temp = ToRegister(instr->temp());
- if (!instr->hydrogen()->value()->IsHeapObject()) {
+ if (!instr->hydrogen()->value()->type().IsHeapObject()) {
__ JumpIfSmi(input, instr->FalseLabel(chunk_));
}
__ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset));
@@ -2486,7 +2524,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<Code> ic = CompareIC::GetUninitialized(isolate(), op);
@@ -2502,7 +2540,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;
}
@@ -2522,7 +2560,7 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
Register scratch = scratch0();
Register input = ToRegister(instr->value());
- if (!instr->hydrogen()->value()->IsHeapObject()) {
+ if (!instr->hydrogen()->value()->type().IsHeapObject()) {
__ JumpIfSmi(input, instr->FalseLabel(chunk_));
}
@@ -2565,9 +2603,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);
@@ -2646,12 +2684,12 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->context()).is(cp));
Label true_label, done;
- ASSERT(ToRegister(instr->left()).is(a0)); // Object is in a0.
- ASSERT(ToRegister(instr->right()).is(a1)); // Function is in a1.
+ DCHECK(ToRegister(instr->left()).is(a0)); // Object is in a0.
+ DCHECK(ToRegister(instr->right()).is(a1)); // Function is in a1.
Register result = ToRegister(instr->result());
- ASSERT(result.is(v0));
+ DCHECK(result.is(v0));
InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
@@ -2690,8 +2728,8 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
Register temp = ToRegister(instr->temp());
Register result = ToRegister(instr->result());
- ASSERT(object.is(a0));
- ASSERT(result.is(v0));
+ DCHECK(object.is(a0));
+ DCHECK(result.is(v0));
// A Smi is not instance of anything.
__ JumpIfSmi(object, &false_result);
@@ -2745,7 +2783,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
Label* map_check) {
Register result = ToRegister(instr->result());
- ASSERT(result.is(v0));
+ DCHECK(result.is(v0));
InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
flags = static_cast<InstanceofStub::Flags>(
@@ -2756,14 +2794,14 @@ void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
flags | InstanceofStub::kReturnTrueFalseObject);
InstanceofStub stub(isolate(), flags);
- PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ PushSafepointRegistersScope scope(this);
LoadContextFromDeferred(instr->context());
// Get the temp register reserved by the instruction. This needs to be t0 as
// its slot of the pushing of safepoint registers is used to communicate the
// offset to the location of the map check.
Register temp = ToRegister(instr->temp());
- ASSERT(temp.is(t0));
+ DCHECK(temp.is(t0));
__ li(InstanceofStub::right(), instr->function());
static const int kAdditionalDelta = 7;
int delta = masm_->InstructionsGeneratedSince(map_check) + kAdditionalDelta;
@@ -2787,7 +2825,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<Code> ic = CompareIC::GetUninitialized(isolate(), op);
@@ -2802,7 +2840,7 @@ void LCodeGen::DoCmpT(LCmpT* instr) {
__ Branch(USE_DELAY_SLOT, &done, condition, v0, Operand(zero_reg));
__ bind(&check);
__ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex);
- ASSERT_EQ(1, masm()->InstructionsGeneratedSince(&check));
+ DCHECK_EQ(1, masm()->InstructionsGeneratedSince(&check));
__ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex);
__ bind(&done);
}
@@ -2861,11 +2899,20 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->global_object()).is(a0));
- ASSERT(ToRegister(instr->result()).is(v0));
-
- __ li(a2, Operand(instr->name()));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
+ DCHECK(ToRegister(instr->result()).is(v0));
+
+ __ li(LoadIC::NameRegister(), Operand(instr->name()));
+ if (FLAG_vector_ics) {
+ Register vector = ToRegister(instr->temp_vector());
+ DCHECK(vector.is(LoadIC::VectorRegister()));
+ __ li(vector, instr->hydrogen()->feedback_vector());
+ // No need to allocate this register.
+ DCHECK(LoadIC::SlotRegister().is(a0));
+ __ li(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);
@@ -2940,7 +2987,7 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
__ sw(value, target);
if (instr->hydrogen()->NeedsWriteBarrier()) {
SmiCheck check_needed =
- instr->hydrogen()->value()->IsHeapObject()
+ instr->hydrogen()->value()->type().IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
__ RecordWriteContextSlot(context,
target.offset(),
@@ -2985,12 +3032,21 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(a0));
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->object()).is(LoadIC::ReceiverRegister()));
+ DCHECK(ToRegister(instr->result()).is(v0));
// Name is always in a2.
- __ li(a2, Operand(instr->name()));
+ __ li(LoadIC::NameRegister(), Operand(instr->name()));
+ if (FLAG_vector_ics) {
+ Register vector = ToRegister(instr->temp_vector());
+ DCHECK(vector.is(LoadIC::VectorRegister()));
+ __ li(vector, instr->hydrogen()->feedback_vector());
+ // No need to allocate this register.
+ DCHECK(LoadIC::SlotRegister().is(a0));
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(instr->hydrogen()->slot())));
+ }
Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -3001,17 +3057,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.
- __ GetObjectType(function, result, scratch);
- DeoptimizeIf(ne, instr->environment(), scratch, Operand(JS_FUNCTION_TYPE));
-
- // Make sure that the function has an instance prototype.
- Label non_instance;
- __ lbu(scratch, FieldMemOperand(result, Map::kBitFieldOffset));
- __ And(scratch, scratch, Operand(1 << Map::kHasNonInstancePrototype));
- __ Branch(&non_instance, ne, scratch, Operand(zero_reg));
-
// Get the prototype or initial map from the function.
__ lw(result,
FieldMemOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
@@ -3027,12 +3072,6 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) {
// Get the prototype from the initial map.
__ lw(result, FieldMemOperand(result, Map::kPrototypeOffset));
- __ Branch(&done);
-
- // Non-instance prototype: Fetch prototype from constructor field
- // in initial map.
- __ bind(&non_instance);
- __ lw(result, FieldMemOperand(result, Map::kConstructorOffset));
// All done.
__ bind(&done);
@@ -3107,16 +3146,13 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
int element_size_shift = ElementsKindToShiftSize(elements_kind);
int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
? (element_size_shift - kSmiTagSize) : element_size_shift;
- int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
- ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
- : 0;
+ int base_offset = instr->base_offset();
if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
elements_kind == FLOAT32_ELEMENTS ||
elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
elements_kind == FLOAT64_ELEMENTS) {
- int base_offset =
- (instr->additional_index() << element_size_shift) + additional_offset;
+ int base_offset = instr->base_offset();
FPURegister result = ToDoubleRegister(instr->result());
if (key_is_constant) {
__ Addu(scratch0(), external_pointer, constant_key << element_size_shift);
@@ -3128,15 +3164,14 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
elements_kind == FLOAT32_ELEMENTS) {
__ lwc1(result, MemOperand(scratch0(), base_offset));
__ cvt_d_s(result, result);
- } else { // loading doubles, not floats.
+ } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
__ ldc1(result, MemOperand(scratch0(), base_offset));
}
} else {
Register result = ToRegister(instr->result());
MemOperand mem_operand = PrepareKeyedOperand(
key, external_pointer, key_is_constant, constant_key,
- element_size_shift, shift_size,
- instr->additional_index(), additional_offset);
+ element_size_shift, shift_size, base_offset);
switch (elements_kind) {
case EXTERNAL_INT8_ELEMENTS:
case INT8_ELEMENTS:
@@ -3196,15 +3231,13 @@ void LCodeGen::DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr) {
int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
- int base_offset =
- FixedDoubleArray::kHeaderSize - kHeapObjectTag +
- (instr->additional_index() << element_size_shift);
+ int base_offset = instr->base_offset();
if (key_is_constant) {
int constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
if (constant_key & 0xF0000000) {
Abort(kArrayIndexConstantValueTooBig);
}
- base_offset += constant_key << element_size_shift;
+ base_offset += constant_key * kDoubleSize;
}
__ Addu(scratch, elements, Operand(base_offset));
@@ -3230,12 +3263,11 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
Register result = ToRegister(instr->result());
Register scratch = scratch0();
Register store_base = scratch;
- int offset = 0;
+ int offset = instr->base_offset();
if (instr->key()->IsConstantOperand()) {
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
- offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
- instr->additional_index());
+ offset += ToInteger32(const_operand) * kPointerSize;
store_base = elements;
} else {
Register key = ToRegister(instr->key());
@@ -3250,9 +3282,8 @@ void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
__ sll(scratch, key, kPointerSizeLog2);
__ addu(scratch, elements, scratch);
}
- offset = FixedArray::OffsetOfElementAt(instr->additional_index());
}
- __ lw(result, FieldMemOperand(store_base, offset));
+ __ lw(result, MemOperand(store_base, offset));
// Check for the hole value.
if (instr->hydrogen()->RequiresHoleCheck()) {
@@ -3284,40 +3315,18 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key,
int constant_key,
int element_size,
int shift_size,
- int additional_index,
- int additional_offset) {
- int base_offset = (additional_index << element_size) + additional_offset;
+ int base_offset) {
if (key_is_constant) {
- return MemOperand(base,
- base_offset + (constant_key << element_size));
+ return MemOperand(base, (constant_key << element_size) + base_offset);
}
- if (additional_offset != 0) {
- if (shift_size >= 0) {
- __ sll(scratch0(), key, shift_size);
- __ Addu(scratch0(), scratch0(), Operand(base_offset));
- } else {
- ASSERT_EQ(-1, shift_size);
- // Key can be negative, so using sra here.
- __ sra(scratch0(), key, 1);
- __ Addu(scratch0(), scratch0(), Operand(base_offset));
- }
- __ Addu(scratch0(), base, scratch0());
- return MemOperand(scratch0());
- }
-
- if (additional_index != 0) {
- additional_index *= 1 << (element_size - shift_size);
- __ Addu(scratch0(), key, Operand(additional_index));
- }
-
- if (additional_index == 0) {
+ if (base_offset == 0) {
if (shift_size >= 0) {
__ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), base, scratch0());
return MemOperand(scratch0());
} else {
- ASSERT_EQ(-1, shift_size);
+ DCHECK_EQ(-1, shift_size);
__ srl(scratch0(), key, 1);
__ Addu(scratch0(), base, scratch0());
return MemOperand(scratch0());
@@ -3325,22 +3334,32 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key,
}
if (shift_size >= 0) {
- __ sll(scratch0(), scratch0(), shift_size);
+ __ sll(scratch0(), key, shift_size);
__ Addu(scratch0(), base, scratch0());
- return MemOperand(scratch0());
+ return MemOperand(scratch0(), base_offset);
} else {
- ASSERT_EQ(-1, shift_size);
- __ srl(scratch0(), scratch0(), 1);
+ DCHECK_EQ(-1, shift_size);
+ __ sra(scratch0(), key, 1);
__ Addu(scratch0(), base, scratch0());
- return MemOperand(scratch0());
+ return MemOperand(scratch0(), base_offset);
}
}
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(a1));
- ASSERT(ToRegister(instr->key()).is(a0));
+ 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()));
+ __ li(vector, instr->hydrogen()->feedback_vector());
+ // No need to allocate this register.
+ DCHECK(LoadIC::SlotRegister().is(a0));
+ __ li(LoadIC::SlotRegister(),
+ Operand(Smi::FromInt(instr->hydrogen()->slot())));
+ }
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
@@ -3437,7 +3456,7 @@ void LCodeGen::DoWrapReceiver(LWrapReceiver* instr) {
__ lw(result,
ContextOperand(result, Context::GLOBAL_OBJECT_INDEX));
__ lw(result,
- FieldMemOperand(result, GlobalObject::kGlobalReceiverOffset));
+ FieldMemOperand(result, GlobalObject::kGlobalProxyOffset));
if (result.is(receiver)) {
__ bind(&result_in_receiver);
@@ -3457,9 +3476,9 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
Register length = ToRegister(instr->length());
Register elements = ToRegister(instr->elements());
Register scratch = scratch0();
- ASSERT(receiver.is(a0)); // Used for parameter count.
- ASSERT(function.is(a1)); // Required by InvokeFunction.
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(receiver.is(a0)); // Used for parameter count.
+ DCHECK(function.is(a1)); // Required by InvokeFunction.
+ DCHECK(ToRegister(instr->result()).is(v0));
// Copy the arguments to this function possibly from the
// adaptor frame below it.
@@ -3488,7 +3507,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) {
__ sll(scratch, length, 2);
__ bind(&invoke);
- ASSERT(instr->HasPointerMap());
+ DCHECK(instr->HasPointerMap());
LPointerMap* pointers = instr->pointer_map();
SafepointGenerator safepoint_generator(
this, pointers, Safepoint::kLazyDeopt);
@@ -3528,18 +3547,18 @@ void LCodeGen::DoContext(LContext* instr) {
__ lw(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));
__ li(scratch0(), instr->hydrogen()->pairs());
__ li(scratch1(), Operand(Smi::FromInt(instr->hydrogen()->flags())));
// The context is the first argument.
__ Push(cp, scratch0(), scratch1());
- CallRuntime(Runtime::kHiddenDeclareGlobals, 3, instr);
+ CallRuntime(Runtime::kDeclareGlobals, 3, instr);
}
@@ -3585,8 +3604,8 @@ void LCodeGen::CallKnownFunction(Handle<JSFunction> 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();
@@ -3609,7 +3628,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.
@@ -3628,7 +3647,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(v0))
@@ -3805,6 +3824,14 @@ void LCodeGen::DoMathRound(LMathRound* instr) {
}
+void LCodeGen::DoMathFround(LMathFround* instr) {
+ DoubleRegister input = ToDoubleRegister(instr->value());
+ DoubleRegister result = ToDoubleRegister(instr->result());
+ __ cvt_s_d(result.low(), input);
+ __ cvt_d_s(result, result.low());
+}
+
+
void LCodeGen::DoMathSqrt(LMathSqrt* instr) {
DoubleRegister input = ToDoubleRegister(instr->value());
DoubleRegister result = ToDoubleRegister(instr->result());
@@ -3817,7 +3844,7 @@ void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
DoubleRegister result = ToDoubleRegister(instr->result());
DoubleRegister temp = ToDoubleRegister(instr->temp());
- ASSERT(!input.is(result));
+ DCHECK(!input.is(result));
// Note that according to ECMA-262 15.8.2.13:
// Math.pow(-Infinity, 0.5) == Infinity
@@ -3840,12 +3867,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(f4));
- ASSERT(!instr->right()->IsRegister() ||
+ DCHECK(!instr->right()->IsRegister() ||
ToRegister(instr->right()).is(a2));
- ASSERT(ToDoubleRegister(instr->left()).is(f2));
- ASSERT(ToDoubleRegister(instr->result()).is(f0));
+ DCHECK(ToDoubleRegister(instr->left()).is(f2));
+ DCHECK(ToDoubleRegister(instr->result()).is(f0));
if (exponent_type.IsSmi()) {
MathPowStub stub(isolate(), MathPowStub::TAGGED);
@@ -3863,7 +3890,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);
}
@@ -3901,9 +3928,9 @@ void LCodeGen::DoMathClz32(LMathClz32* instr) {
void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->function()).is(a1));
- ASSERT(instr->HasPointerMap());
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->function()).is(a1));
+ DCHECK(instr->HasPointerMap());
Handle<JSFunction> known_function = instr->hydrogen()->known_function();
if (known_function.is_null()) {
@@ -3922,7 +3949,7 @@ void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->result()).is(v0));
LPointerMap* pointers = instr->pointer_map();
SafepointGenerator generator(this, pointers, Safepoint::kLazyDeopt);
@@ -3933,7 +3960,7 @@ void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
generator.BeforeCall(__ CallSize(code, RelocInfo::CODE_TARGET));
__ Call(code, RelocInfo::CODE_TARGET);
} else {
- ASSERT(instr->target()->IsRegister());
+ DCHECK(instr->target()->IsRegister());
Register target = ToRegister(instr->target());
generator.BeforeCall(__ CallSize(target));
__ Addu(target, target, Operand(Code::kHeaderSize - kHeapObjectTag));
@@ -3944,8 +3971,8 @@ void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
- ASSERT(ToRegister(instr->function()).is(a1));
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->function()).is(a1));
+ DCHECK(ToRegister(instr->result()).is(v0));
if (instr->hydrogen()->pass_argument_count()) {
__ li(a0, Operand(instr->arity()));
@@ -3963,9 +3990,9 @@ void LCodeGen::DoCallJSFunction(LCallJSFunction* instr) {
void LCodeGen::DoCallFunction(LCallFunction* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->function()).is(a1));
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->function()).is(a1));
+ DCHECK(ToRegister(instr->result()).is(v0));
int arity = instr->arity();
CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
@@ -3974,9 +4001,9 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
void LCodeGen::DoCallNew(LCallNew* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->constructor()).is(a1));
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->constructor()).is(a1));
+ DCHECK(ToRegister(instr->result()).is(v0));
__ li(a0, Operand(instr->arity()));
// No cell in a2 for construct type feedback in optimized code
@@ -3987,9 +4014,9 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->constructor()).is(a1));
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->constructor()).is(a1));
+ DCHECK(ToRegister(instr->result()).is(v0));
__ li(a0, Operand(instr->arity()));
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
@@ -4075,13 +4102,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());
DoubleRegister value = ToDoubleRegister(instr->value());
__ sdc1(value, FieldMemOperand(object, offset));
return;
@@ -4095,14 +4122,11 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
if (instr->hydrogen()->NeedsWriteBarrierForMap()) {
Register temp = ToRegister(instr->temp());
// Update the write barrier for the map field.
- __ RecordWriteField(object,
- HeapObject::kMapOffset,
- scratch,
- temp,
- GetRAState(),
- kSaveFPRegs,
- OMIT_REMEMBERED_SET,
- OMIT_SMI_CHECK);
+ __ RecordWriteForMap(object,
+ scratch,
+ temp,
+ GetRAState(),
+ kSaveFPRegs);
}
}
@@ -4120,7 +4144,8 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
GetRAState(),
kSaveFPRegs,
EMIT_REMEMBERED_SET,
- instr->hydrogen()->SmiCheckForWriteBarrier());
+ instr->hydrogen()->SmiCheckForWriteBarrier(),
+ instr->hydrogen()->PointersToHereCheckForValue());
}
} else {
__ lw(scratch, FieldMemOperand(object, JSObject::kPropertiesOffset));
@@ -4136,19 +4161,19 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
GetRAState(),
kSaveFPRegs,
EMIT_REMEMBERED_SET,
- instr->hydrogen()->SmiCheckForWriteBarrier());
+ instr->hydrogen()->SmiCheckForWriteBarrier(),
+ instr->hydrogen()->PointersToHereCheckForValue());
}
}
}
void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(a1));
- ASSERT(ToRegister(instr->value()).is(a0));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->object()).is(StoreIC::ReceiverRegister()));
+ DCHECK(ToRegister(instr->value()).is(StoreIC::ValueRegister()));
- // Name is always in a2.
- __ li(a2, Operand(instr->name()));
+ __ li(StoreIC::NameRegister(), Operand(instr->name()));
Handle<Code> ic = StoreIC::initialize_stub(isolate(), instr->strict_mode());
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
@@ -4161,7 +4186,7 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->index()->IsConstantOperand()) {
operand = ToOperand(instr->index());
reg = ToRegister(instr->length());
- cc = ReverseCondition(cc);
+ cc = CommuteCondition(cc);
} else {
reg = ToRegister(instr->index());
operand = ToOperand(instr->length());
@@ -4194,16 +4219,12 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
int element_size_shift = ElementsKindToShiftSize(elements_kind);
int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
? (element_size_shift - kSmiTagSize) : element_size_shift;
- int additional_offset = IsFixedTypedArrayElementsKind(elements_kind)
- ? FixedTypedArrayBase::kDataOffset - kHeapObjectTag
- : 0;
+ int base_offset = instr->base_offset();
if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
elements_kind == FLOAT32_ELEMENTS ||
elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
elements_kind == FLOAT64_ELEMENTS) {
- int base_offset =
- (instr->additional_index() << element_size_shift) + additional_offset;
Register address = scratch0();
FPURegister value(ToDoubleRegister(instr->value()));
if (key_is_constant) {
@@ -4230,7 +4251,7 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
MemOperand mem_operand = PrepareKeyedOperand(
key, external_pointer, key_is_constant, constant_key,
element_size_shift, shift_size,
- instr->additional_index(), additional_offset);
+ base_offset);
switch (elements_kind) {
case EXTERNAL_UINT8_CLAMPED_ELEMENTS:
case EXTERNAL_INT8_ELEMENTS:
@@ -4277,6 +4298,7 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
Register scratch = scratch0();
DoubleRegister double_scratch = double_scratch0();
bool key_is_constant = instr->key()->IsConstantOperand();
+ int base_offset = instr->base_offset();
Label not_nan, done;
// Calculate the effective address of the slot in the array to store the
@@ -4288,13 +4310,11 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
Abort(kArrayIndexConstantValueTooBig);
}
__ Addu(scratch, elements,
- Operand((constant_key << element_size_shift) +
- FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+ Operand((constant_key << element_size_shift) + base_offset));
} else {
int shift_size = (instr->hydrogen()->key()->representation().IsSmi())
? (element_size_shift - kSmiTagSize) : element_size_shift;
- __ Addu(scratch, elements,
- Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
+ __ Addu(scratch, elements, Operand(base_offset));
__ sll(at, ToRegister(instr->key()), shift_size);
__ Addu(scratch, scratch, at);
}
@@ -4309,14 +4329,12 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
__ bind(&is_nan);
__ LoadRoot(at, Heap::kNanValueRootIndex);
__ ldc1(double_scratch, FieldMemOperand(at, HeapNumber::kValueOffset));
- __ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() <<
- element_size_shift));
+ __ sdc1(double_scratch, MemOperand(scratch, 0));
__ Branch(&done);
}
__ bind(&not_nan);
- __ sdc1(value, MemOperand(scratch, instr->additional_index() <<
- element_size_shift));
+ __ sdc1(value, MemOperand(scratch, 0));
__ bind(&done);
}
@@ -4328,14 +4346,13 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
: no_reg;
Register scratch = scratch0();
Register store_base = scratch;
- int offset = 0;
+ int offset = instr->base_offset();
// Do the store.
if (instr->key()->IsConstantOperand()) {
- ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
+ DCHECK(!instr->hydrogen()->NeedsWriteBarrier());
LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
- offset = FixedArray::OffsetOfElementAt(ToInteger32(const_operand) +
- instr->additional_index());
+ offset += ToInteger32(const_operand) * kPointerSize;
store_base = elements;
} else {
// Even though the HLoadKeyed instruction forces the input
@@ -4349,23 +4366,23 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
__ sll(scratch, key, kPointerSizeLog2);
__ addu(scratch, elements, scratch);
}
- offset = FixedArray::OffsetOfElementAt(instr->additional_index());
}
- __ sw(value, FieldMemOperand(store_base, offset));
+ __ sw(value, MemOperand(store_base, offset));
if (instr->hydrogen()->NeedsWriteBarrier()) {
SmiCheck check_needed =
- instr->hydrogen()->value()->IsHeapObject()
+ instr->hydrogen()->value()->type().IsHeapObject()
? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
// Compute address of modified element and store it into key register.
- __ Addu(key, store_base, Operand(offset - kHeapObjectTag));
+ __ Addu(key, store_base, Operand(offset));
__ RecordWrite(elements,
key,
value,
GetRAState(),
kSaveFPRegs,
EMIT_REMEMBERED_SET,
- check_needed);
+ check_needed,
+ instr->hydrogen()->PointersToHereCheckForValue());
}
}
@@ -4383,10 +4400,10 @@ void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->object()).is(a2));
- ASSERT(ToRegister(instr->key()).is(a1));
- ASSERT(ToRegister(instr->value()).is(a0));
+ 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()
@@ -4413,18 +4430,20 @@ void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
__ li(new_map_reg, Operand(to_map));
__ sw(new_map_reg, FieldMemOperand(object_reg, HeapObject::kMapOffset));
// Write barrier.
- __ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
- scratch, GetRAState(), kDontSaveFPRegs);
+ __ RecordWriteForMap(object_reg,
+ new_map_reg,
+ scratch,
+ GetRAState(),
+ kDontSaveFPRegs);
} else {
- ASSERT(object_reg.is(a0));
- ASSERT(ToRegister(instr->context()).is(cp));
- PushSafepointRegistersScope scope(
- this, Safepoint::kWithRegistersAndDoubles);
+ DCHECK(object_reg.is(a0));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ PushSafepointRegistersScope scope(this);
__ li(a1, Operand(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(&not_applicable);
@@ -4443,9 +4462,9 @@ void LCodeGen::DoTrapAllocationMemento(LTrapAllocationMemento* instr) {
void LCodeGen::DoStringAdd(LStringAdd* instr) {
- ASSERT(ToRegister(instr->context()).is(cp));
- ASSERT(ToRegister(instr->left()).is(a1));
- ASSERT(ToRegister(instr->right()).is(a0));
+ DCHECK(ToRegister(instr->context()).is(cp));
+ DCHECK(ToRegister(instr->left()).is(a1));
+ DCHECK(ToRegister(instr->right()).is(a0));
StringAddStub stub(isolate(),
instr->hydrogen()->flags(),
instr->hydrogen()->pretenure_flag());
@@ -4487,7 +4506,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
// contained in the register pointer map.
__ mov(result, zero_reg);
- 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.
@@ -4500,7 +4519,7 @@ void LCodeGen::DoDeferredStringCharCodeAt(LStringCharCodeAt* instr) {
__ SmiTag(index);
__ push(index);
}
- CallRuntimeFromDeferred(Runtime::kHiddenStringCharCodeAt, 2, instr,
+ CallRuntimeFromDeferred(Runtime::kStringCharCodeAtRT, 2, instr,
instr->context());
__ AssertSmi(v0);
__ SmiUntag(v0);
@@ -4524,11 +4543,11 @@ 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());
Register scratch = scratch0();
- ASSERT(!char_code.is(result));
+ DCHECK(!char_code.is(result));
__ Branch(deferred->entry(), hi,
char_code, Operand(String::kMaxOneByteCharCode));
@@ -4551,7 +4570,7 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
// contained in the register pointer map.
__ mov(result, zero_reg);
- PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ PushSafepointRegistersScope scope(this);
__ SmiTag(char_code);
__ push(char_code);
CallRuntimeFromDeferred(Runtime::kCharFromCode, 1, instr, instr->context());
@@ -4561,9 +4580,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());
FPURegister single_scratch = double_scratch0().low();
if (input->IsStackSlot()) {
Register scratch = scratch0();
@@ -4684,15 +4703,15 @@ void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
__ mov(dst, zero_reg);
// 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.
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
- __ CallRuntimeSaveDoubles(Runtime::kHiddenAllocateHeapNumber);
+ __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
RecordSafepointWithRegisters(
instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
__ Subu(v0, v0, kHeapObjectTag);
@@ -4750,14 +4769,14 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
Register reg = ToRegister(instr->result());
__ mov(reg, zero_reg);
- 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.
__ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
- __ CallRuntimeSaveDoubles(Runtime::kHiddenAllocateHeapNumber);
+ __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
RecordSafepointWithRegisters(
instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
__ Subu(v0, v0, kHeapObjectTag);
@@ -4839,7 +4858,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);
@@ -4857,8 +4876,8 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
DoubleRegister double_scratch = double_scratch0();
DoubleRegister 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;
@@ -4884,7 +4903,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
__ bind(&no_heap_number);
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
__ Branch(&check_bools, ne, input_reg, Operand(at));
- ASSERT(ToRegister(instr->result()).is(input_reg));
+ DCHECK(ToRegister(instr->result()).is(input_reg));
__ Branch(USE_DELAY_SLOT, &done);
__ mov(input_reg, zero_reg); // In delay slot.
@@ -4945,8 +4964,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);
@@ -4967,9 +4986,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);
DoubleRegister result_reg = ToDoubleRegister(result);
@@ -5062,7 +5081,7 @@ void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
- if (!instr->hydrogen()->value()->IsHeapObject()) {
+ if (!instr->hydrogen()->value()->type().IsHeapObject()) {
LOperand* input = instr->value();
__ SmiTst(ToRegister(input), at);
DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
@@ -5097,7 +5116,7 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) {
instr->hydrogen()->GetCheckMaskAndTag(&mask, &tag);
if (IsPowerOf2(mask)) {
- ASSERT(tag == 0 || IsPowerOf2(tag));
+ DCHECK(tag == 0 || IsPowerOf2(tag));
__ And(at, scratch, mask);
DeoptimizeIf(tag == 0 ? ne : eq, instr->environment(),
at, Operand(zero_reg));
@@ -5129,7 +5148,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, zero_reg);
__ CallRuntimeSaveDoubles(Runtime::kTryMigrateInstance);
@@ -5170,7 +5189,7 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
Register map_reg = scratch0();
LOperand* input = instr->value();
- ASSERT(input->IsRegister());
+ DCHECK(input->IsRegister());
Register reg = ToRegister(input);
__ lw(map_reg, FieldMemOperand(reg, HeapObject::kMapOffset));
@@ -5293,11 +5312,11 @@ void LCodeGen::DoAllocate(LAllocate* instr) {
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);
}
if (instr->size()->IsConstantOperand()) {
@@ -5309,33 +5328,26 @@ 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()));
- __ li(scratch, Operand(size));
+ __ li(scratch, Operand(size - kHeapObjectTag));
} else {
- scratch = ToRegister(instr->size());
+ __ Subu(scratch, ToRegister(instr->size()), Operand(kHeapObjectTag));
}
- __ Subu(scratch, scratch, Operand(kPointerSize));
- __ Subu(result, result, Operand(kHeapObjectTag));
+ __ li(scratch2, Operand(isolate()->factory()->one_pointer_filler_map()));
Label loop;
__ bind(&loop);
- __ li(scratch2, Operand(isolate()->factory()->one_pointer_filler_map()));
+ __ Subu(scratch, scratch, Operand(kPointerSize));
__ Addu(at, result, Operand(scratch));
__ sw(scratch2, MemOperand(at));
- __ Subu(scratch, scratch, Operand(kPointerSize));
__ Branch(&loop, ge, scratch, Operand(zero_reg));
- __ Addu(result, result, Operand(kHeapObjectTag));
}
}
@@ -5348,10 +5360,10 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
// contained in the register pointer map.
__ mov(result, zero_reg);
- 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 {
@@ -5368,11 +5380,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);
@@ -5380,21 +5392,21 @@ void LCodeGen::DoDeferredAllocate(LAllocate* instr) {
__ Push(Smi::FromInt(flags));
CallRuntimeFromDeferred(
- Runtime::kHiddenAllocateInTargetSpace, 2, instr, instr->context());
+ Runtime::kAllocateInTargetSpace, 2, instr, instr->context());
__ StoreToSafepointRegisterSlot(v0, result);
}
void LCodeGen::DoToFastProperties(LToFastProperties* instr) {
- ASSERT(ToRegister(instr->value()).is(a0));
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->value()).is(a0));
+ DCHECK(ToRegister(instr->result()).is(v0));
__ push(a0);
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:
// t3 = literals array.
@@ -5414,7 +5426,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
__ li(t1, Operand(instr->hydrogen()->pattern()));
__ li(t0, Operand(instr->hydrogen()->flags()));
__ Push(t3, t2, t1, t0);
- CallRuntime(Runtime::kHiddenMaterializeRegExpLiteral, 4, instr);
+ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4, instr);
__ mov(a1, v0);
__ bind(&materialized);
@@ -5427,7 +5439,7 @@ void LCodeGen::DoRegExpLiteral(LRegExpLiteral* instr) {
__ bind(&runtime_allocate);
__ li(a0, Operand(Smi::FromInt(size)));
__ Push(a1, a0);
- CallRuntime(Runtime::kHiddenAllocateInNewSpace, 1, instr);
+ CallRuntime(Runtime::kAllocateInNewSpace, 1, instr);
__ pop(a1);
__ bind(&allocated);
@@ -5447,7 +5459,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();
@@ -5462,13 +5474,13 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
__ li(a1, Operand(pretenure ? factory()->true_value()
: factory()->false_value()));
__ Push(cp, a2, a1);
- CallRuntime(Runtime::kHiddenNewClosure, 3, instr);
+ CallRuntime(Runtime::kNewClosure, 3, instr);
}
}
void LCodeGen::DoTypeof(LTypeof* instr) {
- ASSERT(ToRegister(instr->result()).is(v0));
+ DCHECK(ToRegister(instr->result()).is(v0));
Register input = ToRegister(instr->value());
__ push(input);
CallRuntime(Runtime::kTypeof, 1, instr);
@@ -5485,11 +5497,11 @@ void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
instr->FalseLabel(chunk_),
input,
instr->type_literal(),
- cmp1,
- cmp2);
+ &cmp1,
+ &cmp2);
- ASSERT(cmp1.is_valid());
- ASSERT(!cmp2.is_reg() || cmp2.rm().is_valid());
+ DCHECK(cmp1.is_valid());
+ DCHECK(!cmp2.is_reg() || cmp2.rm().is_valid());
if (final_branch_condition != kNoCondition) {
EmitBranch(instr, final_branch_condition, cmp1, cmp2);
@@ -5501,8 +5513,8 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
Label* false_label,
Register input,
Handle<String> type_name,
- Register& cmp1,
- Operand& cmp2) {
+ Register* cmp1,
+ Operand* cmp2) {
// This function utilizes the delay slot heavily. This is used to load
// values that are always usable without depending on the type of the input
// register.
@@ -5513,8 +5525,8 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
__ JumpIfSmi(input, true_label);
__ lw(input, FieldMemOperand(input, HeapObject::kMapOffset));
__ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
- cmp1 = input;
- cmp2 = Operand(at);
+ *cmp1 = input;
+ *cmp2 = Operand(at);
final_branch_condition = eq;
} else if (String::Equals(type_name, factory->string_string())) {
@@ -5526,30 +5538,23 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
// other branch.
__ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset));
__ And(at, at, 1 << Map::kIsUndetectable);
- cmp1 = at;
- cmp2 = Operand(zero_reg);
+ *cmp1 = at;
+ *cmp2 = Operand(zero_reg);
final_branch_condition = eq;
} else if (String::Equals(type_name, factory->symbol_string())) {
__ JumpIfSmi(input, false_label);
__ GetObjectType(input, input, scratch);
- cmp1 = scratch;
- cmp2 = Operand(SYMBOL_TYPE);
+ *cmp1 = scratch;
+ *cmp2 = Operand(SYMBOL_TYPE);
final_branch_condition = eq;
} else if (String::Equals(type_name, factory->boolean_string())) {
__ LoadRoot(at, Heap::kTrueValueRootIndex);
__ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
__ LoadRoot(at, Heap::kFalseValueRootIndex);
- cmp1 = at;
- cmp2 = Operand(input);
- final_branch_condition = eq;
-
- } else if (FLAG_harmony_typeof &&
- String::Equals(type_name, factory->null_string())) {
- __ LoadRoot(at, Heap::kNullValueRootIndex);
- cmp1 = at;
- cmp2 = Operand(input);
+ *cmp1 = at;
+ *cmp2 = Operand(input);
final_branch_condition = eq;
} else if (String::Equals(type_name, factory->undefined_string())) {
@@ -5562,8 +5567,8 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
__ lw(input, FieldMemOperand(input, HeapObject::kMapOffset));
__ lbu(at, FieldMemOperand(input, Map::kBitFieldOffset));
__ And(at, at, 1 << Map::kIsUndetectable);
- cmp1 = at;
- cmp2 = Operand(zero_reg);
+ *cmp1 = at;
+ *cmp2 = Operand(zero_reg);
final_branch_condition = ne;
} else if (String::Equals(type_name, factory->function_string())) {
@@ -5571,16 +5576,14 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
__ JumpIfSmi(input, false_label);
__ GetObjectType(input, scratch, input);
__ Branch(true_label, eq, input, Operand(JS_FUNCTION_TYPE));
- cmp1 = input;
- cmp2 = Operand(JS_FUNCTION_PROXY_TYPE);
+ *cmp1 = input;
+ *cmp2 = Operand(JS_FUNCTION_PROXY_TYPE);
final_branch_condition = eq;
} else if (String::Equals(type_name, factory->object_string())) {
__ JumpIfSmi(input, false_label);
- if (!FLAG_harmony_typeof) {
- __ LoadRoot(at, Heap::kNullValueRootIndex);
- __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
- }
+ __ LoadRoot(at, Heap::kNullValueRootIndex);
+ __ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
Register map = input;
__ GetObjectType(input, map, scratch);
__ Branch(false_label,
@@ -5591,13 +5594,13 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
// Check for undetectable objects => false.
__ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
__ And(at, at, 1 << Map::kIsUndetectable);
- cmp1 = at;
- cmp2 = Operand(zero_reg);
+ *cmp1 = at;
+ *cmp2 = Operand(zero_reg);
final_branch_condition = eq;
} else {
- cmp1 = at;
- cmp2 = Operand(zero_reg); // Set to valid regs, to avoid caller assertion.
+ *cmp1 = at;
+ *cmp2 = Operand(zero_reg); // Set to valid regs, to avoid caller assertion.
__ Branch(false_label);
}
@@ -5616,7 +5619,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.
__ lw(temp1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
@@ -5640,7 +5643,7 @@ void LCodeGen::EnsureSpaceForLazyDeopt(int space_needed) {
int current_pc = masm()->pc_offset();
if (current_pc < last_lazy_deopt_pc_ + space_needed) {
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;
@@ -5653,7 +5656,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());
@@ -5686,12 +5689,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());
}
@@ -5710,7 +5713,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.
@@ -5719,14 +5722,14 @@ void LCodeGen::DoStackCheck(LStackCheck* instr) {
Label done;
__ LoadRoot(at, Heap::kStackLimitRootIndex);
__ Branch(&done, hs, sp, Operand(at));
- ASSERT(instr->context()->IsRegister());
- ASSERT(ToRegister(instr->context()).is(cp));
+ DCHECK(instr->context()->IsRegister());
+ DCHECK(ToRegister(instr->context()).is(cp));
CallCode(isolate()->builtins()->StackCheck(),
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);
@@ -5751,7 +5754,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();
@@ -5776,7 +5779,7 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
DeoptimizeIf(le, instr->environment(), a1, Operand(LAST_JS_PROXY_TYPE));
Label use_cache, call_runtime;
- ASSERT(object.is(a0));
+ DCHECK(object.is(a0));
__ CheckEnumCache(null_value, &call_runtime);
__ lw(result, FieldMemOperand(object, HeapObject::kMapOffset));
@@ -5788,7 +5791,7 @@ void LCodeGen::DoForInPrepareMap(LForInPrepareMap* instr) {
CallRuntime(Runtime::kGetPropertyNamesFast, 1, instr);
__ lw(a1, FieldMemOperand(v0, HeapObject::kMapOffset));
- ASSERT(result.is(v0));
+ DCHECK(result.is(v0));
__ LoadRoot(at, Heap::kMetaMapRootIndex);
DeoptimizeIf(ne, instr->environment(), a1, Operand(at));
__ bind(&use_cache);
@@ -5828,7 +5831,7 @@ void LCodeGen::DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
Register result,
Register object,
Register index) {
- PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ PushSafepointRegistersScope scope(this);
__ Push(object, index);
__ mov(cp, zero_reg);
__ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble);
@@ -5898,6 +5901,21 @@ void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) {
}
+void LCodeGen::DoStoreFrameContext(LStoreFrameContext* instr) {
+ Register context = ToRegister(instr->context());
+ __ sw(context, MemOperand(fp, StandardFrameConstants::kContextOffset));
+}
+
+
+void LCodeGen::DoAllocateBlockContext(LAllocateBlockContext* instr) {
+ Handle<ScopeInfo> scope_info = instr->scope_info();
+ __ li(at, scope_info);
+ __ Push(at, ToRegister(instr->function()));
+ CallRuntime(Runtime::kPushBlockContext, 2, instr);
+ RecordSafepoint(Safepoint::kNoLazyDeopt);
+}
+
+
#undef __
} } // namespace v8::internal