diff options
Diffstat (limited to 'chromium/v8')
-rw-r--r-- | chromium/v8/include/v8-version.h | 2 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/arm/lithium-arm.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/arm64/lithium-arm64.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/hydrogen-instructions.cc | 6 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/ia32/lithium-ia32.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/lithium.cc | 52 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/lithium.h | 5 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/mips/lithium-mips.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/mips64/lithium-mips64.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/ppc/lithium-ppc.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/s390/lithium-s390.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/x64/lithium-x64.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/crankshaft/x87/lithium-x87.cc | 37 | ||||
-rw-r--r-- | chromium/v8/src/deoptimizer.cc | 117 | ||||
-rw-r--r-- | chromium/v8/src/heap/incremental-marking.cc | 5 |
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); } } |