[es6] Add a flag to the Isolate that defines whether ES2015 tail call elimination is enabled or not.
Thus DevTools will be able to disable tail call elimination dynamically upon user's choice. BUG=v8:4698 LOG=N Review URL: https://codereview.chromium.org/1837513002 Cr-Commit-Position: refs/heads/master@{#35098}
This commit is contained in:
parent
e7cc6091f5
commit
7a33bd5da4
@ -1933,6 +1933,16 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is enabled.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ mov(scratch1, Operand(is_tail_call_elimination_enabled));
|
||||
__ ldrb(scratch1, MemOperand(scratch1));
|
||||
__ cmp(scratch1, Operand(0));
|
||||
__ b(eq, &done);
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
@ -1976,6 +1986,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -1977,6 +1977,16 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is enabled.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ Mov(scratch1, Operand(is_tail_call_elimination_enabled));
|
||||
__ Ldrb(scratch1, MemOperand(scratch1));
|
||||
__ Cmp(scratch1, Operand(0));
|
||||
__ B(eq, &done);
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
@ -2017,6 +2027,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -1632,6 +1632,10 @@ ExternalReference ExternalReference::cpu_features() {
|
||||
return ExternalReference(&CpuFeatures::supported_);
|
||||
}
|
||||
|
||||
ExternalReference ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
Isolate* isolate) {
|
||||
return ExternalReference(isolate->is_tail_call_elimination_enabled_address());
|
||||
}
|
||||
|
||||
ExternalReference ExternalReference::debug_is_active_address(
|
||||
Isolate* isolate) {
|
||||
|
@ -1029,6 +1029,9 @@ class ExternalReference BASE_EMBEDDED {
|
||||
|
||||
static ExternalReference cpu_features();
|
||||
|
||||
static ExternalReference is_tail_call_elimination_enabled_address(
|
||||
Isolate* isolate);
|
||||
|
||||
static ExternalReference debug_is_active_address(Isolate* isolate);
|
||||
static ExternalReference debug_after_break_target_address(Isolate* isolate);
|
||||
|
||||
|
@ -172,6 +172,9 @@ ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
|
||||
"Isolate::virtual_slot_register()");
|
||||
Add(ExternalReference::runtime_function_table_address(isolate).address(),
|
||||
"Runtime::runtime_function_table_address()");
|
||||
Add(ExternalReference::is_tail_call_elimination_enabled_address(isolate)
|
||||
.address(),
|
||||
"Isolate::is_tail_call_elimination_enabled_address()");
|
||||
|
||||
// Debug addresses
|
||||
Add(ExternalReference::debug_after_break_target_address(isolate).address(),
|
||||
|
@ -1886,6 +1886,16 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is enabled.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ movzx_b(scratch1,
|
||||
Operand::StaticVariable(is_tail_call_elimination_enabled));
|
||||
__ cmp(scratch1, Immediate(0));
|
||||
__ j(equal, &done, Label::kNear);
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
@ -1926,6 +1936,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3, ReturnAddressState::kOnStack, 0);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -1826,6 +1826,7 @@ Isolate::Isolate(bool enable_serializer)
|
||||
serializer_enabled_(enable_serializer),
|
||||
has_fatal_error_(false),
|
||||
initialized_from_snapshot_(false),
|
||||
is_tail_call_elimination_enabled_(true),
|
||||
cpu_profiler_(NULL),
|
||||
heap_profiler_(NULL),
|
||||
function_entry_hook_(NULL),
|
||||
|
@ -1089,6 +1089,16 @@ class Isolate {
|
||||
int GetNextUniqueSharedFunctionInfoId() { return next_unique_sfi_id_++; }
|
||||
#endif
|
||||
|
||||
// Support for dynamically disabling tail call elimination.
|
||||
Address is_tail_call_elimination_enabled_address() {
|
||||
return reinterpret_cast<Address>(&is_tail_call_elimination_enabled_);
|
||||
}
|
||||
bool is_tail_call_elimination_enabled() const {
|
||||
return is_tail_call_elimination_enabled_;
|
||||
}
|
||||
void set_tail_call_elimination_enabled(bool enabled) {
|
||||
is_tail_call_elimination_enabled_ = enabled;
|
||||
}
|
||||
|
||||
void AddDetachedContext(Handle<Context> context);
|
||||
void CheckDetachedContextsAfterGC();
|
||||
@ -1277,6 +1287,9 @@ class Isolate {
|
||||
// True if this isolate was initialized from a snapshot.
|
||||
bool initialized_from_snapshot_;
|
||||
|
||||
// True if ES2015 tail call elimination feature is enabled.
|
||||
bool is_tail_call_elimination_enabled_;
|
||||
|
||||
// Time stamp at initialization.
|
||||
double time_millis_at_init_;
|
||||
|
||||
|
@ -1957,6 +1957,15 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is enabled.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ li(at, Operand(is_tail_call_elimination_enabled));
|
||||
__ lb(scratch1, MemOperand(at));
|
||||
__ Branch(&done, eq, scratch1, Operand(zero_reg));
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
@ -2000,6 +2009,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -1948,6 +1948,15 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is enabled.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ li(at, Operand(is_tail_call_elimination_enabled));
|
||||
__ lb(scratch1, MemOperand(at));
|
||||
__ Branch(&done, eq, scratch1, Operand(zero_reg));
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
@ -1990,6 +1999,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -1987,6 +1987,16 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is enabled.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ mov(scratch1, Operand(is_tail_call_elimination_enabled));
|
||||
__ lbz(scratch1, MemOperand(scratch1));
|
||||
__ cmpi(scratch1, Operand::Zero());
|
||||
__ beq(&done);
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
@ -2034,6 +2044,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -1949,6 +1949,16 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is active.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ mov(scratch1, Operand(is_tail_call_elimination_enabled));
|
||||
__ LoadlB(scratch1, MemOperand(scratch1));
|
||||
__ CmpP(scratch1, Operand::Zero());
|
||||
__ beq(&done);
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
@ -1995,6 +2005,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -2052,6 +2052,15 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is active.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ Move(kScratchRegister, is_tail_call_elimination_enabled);
|
||||
__ cmpb(Operand(kScratchRegister, 0), Immediate(0));
|
||||
__ j(equal, &done);
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
@ -2091,6 +2100,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3, ReturnAddressState::kOnStack);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -1912,6 +1912,16 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is enabled.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ movzx_b(scratch1,
|
||||
Operand::StaticVariable(is_tail_call_elimination_enabled));
|
||||
__ cmp(scratch1, Immediate(0));
|
||||
__ j(equal, &done, Label::kNear);
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
@ -1952,6 +1962,7 @@ void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3, ReturnAddressState::kOnStack, 0);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user