| Index: src/compiler/js-type-feedback.cc
|
| diff --git a/src/compiler/js-type-feedback.cc b/src/compiler/js-type-feedback.cc
|
| index 749eebab290919e9fc5338a9734f62ca72dfb49e..02c9677bec05631d3c90d020218f036828ea4c2f 100644
|
| --- a/src/compiler/js-type-feedback.cc
|
| +++ b/src/compiler/js-type-feedback.cc
|
| @@ -13,6 +13,7 @@
|
|
|
| #include "src/compiler/access-builder.h"
|
| #include "src/compiler/common-operator.h"
|
| +#include "src/compiler/frame-states.h"
|
| #include "src/compiler/node-aux-data.h"
|
| #include "src/compiler/node-matchers.h"
|
| #include "src/compiler/operator-properties.h"
|
| @@ -24,8 +25,6 @@ namespace compiler {
|
|
|
| enum LoadOrStore { LOAD, STORE };
|
|
|
| -#define EAGER_DEOPT_LOCATIONS_FOR_PROPERTY_ACCESS_ARE_CORRECT false
|
| -
|
| JSTypeFeedbackTable::JSTypeFeedbackTable(Zone* zone)
|
| : map_(TypeFeedbackIdMap::key_compare(),
|
| TypeFeedbackIdMap::allocator_type(zone)) {}
|
| @@ -163,8 +162,8 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
|
| }
|
|
|
| if (!FLAG_turbo_deoptimization) return NoChange();
|
| - // TODO(titzer): deopt locations are wrong for property accesses
|
| - if (!EAGER_DEOPT_LOCATIONS_FOR_PROPERTY_ACCESS_ARE_CORRECT) return NoChange();
|
| + Node* frame_state_before = GetFrameStateBefore(node);
|
| + if (frame_state_before == nullptr) return NoChange();
|
|
|
| // TODO(turbofan): handle vector-based type feedback.
|
| TypeFeedbackId id = js_type_feedback_->find(node);
|
| @@ -197,10 +196,8 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
|
| effect, check_success);
|
|
|
| // TODO(turbofan): handle slow case instead of deoptimizing.
|
| - // TODO(titzer): frame state should be from before the load.
|
| - Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
|
| - Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state, effect,
|
| - check_failed);
|
| + Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before,
|
| + effect, check_failed);
|
| NodeProperties::MergeControlToEnd(graph(), common(), deopt);
|
| NodeProperties::ReplaceWithValue(node, load, load, check_success);
|
| return Replace(load);
|
| @@ -282,8 +279,8 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadProperty(Node* node) {
|
|
|
| Reduction JSTypeFeedbackSpecializer::ReduceJSStoreNamed(Node* node) {
|
| DCHECK(node->opcode() == IrOpcode::kJSStoreNamed);
|
| - // TODO(titzer): deopt locations are wrong for property accesses
|
| - if (!EAGER_DEOPT_LOCATIONS_FOR_PROPERTY_ACCESS_ARE_CORRECT) return NoChange();
|
| + Node* frame_state_before = GetFrameStateBefore(node);
|
| + if (frame_state_before == nullptr) return NoChange();
|
|
|
| TypeFeedbackId id = js_type_feedback_->find(node);
|
| if (id.IsNone() || oracle()->StoreIsUninitialized(id)) return NoChange();
|
| @@ -315,10 +312,8 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSStoreNamed(Node* node) {
|
| receiver, value, effect, check_success);
|
|
|
| // TODO(turbofan): handle slow case instead of deoptimizing.
|
| - // TODO(titzer): frame state should be from before the store.
|
| - Node* frame_state = NodeProperties::GetFrameStateInput(node, 0);
|
| - Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state, effect,
|
| - check_failed);
|
| + Node* deopt = graph()->NewNode(common()->Deoptimize(), frame_state_before,
|
| + effect, check_failed);
|
| NodeProperties::MergeControlToEnd(graph(), common(), deopt);
|
| NodeProperties::ReplaceWithValue(node, store, store, check_success);
|
| return Replace(store);
|
| @@ -372,6 +367,21 @@ void JSTypeFeedbackSpecializer::GatherReceiverTypes(Node* receiver,
|
| }
|
|
|
|
|
| +// Get the frame state before an operation if it exists and has a valid
|
| +// bailout id.
|
| +Node* JSTypeFeedbackSpecializer::GetFrameStateBefore(Node* node) {
|
| + int count = OperatorProperties::GetFrameStateInputCount(node->op());
|
| + DCHECK_LE(count, 2);
|
| + if (count == 2) {
|
| + Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
|
| + if (frame_state->opcode() == IrOpcode::kFrameState) {
|
| + BailoutId id = OpParameter<FrameStateCallInfo>(node).bailout_id();
|
| + if (id != BailoutId::None()) return frame_state;
|
| + }
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|