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,
FrameStateDescriptor* const descriptor = entry.descriptor();
frame_state_offset++;
Translation translation(
&translations_, static_cast<int>(descriptor->GetFrameCount()),
static_cast<int>(descriptor->GetJSFrameCount()), zone());
int update_feedback_count = entry.feedback().IsValid() ? 1 : 0;
Translation translation(&translations_,
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);
BuildTranslationForFrameStateDescriptor(descriptor, &iter, &translation,
state_combine);
......
......@@ -1677,6 +1677,8 @@ void Deoptimizer::MaterializeHeapObjects() {
translated_state_.VerifyMaterializedObjects();
translated_state_.DoUpdateFeedback();
isolate_->materialized_object_store()->Remove(
reinterpret_cast<Address>(stack_fp_));
}
......@@ -2015,6 +2017,11 @@ void Translation::StoreLiteral(int 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() {
StoreStackSlot((StandardFrameConstants::kCallerPCOffset -
......@@ -2042,9 +2049,10 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
case DOUBLE_STACK_SLOT:
case LITERAL:
return 1;
case BEGIN:
case ARGUMENTS_ADAPTOR_FRAME:
case UPDATE_FEEDBACK:
return 2;
case BEGIN:
case INTERPRETED_FRAME:
case CONSTRUCT_STUB_FRAME:
case BUILTIN_CONTINUATION_FRAME:
......@@ -2747,7 +2755,7 @@ TranslatedFrame TranslatedState::CreateNextTranslatedFrame(
return TranslatedFrame::JavaScriptBuiltinContinuationFrame(
bailout_id, shared_info, height_with_context);
}
case Translation::UPDATE_FEEDBACK:
case Translation::BEGIN:
case Translation::DUPLICATED_OBJECT:
case Translation::ARGUMENTS_ELEMENTS:
......@@ -2895,6 +2903,7 @@ int TranslatedState::CreateNextTranslatedValue(
case Translation::CONSTRUCT_STUB_FRAME:
case Translation::JAVA_SCRIPT_BUILTIN_CONTINUATION_FRAME:
case Translation::BUILTIN_CONTINUATION_FRAME:
case Translation::UPDATE_FEEDBACK:
// Peeled off before getting here.
break;
......@@ -3157,8 +3166,7 @@ int TranslatedState::CreateNextTranslatedValue(
FATAL("We should never get here - unexpected deopt info.");
}
TranslatedState::TranslatedState(const JavaScriptFrame* frame)
: isolate_(nullptr), stack_frame_pointer_(nullptr) {
TranslatedState::TranslatedState(const JavaScriptFrame* frame) {
int deopt_index = Safepoint::kNoDeoptimizationIndex;
DeoptimizationData* data =
static_cast<const OptimizedFrame*>(frame)->GetDeoptimizationData(
......@@ -3171,9 +3179,6 @@ TranslatedState::TranslatedState(const JavaScriptFrame* frame)
frame->function()->shared()->internal_formal_parameter_count());
}
TranslatedState::TranslatedState()
: isolate_(nullptr), stack_frame_pointer_(nullptr) {}
void TranslatedState::Init(Address input_frame_pointer,
TranslationIterator* iterator,
FixedArray* literal_array, RegisterValues* registers,
......@@ -3189,9 +3194,15 @@ void TranslatedState::Init(Address input_frame_pointer,
CHECK(opcode == Translation::BEGIN);
int count = iterator->Next();
frames_.reserve(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;
......@@ -3249,6 +3260,11 @@ void TranslatedState::Init(Address input_frame_pointer,
void TranslatedState::Prepare(Address stack_frame_pointer) {
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;
UpdateFromPreviouslyMaterializedObjects();
......@@ -3836,6 +3852,21 @@ void TranslatedState::VerifyMaterializedObjects() {
#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 v8
......
......@@ -268,7 +268,7 @@ class TranslatedFrame {
class TranslatedState {
public:
TranslatedState();
TranslatedState() {}
explicit TranslatedState(const JavaScriptFrame* frame);
void Prepare(Address stack_frame_pointer);
......@@ -297,6 +297,7 @@ class TranslatedState {
FILE* trace_file, int parameter_count);
void VerifyMaterializedObjects();
void DoUpdateFeedback();
private:
friend TranslatedValue;
......@@ -343,6 +344,9 @@ class TranslatedState {
TranslatedFrame* frame, int* value_index, TranslatedValue* slot,
Handle<Map> map, const DisallowHeapAllocation& no_allocation);
void ReadUpdateFeedback(TranslationIterator* iterator,
FixedArray* literal_array);
TranslatedValue* ResolveCapturedObject(TranslatedValue* slot);
TranslatedValue* GetValueByObjectIndex(int object_index);
Handle<Object> GetValueAndAdvance(TranslatedFrame* frame, int* value_index);
......@@ -352,8 +356,8 @@ class TranslatedState {
static Float64 GetDoubleSlot(Address fp, int slot_index);
std::vector<TranslatedFrame> frames_;
Isolate* isolate_;
Address stack_frame_pointer_;
Isolate* isolate_ = nullptr;
Address stack_frame_pointer_ = nullptr;
int formal_parameter_count_;
struct ObjectPosition {
......@@ -361,6 +365,9 @@ class TranslatedState {
int value_index_;
};
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 {
V(BOOL_STACK_SLOT) \
V(FLOAT_STACK_SLOT) \
V(DOUBLE_STACK_SLOT) \
V(LITERAL)
V(LITERAL) \
V(UPDATE_FEEDBACK)
class Translation BASE_EMBEDDED {
public:
......@@ -891,13 +899,12 @@ class Translation BASE_EMBEDDED {
#undef DECLARE_TRANSLATION_OPCODE_ENUM
Translation(TranslationBuffer* buffer, int frame_count, int jsframe_count,
Zone* zone)
: buffer_(buffer),
index_(buffer->CurrentIndex()),
zone_(zone) {
int update_feedback_count, Zone* zone)
: buffer_(buffer), index_(buffer->CurrentIndex()), zone_(zone) {
buffer_->Add(BEGIN);
buffer_->Add(frame_count);
buffer_->Add(jsframe_count);
buffer_->Add(update_feedback_count);
}
int index() const { return index_; }
......@@ -915,6 +922,7 @@ class Translation BASE_EMBEDDED {
void ArgumentsElements(CreateArgumentsType type);
void ArgumentsLength(CreateArgumentsType type);
void BeginCapturedObject(int length);
void AddUpdateFeedback(int vector_literal, int slot);
void DuplicateObject(int object_index);
void StoreRegister(Register reg);
void StoreInt32Register(Register reg);
......
......@@ -1536,6 +1536,7 @@ void OptimizedFrame::GetFunctions(
DCHECK_EQ(Translation::BEGIN, opcode);
it.Next(); // Skip frame count.
int jsframe_count = it.Next();
it.Next(); // Skip update feedback count.
// We insert the frames in reverse order because the frames
// in the deoptimization translation are ordered bottom-to-top.
......
......@@ -14235,9 +14235,11 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT
DCHECK(Translation::BEGIN == opcode);
int frame_count = iterator.Next();
int jsframe_count = iterator.Next();
int update_feedback_count = iterator.Next();
os << " " << Translation::StringFor(opcode)
<< " {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() &&
Translation::BEGIN !=
......@@ -14394,6 +14396,14 @@ void DeoptimizationData::DeoptimizationDataPrint(std::ostream& os) { // NOLINT
os << "{length=" << args_length << "}";
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";
}
......
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