Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1175)

Unified Diff: src/mips/lithium-codegen-mips.cc

Issue 142813003: A64: Synchronize with r15358. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/mips/lithium-codegen-mips.h ('k') | src/mips/lithium-mips.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips/lithium-codegen-mips.cc
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 9649eb99efdbe43724bc266df6cb7f8f7fdf6d40..6751be716081fa214dd8a3dc8189e4b9f2fcdfd5 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -62,7 +62,7 @@ class SafepointGenerator : public CallWrapper {
#define __ masm()->
bool LCodeGen::GenerateCode() {
- HPhase phase("Z_Code generation", chunk());
+ LPhase phase("Z_Code generation", chunk());
ASSERT(is_unused());
status_ = GENERATING;
@@ -87,7 +87,7 @@ void LCodeGen::FinishCode(Handle<Code> code) {
RegisterDependentCodeForEmbeddedMaps(code);
}
PopulateDeoptimizationData(code);
- info()->CommitDependentMaps(code);
+ info()->CommitDependencies(code);
}
@@ -243,7 +243,6 @@ bool LCodeGen::GeneratePrologue() {
if (FLAG_trace && info()->IsOptimizing()) {
__ CallRuntime(Runtime::kTraceEnter, 0);
}
- EnsureSpaceForLazyDeopt();
return !is_aborted();
}
@@ -271,6 +270,7 @@ bool LCodeGen::GenerateBody() {
instr->CompileToNative(this);
}
+ EnsureSpaceForLazyDeopt();
return !is_aborted();
}
@@ -603,27 +603,6 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
for (int i = 0; i < translation_size; ++i) {
LOperand* value = environment->values()->at(i);
- // spilled_registers_ and spilled_double_registers_ are either
- // both NULL or both set.
- if (environment->spilled_registers() != NULL && value != NULL) {
- if (value->IsRegister() &&
- environment->spilled_registers()[value->index()] != NULL) {
- translation->MarkDuplicate();
- AddToTranslation(translation,
- environment->spilled_registers()[value->index()],
- environment->HasTaggedValueAt(i),
- environment->HasUint32ValueAt(i));
- } else if (
- value->IsDoubleRegister() &&
- environment->spilled_double_registers()[value->index()] != NULL) {
- translation->MarkDuplicate();
- AddToTranslation(
- translation,
- environment->spilled_double_registers()[value->index()],
- false,
- false);
- }
- }
// TODO(mstarzinger): Introduce marker operands to indicate that this value
// is not present and must be reconstructed from the deoptimizer. Currently
@@ -633,12 +612,6 @@ void LCodeGen::WriteTranslation(LEnvironment* environment,
translation->BeginArgumentsObject(arguments_count);
for (int i = 0; i < arguments_count; ++i) {
LOperand* value = environment->values()->at(translation_size + i);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsRegister() ||
- environment->spilled_registers()[value->index()] == NULL);
- ASSERT(environment->spilled_registers() == NULL ||
- !value->IsDoubleRegister() ||
- environment->spilled_double_registers()[value->index()] == NULL);
AddToTranslation(translation,
value,
environment->HasTaggedValueAt(translation_size + i),
@@ -706,6 +679,7 @@ void LCodeGen::CallCodeGeneric(Handle<Code> code,
RelocInfo::Mode mode,
LInstruction* instr,
SafepointMode safepoint_mode) {
+ EnsureSpaceForLazyDeopt();
ASSERT(instr != NULL);
LPointerMap* pointers = instr->pointer_map();
RecordPosition(pointers->position());
@@ -1100,7 +1074,8 @@ void LCodeGen::DoCallStub(LCallStub* instr) {
void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) {
- // Nothing to do.
+ // Record the address of the first unknown OSR value as the place to enter.
+ if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset();
}
@@ -1136,9 +1111,37 @@ void LCodeGen::DoModI(LModI* instr) {
__ And(result_reg, scratch, divisor - 1);
__ bind(&done);
- } else {
- // TODO(svenpanne) Add right->has_fixed_right_arg() case.
+ } else if (hmod->fixed_right_arg().has_value) {
+ const Register scratch = scratch0();
+ const Register left_reg = ToRegister(instr->left());
+ const Register result_reg = ToRegister(instr->result());
+
+ Register right_reg = EmitLoadRegister(instr->right(), scratch);
+ int32_t divisor = hmod->fixed_right_arg().value;
+ ASSERT(IsPowerOf2(divisor));
+
+ // Check if our assumption of a fixed right operand still holds.
+ DeoptimizeIf(ne, instr->environment(), right_reg, Operand(divisor));
+
+ Label left_is_not_negative, done;
+ if (left->CanBeNegative()) {
+ __ Branch(USE_DELAY_SLOT, &left_is_not_negative,
+ ge, left_reg, Operand(zero_reg));
+ __ subu(result_reg, zero_reg, left_reg);
+ __ And(result_reg, result_reg, divisor - 1);
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg));
+ }
+ __ Branch(USE_DELAY_SLOT, &done);
+ __ subu(result_reg, zero_reg, result_reg);
+ }
+
+ __ bind(&left_is_not_negative);
+ __ And(result_reg, left_reg, divisor - 1);
+ __ bind(&done);
+
+ } else {
const Register scratch = scratch0();
const Register left_reg = ToRegister(instr->left());
const Register result_reg = ToRegister(instr->result());
@@ -1706,9 +1709,11 @@ void LCodeGen::DoValueOf(LValueOf* instr) {
Register map = ToRegister(instr->temp());
Label done;
- // If the object is a smi return the object.
- __ Move(result, input);
- __ JumpIfSmi(input, &done);
+ if (!instr->hydrogen()->value()->IsHeapObject()) {
+ // If the object is a smi return the object.
+ __ Move(result, input);
+ __ JumpIfSmi(input, &done);
+ }
// If the object is not a value type, return the object.
__ GetObjectType(input, map, map);
@@ -1970,12 +1975,13 @@ int LCodeGen::GetNextEmittedBlock() const {
return -1;
}
-
-void LCodeGen::EmitBranch(int left_block, int right_block,
+template<class InstrType>
+void LCodeGen::EmitBranch(InstrType instr,
Condition cc, Register src1, const Operand& src2) {
+ int right_block = instr->FalseDestination(chunk_);
+ int left_block = instr->TrueDestination(chunk_);
+
int next_block = GetNextEmittedBlock();
- right_block = chunk_->LookupDestination(right_block);
- left_block = chunk_->LookupDestination(left_block);
if (right_block == left_block) {
EmitGoto(left_block);
} else if (left_block == next_block) {
@@ -1990,11 +1996,13 @@ void LCodeGen::EmitBranch(int left_block, int right_block,
}
-void LCodeGen::EmitBranchF(int left_block, int right_block,
+template<class InstrType>
+void LCodeGen::EmitBranchF(InstrType instr,
Condition cc, FPURegister src1, FPURegister src2) {
+ int right_block = instr->FalseDestination(chunk_);
+ int left_block = instr->TrueDestination(chunk_);
+
int next_block = GetNextEmittedBlock();
- right_block = chunk_->LookupDestination(right_block);
- left_block = chunk_->LookupDestination(left_block);
if (right_block == left_block) {
EmitGoto(left_block);
} else if (left_block == next_block) {
@@ -2015,19 +2023,16 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
void LCodeGen::DoBranch(LBranch* instr) {
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
-
Representation r = instr->hydrogen()->value()->representation();
if (r.IsInteger32() || r.IsSmi()) {
ASSERT(!info()->IsStub());
Register reg = ToRegister(instr->value());
- EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
+ EmitBranch(instr, ne, reg, Operand(zero_reg));
} else if (r.IsDouble()) {
ASSERT(!info()->IsStub());
DoubleRegister reg = ToDoubleRegister(instr->value());
// Test the double value. Zero and NaN are false.
- EmitBranchF(true_block, false_block, nue, reg, kDoubleRegZero);
+ EmitBranchF(instr, nue, reg, kDoubleRegZero);
} else {
ASSERT(r.IsTagged());
Register reg = ToRegister(instr->value());
@@ -2035,40 +2040,50 @@ void LCodeGen::DoBranch(LBranch* instr) {
if (type.IsBoolean()) {
ASSERT(!info()->IsStub());
__ LoadRoot(at, Heap::kTrueValueRootIndex);
- EmitBranch(true_block, false_block, eq, reg, Operand(at));
+ EmitBranch(instr, eq, reg, Operand(at));
} else if (type.IsSmi()) {
ASSERT(!info()->IsStub());
- EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg));
+ EmitBranch(instr, ne, reg, Operand(zero_reg));
+ } else if (type.IsJSArray()) {
+ ASSERT(!info()->IsStub());
+ EmitBranch(instr, al, zero_reg, Operand(zero_reg));
+ } else if (type.IsHeapNumber()) {
+ ASSERT(!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());
+ __ lw(at, FieldMemOperand(reg, String::kLengthOffset));
+ EmitBranch(instr, ne, at, Operand(zero_reg));
} else {
- Label* true_label = chunk_->GetAssemblyLabel(true_block);
- Label* false_label = chunk_->GetAssemblyLabel(false_block);
-
ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
// Avoid deopts in the case where we've never executed this path before.
- if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
+ if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic();
if (expected.Contains(ToBooleanStub::UNDEFINED)) {
// undefined -> false.
__ LoadRoot(at, Heap::kUndefinedValueRootIndex);
- __ Branch(false_label, eq, reg, Operand(at));
+ __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
}
if (expected.Contains(ToBooleanStub::BOOLEAN)) {
// Boolean -> its value.
__ LoadRoot(at, Heap::kTrueValueRootIndex);
- __ Branch(true_label, eq, reg, Operand(at));
+ __ Branch(instr->TrueLabel(chunk_), eq, reg, Operand(at));
__ LoadRoot(at, Heap::kFalseValueRootIndex);
- __ Branch(false_label, eq, reg, Operand(at));
+ __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
}
if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
// 'null' -> false.
__ LoadRoot(at, Heap::kNullValueRootIndex);
- __ Branch(false_label, eq, reg, Operand(at));
+ __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(at));
}
if (expected.Contains(ToBooleanStub::SMI)) {
// Smis: 0 -> false, all other -> true.
- __ Branch(false_label, eq, reg, Operand(zero_reg));
- __ JumpIfSmi(reg, true_label);
+ __ Branch(instr->FalseLabel(chunk_), eq, reg, Operand(zero_reg));
+ __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
} else if (expected.NeedsMap()) {
// If we need a map later and have a Smi -> deopt.
__ And(at, reg, Operand(kSmiTagMask));
@@ -2082,14 +2097,15 @@ void LCodeGen::DoBranch(LBranch* instr) {
// Undetectable -> false.
__ lbu(at, FieldMemOperand(map, Map::kBitFieldOffset));
__ And(at, at, Operand(1 << Map::kIsUndetectable));
- __ Branch(false_label, ne, at, Operand(zero_reg));
+ __ Branch(instr->FalseLabel(chunk_), ne, at, Operand(zero_reg));
}
}
if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
// spec object -> true.
__ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
- __ Branch(true_label, ge, at, Operand(FIRST_SPEC_OBJECT_TYPE));
+ __ Branch(instr->TrueLabel(chunk_),
+ ge, at, Operand(FIRST_SPEC_OBJECT_TYPE));
}
if (expected.Contains(ToBooleanStub::STRING)) {
@@ -2098,8 +2114,8 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ lbu(at, FieldMemOperand(map, Map::kInstanceTypeOffset));
__ Branch(&not_string, ge , at, Operand(FIRST_NONSTRING_TYPE));
__ lw(at, FieldMemOperand(reg, String::kLengthOffset));
- __ Branch(true_label, ne, at, Operand(zero_reg));
- __ Branch(false_label);
+ __ Branch(instr->TrueLabel(chunk_), ne, at, Operand(zero_reg));
+ __ Branch(instr->FalseLabel(chunk_));
__ bind(&not_string);
}
@@ -2107,7 +2123,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
// Symbol value -> true.
const Register scratch = scratch1();
__ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
- __ Branch(true_label, eq, scratch, Operand(SYMBOL_TYPE));
+ __ Branch(instr->TrueLabel(chunk_), eq, scratch, Operand(SYMBOL_TYPE));
}
if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
@@ -2117,14 +2133,18 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ LoadRoot(at, Heap::kHeapNumberMapRootIndex);
__ Branch(&not_heap_number, ne, map, Operand(at));
__ ldc1(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
- __ BranchF(true_label, false_label, ne, dbl_scratch, kDoubleRegZero);
+ __ BranchF(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
+ ne, dbl_scratch, kDoubleRegZero);
// Falls through if dbl_scratch == 0.
- __ Branch(false_label);
+ __ Branch(instr->FalseLabel(chunk_));
__ bind(&not_heap_number);
}
- // We've seen something for the first time -> deopt.
- DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg));
+ if (!expected.IsGeneric()) {
+ // We've seen something for the first time -> deopt.
+ // This can only happen if we are not generic already.
+ DeoptimizeIf(al, instr->environment(), zero_reg, Operand(zero_reg));
+ }
}
}
}
@@ -2132,7 +2152,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
void LCodeGen::EmitGoto(int block) {
if (!IsNextEmittedBlock(block)) {
- __ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block)));
+ __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
}
}
@@ -2173,18 +2193,14 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
- int false_block = chunk_->LookupDestination(instr->false_block_id());
- int true_block = chunk_->LookupDestination(instr->true_block_id());
-
Condition cond = TokenToCondition(instr->op(), false);
if (left->IsConstantOperand() && right->IsConstantOperand()) {
// We can statically evaluate the comparison.
double left_val = ToDouble(LConstantOperand::cast(left));
double right_val = ToDouble(LConstantOperand::cast(right));
- int next_block =
- EvalComparison(instr->op(), left_val, right_val) ? true_block
- : false_block;
+ int next_block = EvalComparison(instr->op(), left_val, right_val) ?
+ instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
EmitGoto(next_block);
} else {
if (instr->is_double()) {
@@ -2195,10 +2211,10 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
// If a NaN is involved, i.e. the result is unordered,
// jump to false block label.
- __ BranchF(NULL, chunk_->GetAssemblyLabel(false_block), eq,
+ __ BranchF(NULL, instr->FalseLabel(chunk_), eq,
left_reg, right_reg);
- EmitBranchF(true_block, false_block, cond, left_reg, right_reg);
+ EmitBranchF(instr, cond, left_reg, right_reg);
} else {
Register cmp_left;
Operand cmp_right = Operand(0);
@@ -2228,7 +2244,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
cmp_right = Operand(ToRegister(right));
}
- EmitBranch(true_block, false_block, cond, cmp_left, cmp_right);
+ EmitBranch(instr, cond, cmp_left, cmp_right);
}
}
}
@@ -2237,20 +2253,15 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
Register left = ToRegister(instr->left());
Register right = ToRegister(instr->right());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- EmitBranch(true_block, false_block, eq, left, Operand(right));
+ EmitBranch(instr, eq, left, Operand(right));
}
void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
Register left = ToRegister(instr->left());
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
- EmitBranch(true_block, false_block, eq, left,
- Operand(instr->hydrogen()->right()));
+ EmitBranch(instr, eq, left, Operand(instr->hydrogen()->right()));
}
@@ -2285,23 +2296,22 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
Register temp1 = ToRegister(instr->temp());
Register temp2 = scratch0();
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
- Label* true_label = chunk_->GetAssemblyLabel(true_block);
- Label* false_label = chunk_->GetAssemblyLabel(false_block);
-
Condition true_cond =
- EmitIsObject(reg, temp1, temp2, false_label, true_label);
+ EmitIsObject(reg, temp1, temp2,
+ instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
- EmitBranch(true_block, false_block, true_cond, temp2,
+ EmitBranch(instr, true_cond, temp2,
Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
}
Condition LCodeGen::EmitIsString(Register input,
Register temp1,
- Label* is_not_string) {
- __ JumpIfSmi(input, is_not_string);
+ Label* is_not_string,
+ SmiCheck check_needed = INLINE_SMI_CHECK) {
+ if (check_needed == INLINE_SMI_CHECK) {
+ __ JumpIfSmi(input, is_not_string);
+ }
__ GetObjectType(input, temp1, temp1);
return lt;
@@ -2312,25 +2322,21 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
Register reg = ToRegister(instr->value());
Register temp1 = ToRegister(instr->temp());
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
- Label* false_label = chunk_->GetAssemblyLabel(false_block);
-
+ SmiCheck check_needed =
+ instr->hydrogen()->value()->IsHeapObject()
+ ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
Condition true_cond =
- EmitIsString(reg, temp1, false_label);
+ EmitIsString(reg, temp1, instr->FalseLabel(chunk_), check_needed);
- EmitBranch(true_block, false_block, true_cond, temp1,
+ EmitBranch(instr, true_cond, temp1,
Operand(FIRST_NONSTRING_TYPE));
}
void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
-
Register input_reg = EmitLoadRegister(instr->value(), at);
__ And(at, input_reg, kSmiTagMask);
- EmitBranch(true_block, false_block, eq, at, Operand(zero_reg));
+ EmitBranch(instr, eq, at, Operand(zero_reg));
}
@@ -2338,14 +2344,13 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
Register input = ToRegister(instr->value());
Register temp = ToRegister(instr->temp());
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
-
- __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
+ if (!instr->hydrogen()->value()->IsHeapObject()) {
+ __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+ }
__ lw(temp, FieldMemOperand(input, HeapObject::kMapOffset));
__ lbu(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
__ And(at, temp, Operand(1 << Map::kIsUndetectable));
- EmitBranch(true_block, false_block, ne, at, Operand(zero_reg));
+ EmitBranch(instr, ne, at, Operand(zero_reg));
}
@@ -2371,15 +2376,13 @@ static Condition ComputeCompareCondition(Token::Value op) {
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
Token::Value op = instr->op();
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
CallCode(ic, RelocInfo::CODE_TARGET, instr);
Condition condition = ComputeCompareCondition(op);
- EmitBranch(true_block, false_block, condition, v0, Operand(zero_reg));
+ EmitBranch(instr, condition, v0, Operand(zero_reg));
}
@@ -2407,16 +2410,12 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
Register scratch = scratch0();
Register input = ToRegister(instr->value());
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
-
- Label* false_label = chunk_->GetAssemblyLabel(false_block);
-
- __ JumpIfSmi(input, false_label);
+ if (!instr->hydrogen()->value()->IsHeapObject()) {
+ __ JumpIfSmi(input, instr->FalseLabel(chunk_));
+ }
__ GetObjectType(input, scratch, scratch);
- EmitBranch(true_block,
- false_block,
+ EmitBranch(instr,
BranchCondition(instr->hydrogen()),
scratch,
Operand(TestType(instr->hydrogen())));
@@ -2439,13 +2438,10 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
Register input = ToRegister(instr->value());
Register scratch = scratch0();
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
-
__ lw(scratch,
FieldMemOperand(input, String::kHashFieldOffset));
__ And(at, scratch, Operand(String::kContainsCachedArrayIndexMask));
- EmitBranch(true_block, false_block, eq, at, Operand(zero_reg));
+ EmitBranch(instr, eq, at, Operand(zero_reg));
}
@@ -2521,26 +2517,19 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
Register temp2 = ToRegister(instr->temp());
Handle<String> class_name = instr->hydrogen()->class_name();
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
+ EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
+ class_name, input, temp, temp2);
- Label* true_label = chunk_->GetAssemblyLabel(true_block);
- Label* false_label = chunk_->GetAssemblyLabel(false_block);
-
- EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
-
- EmitBranch(true_block, false_block, eq, temp, Operand(class_name));
+ EmitBranch(instr, eq, temp, Operand(class_name));
}
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
Register reg = ToRegister(instr->value());
Register temp = ToRegister(instr->temp());
- int true_block = instr->true_block_id();
- int false_block = instr->false_block_id();
__ lw(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
- EmitBranch(true_block, false_block, eq, temp, Operand(instr->map()));
+ EmitBranch(instr, eq, temp, Operand(instr->map()));
}
@@ -2860,9 +2849,9 @@ void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) {
__ sw(value, target);
if (instr->hydrogen()->NeedsWriteBarrier()) {
- HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
- type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+ instr->hydrogen()->value()->IsHeapObject()
+ ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
__ RecordWriteContextSlot(context,
target.offset(),
value,
@@ -3625,6 +3614,7 @@ void LCodeGen::EmitIntegerMathAbs(LMathAbs* instr) {
Label done;
__ Branch(USE_DELAY_SLOT, &done, ge, input, Operand(zero_reg));
__ mov(result, input);
+ __ subu(result, zero_reg, input);
// Overflow if result is still negative, i.e. 0x80000000.
DeoptimizeIf(lt, instr->environment(), result, Operand(zero_reg));
__ bind(&done);
@@ -4044,12 +4034,9 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
ASSERT(ToRegister(instr->result()).is(v0));
__ li(a0, Operand(instr->arity()));
- if (FLAG_optimize_constructed_arrays) {
- // No cell in a2 for construct type feedback in optimized code
- Handle<Object> undefined_value(isolate()->heap()->undefined_value(),
- isolate());
- __ li(a2, Operand(undefined_value));
- }
+ // No cell in a2 for construct type feedback in optimized code
+ Handle<Object> undefined_value(isolate()->factory()->undefined_value());
+ __ li(a2, Operand(undefined_value));
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
}
@@ -4058,7 +4045,6 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
ASSERT(ToRegister(instr->constructor()).is(a1));
ASSERT(ToRegister(instr->result()).is(v0));
- ASSERT(FLAG_optimize_constructed_arrays);
__ li(a0, Operand(instr->arity()));
__ li(a2, Operand(instr->hydrogen()->property_cell()));
@@ -4153,9 +4139,9 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
// Do the store.
Register value = ToRegister(instr->value());
ASSERT(!object.is(value));
- HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
- type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+ instr->hydrogen()->value()->IsHeapObject()
+ ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
if (access.IsInobject()) {
__ sw(value, FieldMemOperand(object, offset));
if (instr->hydrogen()->NeedsWriteBarrier()) {
@@ -4380,9 +4366,9 @@ void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
__ sw(value, FieldMemOperand(store_base, offset));
if (instr->hydrogen()->NeedsWriteBarrier()) {
- HType type = instr->hydrogen()->value()->type();
SmiCheck check_needed =
- type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
+ instr->hydrogen()->value()->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));
__ RecordWrite(elements,
@@ -5133,9 +5119,11 @@ void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
- LOperand* input = instr->value();
- __ And(at, ToRegister(input), Operand(kSmiTagMask));
- DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
+ if (!instr->hydrogen()->value()->IsHeapObject()) {
+ LOperand* input = instr->value();
+ __ And(at, ToRegister(input), Operand(kSmiTagMask));
+ DeoptimizeIf(eq, instr->environment(), at, Operand(zero_reg));
+ }
}
@@ -5293,6 +5281,80 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {
}
+void LCodeGen::DoAllocateObject(LAllocateObject* instr) {
+ class DeferredAllocateObject: public LDeferredCode {
+ public:
+ DeferredAllocateObject(LCodeGen* codegen, LAllocateObject* instr)
+ : LDeferredCode(codegen), instr_(instr) { }
+ virtual void Generate() { codegen()->DoDeferredAllocateObject(instr_); }
+ virtual LInstruction* instr() { return instr_; }
+ private:
+ LAllocateObject* instr_;
+ };
+
+ DeferredAllocateObject* deferred =
+ new(zone()) DeferredAllocateObject(this, instr);
+
+ Register result = ToRegister(instr->result());
+ Register scratch = ToRegister(instr->temp());
+ Register scratch2 = ToRegister(instr->temp2());
+ Handle<JSFunction> constructor = instr->hydrogen()->constructor();
+ Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
+ int instance_size = initial_map->instance_size();
+ ASSERT(initial_map->pre_allocated_property_fields() +
+ initial_map->unused_property_fields() -
+ initial_map->inobject_properties() == 0);
+
+ __ Allocate(instance_size, result, scratch, scratch2, deferred->entry(),
+ TAG_OBJECT);
+
+ __ bind(deferred->exit());
+ if (FLAG_debug_code) {
+ Label is_in_new_space;
+ __ JumpIfInNewSpace(result, scratch, &is_in_new_space);
+ __ Abort("Allocated object is not in new-space");
+ __ bind(&is_in_new_space);
+ }
+
+ // Load the initial map.
+ Register map = scratch;
+ __ LoadHeapObject(map, constructor);
+ __ lw(map, FieldMemOperand(map, JSFunction::kPrototypeOrInitialMapOffset));
+
+ // Initialize map and fields of the newly allocated object.
+ ASSERT(initial_map->instance_type() == JS_OBJECT_TYPE);
+ __ sw(map, FieldMemOperand(result, JSObject::kMapOffset));
+ __ LoadRoot(scratch, Heap::kEmptyFixedArrayRootIndex);
+ __ sw(scratch, FieldMemOperand(result, JSObject::kElementsOffset));
+ __ sw(scratch, FieldMemOperand(result, JSObject::kPropertiesOffset));
+ if (initial_map->inobject_properties() != 0) {
+ __ LoadRoot(scratch, Heap::kUndefinedValueRootIndex);
+ for (int i = 0; i < initial_map->inobject_properties(); i++) {
+ int property_offset = JSObject::kHeaderSize + i * kPointerSize;
+ __ sw(scratch, FieldMemOperand(result, property_offset));
+ }
+ }
+}
+
+
+void LCodeGen::DoDeferredAllocateObject(LAllocateObject* instr) {
+ Register result = ToRegister(instr->result());
+ Handle<Map> initial_map = instr->hydrogen()->constructor_initial_map();
+ int instance_size = initial_map->instance_size();
+
+ // 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.
+ __ mov(result, zero_reg);
+
+ PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
+ __ li(a0, Operand(Smi::FromInt(instance_size)));
+ __ push(a0);
+ CallRuntimeFromDeferred(Runtime::kAllocateInNewSpace, 1, instr);
+ __ StoreToSafepointRegisterSlot(v0, result);
+}
+
+
void LCodeGen::DoAllocate(LAllocate* instr) {
class DeferredAllocate: public LDeferredCode {
public:
@@ -5460,16 +5522,12 @@ void LCodeGen::DoTypeof(LTypeof* instr) {
void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
Register input = ToRegister(instr->value());
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
- Label* true_label = chunk_->GetAssemblyLabel(true_block);
- Label* false_label = chunk_->GetAssemblyLabel(false_block);
Register cmp1 = no_reg;
Operand cmp2 = Operand(no_reg);
- Condition final_branch_condition = EmitTypeofIs(true_label,
- false_label,
+ Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_),
+ instr->FalseLabel(chunk_),
input,
instr->type_literal(),
cmp1,
@@ -5479,7 +5537,7 @@ void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
ASSERT(!cmp2.is_reg() || cmp2.rm().is_valid());
if (final_branch_condition != kNoCondition) {
- EmitBranch(true_block, false_block, final_branch_condition, cmp1, cmp2);
+ EmitBranch(instr, final_branch_condition, cmp1, cmp2);
}
}
@@ -5592,12 +5650,10 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
Register temp1 = ToRegister(instr->temp());
- int true_block = chunk_->LookupDestination(instr->true_block_id());
- int false_block = chunk_->LookupDestination(instr->false_block_id());
EmitIsConstructCall(temp1, scratch0());
- EmitBranch(true_block, false_block, eq, temp1,
+ EmitBranch(instr, eq, temp1,
Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
}
@@ -5748,15 +5804,15 @@ void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
// properly registered for deoptimization and records the assembler's PC
// offset.
LEnvironment* environment = instr->environment();
- environment->SetSpilledRegisters(instr->SpilledRegisterArray(),
- instr->SpilledDoubleRegisterArray());
// If the environment were already registered, we would have no way of
// backpatching it with the spill slot operands.
ASSERT(!environment->HasBeenRegistered());
RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
- ASSERT(osr_pc_offset_ == -1);
- osr_pc_offset_ = masm()->pc_offset();
+
+ // Normally we record the first unknown OSR value as the entrypoint to the OSR
+ // code, but if there were none, record the entrypoint here.
+ if (osr_pc_offset_ == -1) osr_pc_offset_ = masm()->pc_offset();
}
« no previous file with comments | « src/mips/lithium-codegen-mips.h ('k') | src/mips/lithium-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698