Reviewers: ulan, jochen,
Description:
A64: Improve the deoptimization helpers to generate fewer instructions.
Please review this at https://codereview.chromium.org/166343004/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+42, -44 lines):
M src/a64/lithium-codegen-a64.h
M src/a64/lithium-codegen-a64.cc
Index: src/a64/lithium-codegen-a64.cc
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index
033a439513672589c0727811ac25f47fd4d984a6..703399213cca10f6f72888c01d36618110ee9971
100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -1005,8 +1005,11 @@ Deoptimizer::BailoutType LCodeGen::DeoptimizeHeader(
}
-void LCodeGen::Deoptimize(LEnvironment* environment,
- Deoptimizer::BailoutType bailout_type) {
+void LCodeGen::DeoptimizeBranch(LEnvironment* environment,
+ Deoptimizer::BailoutType bailout_type,
+ BranchType branch_type,
+ Register reg,
+ int bit) {
ASSERT(environment->HasBeenRegistered());
ASSERT(info()->IsOptimizing() || info()->IsStub());
int id = environment->deoptimization_index();
@@ -1014,13 +1017,19 @@ void LCodeGen::Deoptimize(LEnvironment* environment,
Deoptimizer::GetDeoptimizationEntry(isolate(), id, bailout_type);
if (info()->ShouldTrapOnDeopt()) {
+ Label dont_trap;
+ __ B(&dont_trap, InvertBranchType(branch_type), reg, bit);
__ Debug("trap_on_deopt", __LINE__, BREAK);
+ __ Bind(&dont_trap);
}
ASSERT(info()->IsStub() || frame_is_built_);
// Go through jump table if we need to build frame, or restore caller
doubles.
if (frame_is_built_ && !info()->saves_caller_doubles()) {
+ Label dont_deopt;
+ __ B(&dont_deopt, InvertBranchType(branch_type), reg, bit);
__ Call(entry, RelocInfo::RUNTIME_ENTRY);
+ __ Bind(&dont_deopt);
} else {
// We often have several deopts to the same entry, reuse the last
// jump entry if this is the case.
@@ -1033,82 +1042,63 @@ void LCodeGen::Deoptimize(LEnvironment* environment,
!frame_is_built_);
deopt_jump_table_.Add(table_entry, zone());
}
- __ B(&deopt_jump_table_.last().label);
+ __ B(&deopt_jump_table_.last().label,
+ branch_type, reg, bit);
}
}
+void LCodeGen::Deoptimize(LEnvironment* environment,
+ Deoptimizer::BailoutType bailout_type) {
+ DeoptimizeBranch(environment, bailout_type, always);
+}
+
+
void LCodeGen::Deoptimize(LEnvironment* environment) {
- Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment,
NULL);
- Deoptimize(environment, bailout_type);
+ DeoptimizeBranch(environment, always);
}
void LCodeGen::DeoptimizeIf(Condition cond, LEnvironment* environment) {
- Label dont_deopt;
- Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment,
NULL);
- __ B(InvertCondition(cond), &dont_deopt);
- Deoptimize(environment, bailout_type);
- __ Bind(&dont_deopt);
+ DeoptimizeBranch(environment, static_cast<BranchType>(cond));
}
void LCodeGen::DeoptimizeIfZero(Register rt, LEnvironment* environment) {
- Label dont_deopt;
- Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment,
NULL);
- __ Cbnz(rt, &dont_deopt);
- Deoptimize(environment, bailout_type);
- __ Bind(&dont_deopt);
+ DeoptimizeBranch(environment, reg_zero, rt);
}
void LCodeGen::DeoptimizeIfNegative(Register rt, LEnvironment*
environment) {
- Label dont_deopt;
- Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment,
NULL);
- __ Tbz(rt, rt.Is64Bits() ? kXSignBit : kWSignBit, &dont_deopt);
- Deoptimize(environment, bailout_type);
- __ Bind(&dont_deopt);
+ int sign_bit = rt.Is64Bits() ? kXSignBit : kWSignBit;
+ DeoptimizeBranch(environment, reg_bit_set, rt, sign_bit);
}
void LCodeGen::DeoptimizeIfSmi(Register rt,
LEnvironment* environment) {
- Label dont_deopt;
- Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment,
NULL);
- __ JumpIfNotSmi(rt, &dont_deopt);
- Deoptimize(environment, bailout_type);
- __ Bind(&dont_deopt);
+ DeoptimizeBranch(environment, reg_bit_clear, rt, MaskToBit(kSmiTagMask));
}
void LCodeGen::DeoptimizeIfNotSmi(Register rt, LEnvironment* environment) {
- Label dont_deopt;
- Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment,
NULL);
- __ JumpIfSmi(rt, &dont_deopt);
- Deoptimize(environment, bailout_type);
- __ Bind(&dont_deopt);
+ DeoptimizeBranch(environment, reg_bit_set, rt, MaskToBit(kSmiTagMask));
}
void LCodeGen::DeoptimizeIfRoot(Register rt,
Heap::RootListIndex index,
LEnvironment* environment) {
- Label dont_deopt;
- Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment,
NULL);
- __ JumpIfNotRoot(rt, index, &dont_deopt);
- Deoptimize(environment, bailout_type);
- __ Bind(&dont_deopt);
+ __ CompareRoot(rt, index);
+ DeoptimizeIf(eq, environment);
}
void LCodeGen::DeoptimizeIfNotRoot(Register rt,
Heap::RootListIndex index,
LEnvironment* environment) {
- Label dont_deopt;
- Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment,
NULL);
- __ JumpIfRoot(rt, index, &dont_deopt);
- Deoptimize(environment, bailout_type);
- __ Bind(&dont_deopt);
+ __ CompareRoot(rt, index);
+ DeoptimizeIf(ne, environment);
}
@@ -2126,9 +2116,6 @@ void LCodeGen::DoCheckMaps(LCheckMaps* instr) {
void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
if (!instr->hydrogen()->value()->IsHeapObject()) {
- // TODO(all): Depending of how we chose to implement the deopt, if we
could
- // guarantee that we have a deopt handler reachable by a tbz
instruction,
- // we could use tbz here and produce less code to support this
instruction.
DeoptimizeIfSmi(ToRegister(instr->value()), instr->environment());
}
}
@@ -2137,7 +2124,6 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) {
void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
Register value = ToRegister(instr->value());
ASSERT(!instr->result() || ToRegister(instr->result()).Is(value));
- // TODO(all): See DoCheckNonSmi for comments on use of tbz.
DeoptimizeIfNotSmi(value, instr->environment());
}
Index: src/a64/lithium-codegen-a64.h
diff --git a/src/a64/lithium-codegen-a64.h b/src/a64/lithium-codegen-a64.h
index
006165157f46740fd44428a3a4322eb64c56ad7b..0889fb2a24940674e0073d9f63c2ac1477f81480
100644
--- a/src/a64/lithium-codegen-a64.h
+++ b/src/a64/lithium-codegen-a64.h
@@ -221,6 +221,18 @@ class LCodeGen: public LCodeGenBase {
Deoptimizer::BailoutType DeoptimizeHeader(
LEnvironment* environment,
Deoptimizer::BailoutType* override_bailout_type);
+ void DeoptimizeBranch(LEnvironment* environment,
+ Deoptimizer::BailoutType bailout_type,
+ BranchType branch_type,
+ Register reg = NoReg,
+ int bit = -1);
+ void DeoptimizeBranch(LEnvironment* environment,
+ BranchType branch_type,
+ Register reg = NoReg,
+ int bit = -1) {
+ Deoptimizer::BailoutType bailout_type = DeoptimizeHeader(environment,
NULL);
+ DeoptimizeBranch(environment, bailout_type, branch_type, reg, bit);
+ }
void Deoptimize(LEnvironment* environment);
void Deoptimize(LEnvironment* environment,
Deoptimizer::BailoutType bailout_type);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.