summaryrefslogtreecommitdiff
path: root/chromium/v8
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8')
-rw-r--r--chromium/v8/include/v8-version.h2
-rw-r--r--chromium/v8/src/crankshaft/arm/lithium-arm.cc37
-rw-r--r--chromium/v8/src/crankshaft/arm64/lithium-arm64.cc37
-rw-r--r--chromium/v8/src/crankshaft/hydrogen-instructions.cc6
-rw-r--r--chromium/v8/src/crankshaft/ia32/lithium-ia32.cc37
-rw-r--r--chromium/v8/src/crankshaft/lithium.cc52
-rw-r--r--chromium/v8/src/crankshaft/lithium.h5
-rw-r--r--chromium/v8/src/crankshaft/mips/lithium-mips.cc37
-rw-r--r--chromium/v8/src/crankshaft/mips64/lithium-mips64.cc37
-rw-r--r--chromium/v8/src/crankshaft/ppc/lithium-ppc.cc37
-rw-r--r--chromium/v8/src/crankshaft/s390/lithium-s390.cc37
-rw-r--r--chromium/v8/src/crankshaft/x64/lithium-x64.cc37
-rw-r--r--chromium/v8/src/crankshaft/x87/lithium-x87.cc37
-rw-r--r--chromium/v8/src/deoptimizer.cc117
-rw-r--r--chromium/v8/src/heap/incremental-marking.cc5
15 files changed, 187 insertions, 333 deletions
diff --git a/chromium/v8/include/v8-version.h b/chromium/v8/include/v8-version.h
index a4ab92702ea..14102e3a163 100644
--- a/chromium/v8/include/v8-version.h
+++ b/chromium/v8/include/v8-version.h
@@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 5
#define V8_MINOR_VERSION 1
#define V8_BUILD_NUMBER 281
-#define V8_PATCH_LEVEL 30
+#define V8_PATCH_LEVEL 33
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/chromium/v8/src/crankshaft/arm/lithium-arm.cc b/chromium/v8/src/crankshaft/arm/lithium-arm.cc
index 456ef6b04d0..4072982513b 100644
--- a/chromium/v8/src/crankshaft/arm/lithium-arm.cc
+++ b/chromium/v8/src/crankshaft/arm/lithium-arm.cc
@@ -871,42 +871,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
}
chunk_->AddInstruction(instr, current_block_);
- if (instr->IsCall()) {
- 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) {
- // Push return value on top of outer environment.
- 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_);
- }
+ CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
}
diff --git a/chromium/v8/src/crankshaft/arm64/lithium-arm64.cc b/chromium/v8/src/crankshaft/arm64/lithium-arm64.cc
index 85ce459f8d8..6cfc8465482 100644
--- a/chromium/v8/src/crankshaft/arm64/lithium-arm64.cc
+++ b/chromium/v8/src/crankshaft/arm64/lithium-arm64.cc
@@ -714,42 +714,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
}
chunk_->AddInstruction(instr, current_block_);
- if (instr->IsCall()) {
- 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) {
- // Push return value on top of outer environment.
- 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_);
- }
+ CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
}
diff --git a/chromium/v8/src/crankshaft/hydrogen-instructions.cc b/chromium/v8/src/crankshaft/hydrogen-instructions.cc
index 3d48d8fb718..7de8b5d4a29 100644
--- a/chromium/v8/src/crankshaft/hydrogen-instructions.cc
+++ b/chromium/v8/src/crankshaft/hydrogen-instructions.cc
@@ -2127,7 +2127,11 @@ void HEnterInlined::RegisterReturnTarget(HBasicBlock* return_target,
std::ostream& HEnterInlined::PrintDataTo(std::ostream& os) const { // NOLINT
- return os << function()->debug_name()->ToCString().get();
+ os << function()->debug_name()->ToCString().get();
+ if (syntactic_tail_call_mode() == TailCallMode::kAllow) {
+ os << ", JSTailCall";
+ }
+ return os;
}
diff --git a/chromium/v8/src/crankshaft/ia32/lithium-ia32.cc b/chromium/v8/src/crankshaft/ia32/lithium-ia32.cc
index 8a873167097..4afeef5d682 100644
--- a/chromium/v8/src/crankshaft/ia32/lithium-ia32.cc
+++ b/chromium/v8/src/crankshaft/ia32/lithium-ia32.cc
@@ -904,42 +904,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
}
chunk_->AddInstruction(instr, current_block_);
- if (instr->IsCall()) {
- 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) {
- // Push return value on top of outer environment.
- 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_);
- }
+ CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
}
diff --git a/chromium/v8/src/crankshaft/lithium.cc b/chromium/v8/src/crankshaft/lithium.cc
index 3dff459a54a..d34b04f5da0 100644
--- a/chromium/v8/src/crankshaft/lithium.cc
+++ b/chromium/v8/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;
diff --git a/chromium/v8/src/crankshaft/lithium.h b/chromium/v8/src/crankshaft/lithium.h
index 38e395ea16a..a2c028330b9 100644
--- a/chromium/v8/src/crankshaft/lithium.h
+++ b/chromium/v8/src/crankshaft/lithium.h
@@ -745,6 +745,11 @@ class LChunkBuilderBase BASE_EMBEDDED {
// Will not be moved to a register even if one is freely available.
virtual MUST_USE_RESULT LOperand* UseAny(HValue* value) = 0;
+ // Constructs proper environment for a lazy bailout point after call, creates
+ // LLazyBailout instruction and adds it to current block.
+ void CreateLazyBailoutForCall(HBasicBlock* current_block, LInstruction* instr,
+ HInstruction* hydrogen_val);
+
// Assigns given environment to an instruction. An instruction which can
// deoptimize must have an environment.
LInstruction* AssignEnvironment(LInstruction* instr,
diff --git a/chromium/v8/src/crankshaft/mips/lithium-mips.cc b/chromium/v8/src/crankshaft/mips/lithium-mips.cc
index 8350e13740e..71c34df516c 100644
--- a/chromium/v8/src/crankshaft/mips/lithium-mips.cc
+++ b/chromium/v8/src/crankshaft/mips/lithium-mips.cc
@@ -881,42 +881,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
}
chunk_->AddInstruction(instr, current_block_);
- if (instr->IsCall()) {
- 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) {
- // Push return value on top of outer environment.
- 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_);
- }
+ CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
}
diff --git a/chromium/v8/src/crankshaft/mips64/lithium-mips64.cc b/chromium/v8/src/crankshaft/mips64/lithium-mips64.cc
index 5c1ab618bd2..bcfbc249d22 100644
--- a/chromium/v8/src/crankshaft/mips64/lithium-mips64.cc
+++ b/chromium/v8/src/crankshaft/mips64/lithium-mips64.cc
@@ -881,42 +881,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
}
chunk_->AddInstruction(instr, current_block_);
- if (instr->IsCall()) {
- 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) {
- // Push return value on top of outer environment.
- 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_);
- }
+ CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
}
diff --git a/chromium/v8/src/crankshaft/ppc/lithium-ppc.cc b/chromium/v8/src/crankshaft/ppc/lithium-ppc.cc
index fad5b4bf435..b7397869bbc 100644
--- a/chromium/v8/src/crankshaft/ppc/lithium-ppc.cc
+++ b/chromium/v8/src/crankshaft/ppc/lithium-ppc.cc
@@ -886,42 +886,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
}
chunk_->AddInstruction(instr, current_block_);
- if (instr->IsCall()) {
- 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) {
- // Push return value on top of outer environment.
- 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_);
- }
+ CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
}
diff --git a/chromium/v8/src/crankshaft/s390/lithium-s390.cc b/chromium/v8/src/crankshaft/s390/lithium-s390.cc
index ab2ed8f774f..a18f8771875 100644
--- a/chromium/v8/src/crankshaft/s390/lithium-s390.cc
+++ b/chromium/v8/src/crankshaft/s390/lithium-s390.cc
@@ -810,42 +810,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
}
chunk_->AddInstruction(instr, current_block_);
- if (instr->IsCall()) {
- 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) {
- // Push return value on top of outer environment.
- 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_);
- }
+ CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
}
LInstruction* LChunkBuilder::DoPrologue(HPrologue* instr) {
diff --git a/chromium/v8/src/crankshaft/x64/lithium-x64.cc b/chromium/v8/src/crankshaft/x64/lithium-x64.cc
index 5e2e9fa4cd4..e86b90c8382 100644
--- a/chromium/v8/src/crankshaft/x64/lithium-x64.cc
+++ b/chromium/v8/src/crankshaft/x64/lithium-x64.cc
@@ -896,42 +896,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
}
chunk_->AddInstruction(instr, current_block_);
- if (instr->IsCall()) {
- 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) {
- // Push return value on top of outer environment.
- 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_);
- }
+ CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
}
diff --git a/chromium/v8/src/crankshaft/x87/lithium-x87.cc b/chromium/v8/src/crankshaft/x87/lithium-x87.cc
index 51d9cd697b1..163d2c9cfba 100644
--- a/chromium/v8/src/crankshaft/x87/lithium-x87.cc
+++ b/chromium/v8/src/crankshaft/x87/lithium-x87.cc
@@ -919,42 +919,7 @@ void LChunkBuilder::AddInstruction(LInstruction* instr,
}
chunk_->AddInstruction(instr, current_block_);
- if (instr->IsCall()) {
- 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) {
- // Push return value on top of outer environment.
- 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_);
- }
+ CreateLazyBailoutForCall(current_block_, instr, hydrogen_val);
}
diff --git a/chromium/v8/src/deoptimizer.cc b/chromium/v8/src/deoptimizer.cc
index 639c48e31d6..b2c5d42df42 100644
--- a/chromium/v8/src/deoptimizer.cc
+++ b/chromium/v8/src/deoptimizer.cc
@@ -966,7 +966,6 @@ void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame,
// For the bottommost output frame the context can be gotten from the input
// frame. For all subsequent output frames it can be gotten from the function
// so long as we don't inline functions that need local contexts.
- Register context_reg = JavaScriptFrame::context_register();
output_offset -= kPointerSize;
TranslatedFrame::iterator context_pos = value_iterator;
@@ -991,7 +990,10 @@ void Deoptimizer::DoComputeJSFrame(TranslatedFrame* translated_frame,
}
value = reinterpret_cast<intptr_t>(context);
output_frame->SetContext(value);
- if (is_topmost) output_frame->SetRegister(context_reg.code(), value);
+ if (is_topmost) {
+ Register context_reg = JavaScriptFrame::context_register();
+ output_frame->SetRegister(context_reg.code(), value);
+ }
WriteValueToOutput(context, context_input_index, frame_index, output_offset,
"context ");
if (context == isolate_->heap()->arguments_marker()) {
@@ -1491,12 +1493,27 @@ void Deoptimizer::DoComputeTailCallerFrame(TranslatedFrame* translated_frame,
void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
int frame_index) {
TranslatedFrame::iterator value_iterator = translated_frame->begin();
+ bool is_topmost = (output_count_ - 1 == frame_index);
+ // The construct frame could become topmost only if we inlined a constructor
+ // call which does a tail call (otherwise the tail callee's frame would be
+ // the topmost one). So it could only be the LAZY case.
+ CHECK(!is_topmost || bailout_type_ == LAZY);
int input_index = 0;
Builtins* builtins = isolate_->builtins();
Code* construct_stub = builtins->builtin(Builtins::kJSConstructStubGeneric);
unsigned height = translated_frame->height();
unsigned height_in_bytes = height * kPointerSize;
+
+ // If the construct frame appears to be topmost we should ensure that the
+ // value of result register is preserved during continuation execution.
+ // We do this here by "pushing" the result of the constructor function to the
+ // top of the reconstructed stack and then using the
+ // FullCodeGenerator::TOS_REG machinery.
+ if (is_topmost) {
+ height_in_bytes += kPointerSize;
+ }
+
// Skip function.
value_iterator++;
input_index++;
@@ -1513,8 +1530,8 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
new (output_frame_size) FrameDescription(output_frame_size);
output_frame->SetFrameType(StackFrame::CONSTRUCT);
- // Construct stub can not be topmost or bottommost.
- DCHECK(frame_index > 0 && frame_index < output_count_ - 1);
+ // Construct stub can not be topmost.
+ DCHECK(frame_index > 0 && frame_index < output_count_);
DCHECK(output_[frame_index] == NULL);
output_[frame_index] = output_frame;
@@ -1549,6 +1566,10 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
output_frame->SetCallerFp(output_offset, value);
intptr_t fp_value = top_address + output_offset;
output_frame->SetFp(fp_value);
+ if (is_topmost) {
+ Register fp_reg = JavaScriptFrame::fp_register();
+ output_frame->SetRegister(fp_reg.code(), fp_value);
+ }
DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
if (FLAG_enable_embedded_constant_pool) {
@@ -1571,6 +1592,10 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
output_offset -= kPointerSize;
value = output_[frame_index - 1]->GetContext();
output_frame->SetFrameSlot(output_offset, value);
+ if (is_topmost) {
+ Register context_reg = JavaScriptFrame::context_register();
+ output_frame->SetRegister(context_reg.code(), value);
+ }
DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
// The allocation site.
@@ -1596,6 +1621,18 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
DebugPrintOutputSlot(value, frame_index, output_offset,
"allocated receiver\n");
+ if (is_topmost) {
+ // Ensure the result is restored back when we return to the stub.
+ output_offset -= kPointerSize;
+ Register result_reg = FullCodeGenerator::result_register();
+ value = input_->GetRegister(result_reg.code());
+ output_frame->SetFrameSlot(output_offset, value);
+ DebugPrintOutputSlot(value, frame_index, output_offset,
+ "constructor result\n");
+
+ output_frame->SetState(Smi::FromInt(FullCodeGenerator::TOS_REG));
+ }
+
CHECK_EQ(0u, output_offset);
intptr_t pc = reinterpret_cast<intptr_t>(
@@ -1606,6 +1643,20 @@ void Deoptimizer::DoComputeConstructStubFrame(TranslatedFrame* translated_frame,
intptr_t constant_pool_value =
reinterpret_cast<intptr_t>(construct_stub->constant_pool());
output_frame->SetConstantPool(constant_pool_value);
+ if (is_topmost) {
+ Register constant_pool_reg =
+ JavaScriptFrame::constant_pool_pointer_register();
+ output_frame->SetRegister(constant_pool_reg.code(), fp_value);
+ }
+ }
+
+ // Set the continuation for the topmost frame.
+ if (is_topmost) {
+ Builtins* builtins = isolate_->builtins();
+ DCHECK_EQ(LAZY, bailout_type_);
+ Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
+ output_frame->SetContinuation(
+ reinterpret_cast<intptr_t>(continuation->entry()));
}
}
@@ -1613,6 +1664,11 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
int frame_index,
bool is_setter_stub_frame) {
TranslatedFrame::iterator value_iterator = translated_frame->begin();
+ bool is_topmost = (output_count_ - 1 == frame_index);
+ // The accessor frame could become topmost only if we inlined an accessor
+ // call which does a tail call (otherwise the tail callee's frame would be
+ // the topmost one). So it could only be the LAZY case.
+ CHECK(!is_topmost || bailout_type_ == LAZY);
int input_index = 0;
// Skip accessor.
@@ -1623,6 +1679,19 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
// frame. This means that we have to use a height of 0.
unsigned height = 0;
unsigned height_in_bytes = height * kPointerSize;
+
+ // If the accessor frame appears to be topmost we should ensure that the
+ // value of result register is preserved during continuation execution.
+ // We do this here by "pushing" the result of the accessor function to the
+ // top of the reconstructed stack and then using the
+ // FullCodeGenerator::TOS_REG machinery.
+ // We don't need to restore the result in case of a setter call because we
+ // have to return the stored value but not the result of the setter function.
+ bool should_preserve_result = is_topmost && !is_setter_stub_frame;
+ if (should_preserve_result) {
+ height_in_bytes += kPointerSize;
+ }
+
const char* kind = is_setter_stub_frame ? "setter" : "getter";
if (trace_scope_ != NULL) {
PrintF(trace_scope_->file(),
@@ -1645,8 +1714,8 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
new (output_frame_size) FrameDescription(output_frame_size);
output_frame->SetFrameType(StackFrame::INTERNAL);
- // A frame for an accessor stub can not be the topmost or bottommost one.
- CHECK(frame_index > 0 && frame_index < output_count_ - 1);
+ // A frame for an accessor stub can not be bottommost.
+ CHECK(frame_index > 0 && frame_index < output_count_);
CHECK_NULL(output_[frame_index]);
output_[frame_index] = output_frame;
@@ -1669,6 +1738,10 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
output_frame->SetCallerFp(output_offset, value);
intptr_t fp_value = top_address + output_offset;
output_frame->SetFp(fp_value);
+ if (is_topmost) {
+ Register fp_reg = JavaScriptFrame::fp_register();
+ output_frame->SetRegister(fp_reg.code(), fp_value);
+ }
DebugPrintOutputSlot(value, frame_index, output_offset, "caller's fp\n");
if (FLAG_enable_embedded_constant_pool) {
@@ -1703,6 +1776,10 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
output_offset -= kPointerSize;
value = output_[frame_index - 1]->GetContext();
output_frame->SetFrameSlot(output_offset, value);
+ if (is_topmost) {
+ Register context_reg = JavaScriptFrame::context_register();
+ output_frame->SetRegister(context_reg.code(), value);
+ }
DebugPrintOutputSlot(value, frame_index, output_offset, "context\n");
// Skip receiver.
@@ -1717,6 +1794,20 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
output_offset);
}
+ if (should_preserve_result) {
+ // Ensure the result is restored back when we return to the stub.
+ output_offset -= kPointerSize;
+ Register result_reg = FullCodeGenerator::result_register();
+ value = input_->GetRegister(result_reg.code());
+ output_frame->SetFrameSlot(output_offset, value);
+ DebugPrintOutputSlot(value, frame_index, output_offset,
+ "accessor result\n");
+
+ output_frame->SetState(Smi::FromInt(FullCodeGenerator::TOS_REG));
+ } else {
+ output_frame->SetState(Smi::FromInt(FullCodeGenerator::NO_REGISTERS));
+ }
+
CHECK_EQ(0u, output_offset);
Smi* offset = is_setter_stub_frame ?
@@ -1729,6 +1820,20 @@ void Deoptimizer::DoComputeAccessorStubFrame(TranslatedFrame* translated_frame,
intptr_t constant_pool_value =
reinterpret_cast<intptr_t>(accessor_stub->constant_pool());
output_frame->SetConstantPool(constant_pool_value);
+ if (is_topmost) {
+ Register constant_pool_reg =
+ JavaScriptFrame::constant_pool_pointer_register();
+ output_frame->SetRegister(constant_pool_reg.code(), fp_value);
+ }
+ }
+
+ // Set the continuation for the topmost frame.
+ if (is_topmost) {
+ Builtins* builtins = isolate_->builtins();
+ DCHECK_EQ(LAZY, bailout_type_);
+ Code* continuation = builtins->builtin(Builtins::kNotifyLazyDeoptimized);
+ output_frame->SetContinuation(
+ reinterpret_cast<intptr_t>(continuation->entry()));
}
}
diff --git a/chromium/v8/src/heap/incremental-marking.cc b/chromium/v8/src/heap/incremental-marking.cc
index 3636dce606e..c82fc83ff7f 100644
--- a/chromium/v8/src/heap/incremental-marking.cc
+++ b/chromium/v8/src/heap/incremental-marking.cc
@@ -277,6 +277,11 @@ class IncrementalMarkingMarkingVisitor
void IncrementalMarking::IterateBlackObject(HeapObject* object) {
if (IsMarking() && Marking::IsBlack(Marking::MarkBitFrom(object))) {
+ Page* page = Page::FromAddress(object->address());
+ if ((page->owner() != nullptr) && (page->owner()->identity() == LO_SPACE)) {
+ // IterateBlackObject requires us to visit the hole object.
+ page->ResetProgressBar();
+ }
IncrementalMarkingMarkingVisitor::IterateBody(object->map(), object);
}
}