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

Unified Diff: src/compiler/frame-states.cc

Issue 1485183002: [turbofan] Deopt support for escape analysis (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@ea-local
Patch Set: Created 5 years 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
Index: src/compiler/frame-states.cc
diff --git a/src/compiler/frame-states.cc b/src/compiler/frame-states.cc
index b9ea010cccdb38e7caf98b337879db996d497e36..fb3740d06256b551fc383ca8df3dd6e4745fe204 100644
--- a/src/compiler/frame-states.cc
+++ b/src/compiler/frame-states.cc
@@ -2,8 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/base/functional.h"
#include "src/compiler/frame-states.h"
+
+#include "src/base/functional.h"
+#include "src/compiler/code-generator.h"
+#include "src/compiler/instruction-selector-impl.h"
+#include "src/compiler/node.h"
+#include "src/compiler/state-values-utils.h"
#include "src/handles-inl.h"
namespace v8 {
@@ -72,6 +77,225 @@ std::ostream& operator<<(std::ostream& os, FrameStateInfo const& info) {
return os;
}
+
+FrameStateDescriptor::FrameStateDescriptor(
+ Zone* zone, FrameStateType type, BailoutId bailout_id,
+ OutputFrameStateCombine state_combine, size_t parameters_count,
+ size_t locals_count, size_t stack_count,
+ MaybeHandle<SharedFunctionInfo> shared_info,
+ FrameStateDescriptor* outer_state)
+ : type_(type),
+ bailout_id_(bailout_id),
+ frame_state_combine_(state_combine),
+ parameters_count_(parameters_count),
+ locals_count_(locals_count),
+ stack_count_(stack_count),
+ values_(zone, kMachAnyTagged),
+ shared_info_(shared_info),
+ outer_state_(outer_state) {}
+
+
+size_t FrameStateDescriptor::GetSize(OutputFrameStateCombine combine) const {
+ size_t size = 1 + parameters_count() + locals_count() + stack_count() +
+ (HasContext() ? 1 : 0);
+ switch (combine.kind()) {
+ case OutputFrameStateCombine::kPushOutput:
+ size += combine.GetPushCount();
+ break;
+ case OutputFrameStateCombine::kPokeAt:
+ break;
+ }
+ return size;
+}
+
+
+size_t FrameStateDescriptor::GetTotalSize() const {
+ size_t total_size = 0;
+ for (const FrameStateDescriptor* iter = this; iter != NULL;
+ iter = iter->outer_state_) {
+ total_size += iter->GetSize();
+ }
+ return total_size;
+}
+
+
+size_t FrameStateDescriptor::GetFrameCount() const {
+ size_t count = 0;
+ for (const FrameStateDescriptor* iter = this; iter != NULL;
+ iter = iter->outer_state_) {
+ ++count;
+ }
+ return count;
+}
+
+
+size_t FrameStateDescriptor::GetJSFrameCount() const {
+ size_t count = 0;
+ for (const FrameStateDescriptor* iter = this; iter != NULL;
+ iter = iter->outer_state_) {
+ if (iter->type_ == FrameStateType::kJavaScriptFunction) {
+ ++count;
+ }
+ }
+ return count;
+}
+
+
+size_t StateValueDescriptor::AddOperand(InstructionOperandVector* inputs,
Jarin 2015/12/02 12:24:34 Could we have a comment explaining what the return
sigurds 2015/12/02 16:35:13 Done.
+ OperandGenerator* g,
+ StateObjectCache* cache, Node* input,
+ MachineType type,
+ FrameStateInputKind kind, Zone* zone) {
+ switch (input->opcode()) {
+ case IrOpcode::kObjectState: {
+ size_t id = cache->GetObjectId(input);
+ if (id == StateObjectCache::kNotCached) {
+ size_t entries = 0;
+ id = cache->InsertObject(input);
+ fields_.push_back(StateValueDescriptor(zone, kMachAnyTagged, id));
+ StateValueDescriptor& desc = fields_.back();
+ for (Edge edge : input->input_edges()) {
+ entries += desc.AddOperand(inputs, g, cache, edge.to(),
+ kMachAnyTagged, kind, zone);
+ }
+ return entries;
+ } else {
+ fields_.push_back(StateValueDescriptor(zone, kMachAnyTagged, id));
Jarin 2015/12/02 12:24:34 I think it would be nice to somehow signal in the
sigurds 2015/12/02 16:35:13 Great idea, thanks.
+ return 0;
+ }
+ } break;
Jarin 2015/12/02 12:24:34 The "break;" should go before the brace.
sigurds 2015/12/02 16:35:12 Done.
+ default:
+ inputs->push_back(g->UseForDeopt(input, kind));
+ fields_.push_back(StateValueDescriptor(zone, type));
+ return 1;
+ }
+}
+
+
+size_t FrameStateDescriptor::AddInputs(Node* state, OperandGenerator* g,
+ StateObjectCache* cache,
+ InstructionOperandVector* inputs,
+ FrameStateInputKind kind, Zone* zone) {
+ DCHECK_EQ(IrOpcode::kFrameState, state->op()->opcode());
+
+ size_t entries = 0;
+ size_t initial_size = inputs->size();
+
+ if (outer_state()) {
+ entries +=
+ outer_state()->AddInputs(state->InputAt(kFrameStateOuterStateInput), g,
+ cache, inputs, kind, zone);
+ }
+
+ Node* parameters = state->InputAt(kFrameStateParametersInput);
+ Node* locals = state->InputAt(kFrameStateLocalsInput);
+ Node* stack = state->InputAt(kFrameStateStackInput);
+ Node* context = state->InputAt(kFrameStateContextInput);
+ Node* function = state->InputAt(kFrameStateFunctionInput);
+
+ DCHECK_EQ(parameters_count(), StateValuesAccess(parameters).size());
+ DCHECK_EQ(locals_count(), StateValuesAccess(locals).size());
+ DCHECK_EQ(stack_count(), StateValuesAccess(stack).size());
+
+ StateValueDescriptor* desc = GetStateValueDescriptor();
+ entries +=
+ desc->AddOperand(inputs, g, cache, function, kMachAnyTagged, kind, zone);
+ for (StateValuesAccess::TypedNode input_node :
+ StateValuesAccess(parameters)) {
+ entries += desc->AddOperand(inputs, g, cache, input_node.node,
+ input_node.type, kind, zone);
+ }
+ if (HasContext()) {
+ entries +=
+ desc->AddOperand(inputs, g, cache, context, kMachAnyTagged, kind, zone);
+ }
+ for (StateValuesAccess::TypedNode input_node : StateValuesAccess(locals)) {
+ entries += desc->AddOperand(inputs, g, cache, input_node.node,
+ input_node.type, kind, zone);
+ }
+ for (StateValuesAccess::TypedNode input_node : StateValuesAccess(stack)) {
+ entries += desc->AddOperand(inputs, g, cache, input_node.node,
+ input_node.type, kind, zone);
+ }
+ DCHECK_EQ(initial_size + entries, inputs->size());
+ return entries;
+}
+
+
+size_t StateValueDescriptor::Translate(CodeGenerator* gen,
Jarin 2015/12/02 12:24:34 Description of return value, please. (Number of co
sigurds 2015/12/02 16:35:13 Done.
+ Translation* translation,
+ Instruction* instr,
+ size_t frame_state_offset) {
+ if (IsRecursive()) {
+ size_t entries = 0;
+ translation->BeginCapturedObject(static_cast<int>(size()));
+ for (size_t index = 0; index < fields_.size(); index++) {
+ entries += fields_[index].Translate(gen, translation, instr,
+ frame_state_offset + index);
+ }
+ return entries;
+ } else if (IsDuplicate()) {
+ translation->DuplicateObject(static_cast<int>(id_));
+ return 0;
+ } else {
+ gen->AddTranslationForOperand(translation, instr,
+ instr->InputAt(frame_state_offset), type_);
+ return 1;
+ }
+}
+
+
+size_t StateValueDescriptor::TranslateOperand(size_t index, CodeGenerator* gen,
+ Translation* translation,
+ Instruction* instr,
+ size_t frame_state_offset) {
+ return fields_[index].Translate(gen, translation, instr,
+ frame_state_offset + index);
+}
+
+
+void FrameStateDescriptor::TranslateOperands(CodeGenerator* gen,
+ Instruction* instr,
+ size_t frame_state_offset,
+ OutputFrameStateCombine combine,
+ Translation* translation) {
+ for (size_t index = 0; index < GetSize(combine); index++) {
+ switch (combine.kind()) {
+ case OutputFrameStateCombine::kPushOutput: {
+ DCHECK(combine.GetPushCount() <= instr->OutputCount());
+ size_t size_without_output = GetSize(OutputFrameStateCombine::Ignore());
+ // If the index is past the existing stack items in values_.
+ if (index >= size_without_output) {
+ // Materialize the result of the call instruction in this slot.
+ gen->AddTranslationForOperand(
+ translation, instr, instr->OutputAt(index - size_without_output),
+ kMachAnyTagged);
+ continue;
+ }
+ break;
+ }
+ case OutputFrameStateCombine::kPokeAt:
+ // The result of the call should be placed at position
+ // [index_from_top] in the stack (overwriting whatever was
+ // previously there).
+ size_t index_from_top =
+ GetSize(combine) - 1 - combine.GetOffsetToPokeAt();
+ if (index >= index_from_top &&
+ index < index_from_top + instr->OutputCount()) {
+ gen->AddTranslationForOperand(translation, instr,
+ instr->OutputAt(index - index_from_top),
+ kMachAnyTagged);
+ continue;
+ }
+ break;
+ }
+ // Add the additional fields we read during materialization.
+ frame_state_offset += values_.TranslateOperand(index, gen, translation,
+ instr, frame_state_offset) -
+ 1;
+ }
+}
+
} // namespace compiler
} // namespace internal
} // namespace v8

Powered by Google App Engine
This is Rietveld 408576698