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

Unified Diff: src/crankshaft/lithium.cc

Issue 1936043002: [es6] Properly handle the case when an inlined getter/setter/constructor does a tail call. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Removed too much, fixing Created 4 years, 7 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/crankshaft/lithium.h ('k') | src/crankshaft/mips/lithium-mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/crankshaft/lithium.cc
diff --git a/src/crankshaft/lithium.cc b/src/crankshaft/lithium.cc
index 3dff459a54a695676091d66cc161d76b48c6b650..d34b04f5da022ccaa582777c14db0fbb18f051cd 100644
--- a/src/crankshaft/lithium.cc
+++ b/src/crankshaft/lithium.cc
@@ -338,7 +338,6 @@ void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
}
}
-
LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
return LConstantOperand::Create(constant->id(), zone());
}
@@ -508,6 +507,57 @@ void LChunkBuilderBase::Retry(BailoutReason reason) {
status_ = ABORTED;
}
+void LChunkBuilderBase::CreateLazyBailoutForCall(HBasicBlock* current_block,
+ LInstruction* instr,
+ HInstruction* hydrogen_val) {
+ if (!instr->IsCall()) return;
+
+ HEnvironment* hydrogen_env = current_block->last_environment();
+ HValue* hydrogen_value_for_lazy_bailout = hydrogen_val;
+ DCHECK_NOT_NULL(hydrogen_env);
+ if (instr->IsSyntacticTailCall()) {
+ // If it was a syntactic tail call we need to drop the current frame and
+ // all the frames on top of it that are either an arguments adaptor frame
+ // or a tail caller frame.
+ hydrogen_env = hydrogen_env->outer();
+ while (hydrogen_env != nullptr &&
+ (hydrogen_env->frame_type() == ARGUMENTS_ADAPTOR ||
+ hydrogen_env->frame_type() == TAIL_CALLER_FUNCTION)) {
+ hydrogen_env = hydrogen_env->outer();
+ }
+ if (hydrogen_env != nullptr) {
+ if (hydrogen_env->frame_type() == JS_FUNCTION) {
+ // In case an outer frame is a function frame we have to replay
+ // environment manually because
+ // 1) it does not contain a result of inlined function yet,
+ // 2) we can't find the proper simulate that corresponds to the point
+ // after inlined call to do a ReplayEnvironment() on.
+ // So we push return value on top of outer environment.
+ // As for JS_GETTER/JS_SETTER/JS_CONSTRUCT nothing has to be done here,
+ // the deoptimizer ensures that the result of the callee is correctly
+ // propagated to result register during deoptimization.
+ hydrogen_env = hydrogen_env->Copy();
+ hydrogen_env->Push(hydrogen_val);
+ }
+ } else {
+ // Although we don't need this lazy bailout for normal execution
+ // (because when we tail call from the outermost function we should pop
+ // its frame) we still need it when debugger is on.
+ hydrogen_env = current_block->last_environment();
+ }
+ } else {
+ if (hydrogen_val->HasObservableSideEffects()) {
+ HSimulate* sim = HSimulate::cast(hydrogen_val->next());
+ sim->ReplayEnvironment(hydrogen_env);
+ hydrogen_value_for_lazy_bailout = sim;
+ }
+ }
+ LInstruction* bailout = LChunkBuilderBase::AssignEnvironment(
+ new (zone()) LLazyBailout(), hydrogen_env);
+ bailout->set_hydrogen_value(hydrogen_value_for_lazy_bailout);
+ chunk_->AddInstruction(bailout, current_block);
+}
+
LInstruction* LChunkBuilderBase::AssignEnvironment(LInstruction* instr,
HEnvironment* hydrogen_env) {
int argument_index_accumulator = 0;
« no previous file with comments | « src/crankshaft/lithium.h ('k') | src/crankshaft/mips/lithium-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698