Commit cd99bada authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[turbofan] Add support to deoptimizer for setting no speculation bit

This CL adds support to the deoptimizer for setting the no speculation
bit on a provided feedback vector if desired.

Bug: v8:7127
Change-Id: I31fd1ea306cf5a4e919faeb896a83c1afdfccd63
Reviewed-on: https://chromium-review.googlesource.com/819370
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50064}
parent a52b4cdf
...@@ -915,9 +915,17 @@ int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset, ...@@ -915,9 +915,17 @@ int CodeGenerator::BuildTranslation(Instruction* instr, int pc_offset,
FrameStateDescriptor* const descriptor = entry.descriptor(); FrameStateDescriptor* const descriptor = entry.descriptor();
frame_state_offset++; frame_state_offset++;
Translation translation( int update_feedback_count = entry.feedback().IsValid() ? 1 : 0;
&translations_, static_cast<int>(descriptor->GetFrameCount()), Translation translation(&translations_,
static_cast<int>(descriptor->GetJSFrameCount()), zone()); static_cast<int>(descriptor->GetFrameCount()),
static_cast<int>(descriptor->GetJSFrameCount()),
update_feedback_count, zone());
if (entry.feedback().IsValid()) {
DeoptimizationLiteral literal =
DeoptimizationLiteral(entry.feedback().vector());
int literal_id = DefineDeoptimizationLiteral(literal);
translation.AddUpdateFeedback(literal_id, entry.feedback().slot().ToInt());
}
InstructionOperandIterator iter(instr, frame_state_offset); InstructionOperandIterator iter(instr, frame_state_offset);
BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation, BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation,
state_combine); state_combine);
......
...@@ -1677,6 +1677,8 @@ void Deoptimizer::MaterializeHeapObjects() { ...@@ -1677,6 +1677,8 @@ void Deoptimizer::MaterializeHeapObjects() {
translated_state_.VerifyMaterializedObjects(); translated_state_.VerifyMaterializedObjects();
translated_state_.DoUpdateFeedback();
isolate_->materialized_object_store()->Remove( isolate_->materialized_object_store()->Remove(
reinterpret_cast<Address>(stack_fp_)); reinterpret_cast<Address>(stack_fp_));
} }
...@@ -2015,6 +2017,11 @@ void Translation::StoreLiteral(int literal_id) { ...@@ -2015,6 +2017,11 @@ void Translation::StoreLiteral(int literal_id) {
buffer_->Add(literal_id); buffer_->Add(literal_id);
} }
void Translation::AddUpdateFeedback(int vector_literal, int slot) {
buffer_->Add(UPDATE_FEEDBACK);
buffer_->Add(vector_literal);
buffer_->Add(slot);
}
void Translation::StoreJSFrameFunction() { void Translation::StoreJSFrameFunction() {
StoreStackSlot((StandardFrameConstants::kCallerPCOffset - StoreStackSlot((StandardFrameConstants::kCallerPCOffset -
...@@ -2042,9 +2049,10 @@ int Translation::NumberOfOperandsFor(Opcode opcode) { ...@@ -2042,9 +2049,10 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
case DOUBLE_STACK_SLOT: case DOUBLE_STACK_SLOT:
case LITERAL: case LITERAL:
return 1; return 1;
case BEGIN:
case ARGUMENTS_ADAPTOR_FRAME: case ARGUMENTS_ADAPTOR_FRAME:
case UPDATE_FEEDBACK:
return 2; return 2;
case BEGIN:
case INTERPRETED_FRAME: case INTERPRETED_FRAME:
case CONSTRUCT_STUB_FRAME: case CONSTRUCT_STUB_FRAME:
case BUILTIN_CONTINUATION_FRAME: case BUILTIN_CONTINUATION_FRAME:
...@@ -2747,7 +2755,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame( ...@@ -2747,7 +2755,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
return TranslatedFrame::JavaScriptBuiltinContinuationFrame( return TranslatedFrame::JavaScriptBuiltinContinuationFrame(
bailout_id, shared_info, height_with_context); bailout_id, shared_info, height_with_context);
} }
case Translation::UPDATE_FEEDBACK:
case Translation::BEGIN: case Translation::BEGIN:
case Translation::DUPLICATED_OBJECT: case Translation::DUPLICATED_OBJECT:
case Translation::ARGUMENTS_ELEMENTS: case Translation::ARGUMENTS_ELEMENTS:
...@@ -2895,6 +2903,7 @@ int TranslatedState::CreateNextTranslatedValue( ...@@ -2895,6 +2903,7 @@ int TranslatedState::CreateNextTranslatedValue(
case Translation::CONSTRUCT_STUB_FRAME: case Translation::CONSTRUCT_STUB_FRAME:
case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME: case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME:
case Translation::BUILTIN_CONTINUATION_FRAME: case Translation::BUILTIN_CONTINUATION_FRAME:
case Translation::UPDATE_FEEDBACK:
// Peeled off before getting here. // Peeled off before getting here.
break; break;
...@@ -3157,8 +3166,7 @@ int TranslatedState::CreateNextTranslatedValue( ...@@ -3157,8 +3166,7 @@ int TranslatedState::CreateNextTranslatedValue(
FATAL("We should never get here - unexpected deopt info."); FATAL("We should never get here - unexpected deopt info.");
} }
TranslatedState::TranslatedState(const JavaScriptFrame* frame) TranslatedState::TranslatedState(const JavaScriptFrame* frame) {
: isolate_(nullptr), stack_frame_pointer_(nullptr) {
int deopt_index = Safepoint::kNoDeoptimizationIndex; int deopt_index = Safepoint::kNoDeoptimizationIndex;
DeoptimizationData* data = DeoptimizationData* data =
static_cast<const OptimizedFrame*>(frame)->GetDeoptimizationData( static_cast<const OptimizedFrame*>(frame)->GetDeoptimizationData(
...@@ -3171,9 +3179,6 @@ TranslatedState::TranslatedState(const JavaScriptFrame* frame) ...@@ -3171,9 +3179,6 @@ TranslatedState::TranslatedState(const JavaScriptFrame* frame)
frame->function()->shared()->internal_formal_parameter_count()); frame->function()->shared()->internal_formal_parameter_count());
} }
TranslatedState::TranslatedState()
: isolate_(nullptr), stack_frame_pointer_(nullptr) {}
void TranslatedState::Init(Address input_frame_pointer, void TranslatedState::Init(Address input_frame_pointer,
TranslationIterator* iterator, TranslationIterator* iterator,
FixedArray* literal_array, RegisterValues* registers, FixedArray* literal_array, RegisterValues* registers,
...@@ -3189,9 +3194,15 @@ void TranslatedState::Init(Address input_frame_pointer, ...@@ -3189,9 +3194,15 @@ void TranslatedState::Init(Address input_frame_pointer,
CHECK(opcode == Translation::BEGIN); CHECK(opcode == Translation::BEGIN);
int count = iterator->Next(); int count = iterator->Next();
frames_.reserve(count);
iterator->Next(); // Drop JS frames count. iterator->Next(); // Drop JS frames count.
int update_feedback_count = iterator->Next();
CHECK_GE(update_feedback_count, 0);
CHECK_LE(update_feedback_count, 1);
frames_.reserve(count); if (update_feedback_count == 1) {
ReadUpdateFeedback(iterator, literal_array);
}
std::stack<int> nested_counts; std::stack<int> nested_counts;
...@@ -3249,6 +3260,11 @@ void TranslatedState::Init(Address input_frame_pointer, ...@@ -3249,6 +3260,11 @@ void TranslatedState::Init(Address input_frame_pointer,
void TranslatedState::Prepare(Address stack_frame_pointer) { void TranslatedState::Prepare(Address stack_frame_pointer) {
for (auto& frame : frames_) frame.Handlify(); for (auto& frame : frames_) frame.Handlify();
if (feedback_vector_ != nullptr) {
feedback_vector_handle_ =
Handle<FeedbackVector>(feedback_vector_, isolate());
feedback_vector_ = nullptr;
}
stack_frame_pointer_ = stack_frame_pointer; stack_frame_pointer_ = stack_frame_pointer;
UpdateFromPreviouslyMaterializedObjects(); UpdateFromPreviouslyMaterializedObjects();
...@@ -3836,6 +3852,21 @@ void TranslatedState::VerifyMaterializedObjects() { ...@@ -3836,6 +3852,21 @@ void TranslatedState::VerifyMaterializedObjects() {
#endif #endif
} }
void TranslatedState::DoUpdateFeedback() {
if (!feedback_vector_handle_.is_null()) {
CHECK(!feedback_slot_.IsInvalid());
CallICNexus nexus(feedback_vector_handle_, feedback_slot_);
nexus.SetSpeculationMode(SpeculationMode::kDisallowSpeculation);
}
}
void TranslatedState::ReadUpdateFeedback(TranslationIterator* iterator,
FixedArray* literal_array) {
CHECK_EQ(Translation::UPDATE_FEEDBACK, iterator->Next());
feedback_vector_ = FeedbackVector::cast(literal_array->get(iterator->Next()));
feedback_slot_ = FeedbackSlot(iterator->Next());
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -268,7 +268,7 @@ class TranslatedFrame { ...@@ -268,7 +268,7 @@ class TranslatedFrame {
class TranslatedState { class TranslatedState {
public: public:
TranslatedState(); TranslatedState() {}
explicit TranslatedState(const JavaScriptFrame* frame); explicit TranslatedState(const JavaScriptFrame* frame);
void Prepare(Address stack_frame_pointer); void Prepare(Address stack_frame_pointer);
...@@ -297,6 +297,7 @@ class TranslatedState { ...@@ -297,6 +297,7 @@ class TranslatedState {
FILE* trace_file, int parameter_count); FILE* trace_file, int parameter_count);
void VerifyMaterializedObjects(); void VerifyMaterializedObjects();
void DoUpdateFeedback();
private: private:
friend TranslatedValue; friend TranslatedValue;
...@@ -343,6 +344,9 @@ class TranslatedState { ...@@ -343,6 +344,9 @@ class TranslatedState {
TranslatedFrame* frame, int* value_index, TranslatedValue* slot, TranslatedFrame* frame, int* value_index, TranslatedValue* slot,
Handle<Map> map, const DisallowHeapAllocation& no_allocation); Handle<Map> map, const DisallowHeapAllocation& no_allocation);
void ReadUpdateFeedback(TranslationIterator* iterator,
FixedArray* literal_array);
TranslatedValue* ResolveCapturedObject(TranslatedValue* slot); TranslatedValue* ResolveCapturedObject(TranslatedValue* slot);
TranslatedValue* GetValueByObjectIndex(int object_index); TranslatedValue* GetValueByObjectIndex(int object_index);
Handle<Object> GetValueAndAdvance(TranslatedFrame* frame, int* value_index); Handle<Object> GetValueAndAdvance(TranslatedFrame* frame, int* value_index);
...@@ -352,8 +356,8 @@ class TranslatedState { ...@@ -352,8 +356,8 @@ class TranslatedState {
static Float64 GetDoubleSlot(Address fp, int slot_index); static Float64 GetDoubleSlot(Address fp, int slot_index);
std::vector<TranslatedFrame> frames_; std::vector<TranslatedFrame> frames_;
Isolate* isolate_; Isolate* isolate_ = nullptr;
Address stack_frame_pointer_; Address stack_frame_pointer_ = nullptr;
int formal_parameter_count_; int formal_parameter_count_;
struct ObjectPosition { struct ObjectPosition {
...@@ -361,6 +365,9 @@ class TranslatedState { ...@@ -361,6 +365,9 @@ class TranslatedState {
int value_index_; int value_index_;
}; };
std::deque<ObjectPosition> object_positions_; std::deque<ObjectPosition> object_positions_;
Handle<FeedbackVector> feedback_vector_handle_;
FeedbackVector* feedback_vector_ = nullptr;
FeedbackSlot feedback_slot_;
}; };
...@@ -879,7 +886,8 @@ class TranslationIterator BASE_EMBEDDED { ...@@ -879,7 +886,8 @@ class TranslationIterator BASE_EMBEDDED {
V(BOOL_STACK_SLOT) \ V(BOOL_STACK_SLOT) \
V(FLOAT_STACK_SLOT) \ V(FLOAT_STACK_SLOT) \
V(DOUBLE_STACK_SLOT) \ V(DOUBLE_STACK_SLOT) \
V(LITERAL) V(LITERAL) \
V(UPDATE_FEEDBACK)
class Translation BASE_EMBEDDED { class Translation BASE_EMBEDDED {
public: public:
...@@ -891,13 +899,12 @@ class Translation BASE_EMBEDDED { ...@@ -891,13 +899,12 @@ class Translation BASE_EMBEDDED {
#undef DECLARE_TRANSLATION_OPCODE_ENUM #undef DECLARE_TRANSLATION_OPCODE_ENUM
Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count, Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count,
Zone* zone) int update_feedback_count, Zone* zone)
: buffer_(buffer), : buffer_(buffer), index_(buffer->CurrentIndex()), zone_(zone) {
index_(buffer->CurrentIndex()),
zone_(zone) {
buffer_->Add(BEGIN); buffer_->Add(BEGIN);
buffer_->Add(frame_count); buffer_->Add(frame_count);
buffer_->Add(jsframe_count); buffer_->Add(jsframe_count);
buffer_->Add(update_feedback_count);
} }
int index() const { return index_; } int index() const { return index_; }
...@@ -915,6 +922,7 @@ class Translation BASE_EMBEDDED { ...@@ -915,6 +922,7 @@ class Translation BASE_EMBEDDED {
void ArgumentsElements(CreateArgumentsType type); void ArgumentsElements(CreateArgumentsType type);
void ArgumentsLength(CreateArgumentsType type); void ArgumentsLength(CreateArgumentsType type);
void BeginCapturedObject(int length); void BeginCapturedObject(int length);
void AddUpdateFeedback(int vector_literal, int slot);
void DuplicateObject(int object_index); void DuplicateObject(int object_index);
void StoreRegister(Register reg); void StoreRegister(Register reg);
void StoreInt32Register(Register reg); void StoreInt32Register(Register reg);
......
...@@ -1536,6 +1536,7 @@ void OptimizedFrame::GetFunctions( ...@@ -1536,6 +1536,7 @@ void OptimizedFrame::GetFunctions(
DCHECK_EQ(Translation::BEGIN, opcode); DCHECK_EQ(Translation::BEGIN, opcode);
it.Next(); // Skip frame count. it.Next(); // Skip frame count.
int jsframe_count = it.Next(); int jsframe_count = it.Next();
it.Next(); // Skip update feedback count.
// We insert the frames in reverse order because the frames // We insert the frames in reverse order because the frames
// in the deoptimization translation are ordered bottom-to-top. // in the deoptimization translation are ordered bottom-to-top.
......
...@@ -14235,9 +14235,11 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT ...@@ -14235,9 +14235,11 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT
DCHECK(Translation::BEGIN == opcode); DCHECK(Translation::BEGIN == opcode);
int frame_count = iterator.Next(); int frame_count = iterator.Next();
int jsframe_count = iterator.Next(); int jsframe_count = iterator.Next();
int update_feedback_count = iterator.Next();
os << " " << Translation::StringFor(opcode) os << " " << Translation::StringFor(opcode)
<< " {frame count=" << frame_count << " {frame count=" << frame_count
<< ", js frame count=" << jsframe_count << "}\n"; << ", js frame count=" << jsframe_count
<< ", update_feedback_count=" << update_feedback_count << "}\n";
while (iterator.HasNext() && while (iterator.HasNext() &&
Translation::BEGIN != Translation::BEGIN !=
...@@ -14394,6 +14396,14 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT ...@@ -14394,6 +14396,14 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT
os << "{length=" << args_length << "}"; os << "{length=" << args_length << "}";
break; break;
} }
case Translation::UPDATE_FEEDBACK: {
int literal_index = iterator.Next();
FeedbackSlot slot(iterator.Next());
os << "{feedback={vector_index=" << literal_index << ", slot=" << slot
<< "}}";
break;
}
} }
os << "\n"; os << "\n";
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment