summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/js-type-feedback-lowering.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/js-type-feedback-lowering.cc')
-rw-r--r--deps/v8/src/compiler/js-type-feedback-lowering.cc118
1 files changed, 118 insertions, 0 deletions
diff --git a/deps/v8/src/compiler/js-type-feedback-lowering.cc b/deps/v8/src/compiler/js-type-feedback-lowering.cc
new file mode 100644
index 0000000000..2522a7af07
--- /dev/null
+++ b/deps/v8/src/compiler/js-type-feedback-lowering.cc
@@ -0,0 +1,118 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "src/compiler/js-type-feedback-lowering.h"
+
+#include "src/compiler/access-builder.h"
+#include "src/compiler/js-graph.h"
+#include "src/compiler/node-properties.h"
+
+namespace v8 {
+namespace internal {
+namespace compiler {
+
+JSTypeFeedbackLowering::JSTypeFeedbackLowering(Editor* editor, Flags flags,
+ JSGraph* jsgraph)
+ : AdvancedReducer(editor),
+ flags_(flags),
+ jsgraph_(jsgraph),
+ simplified_(graph()->zone()) {}
+
+
+Reduction JSTypeFeedbackLowering::Reduce(Node* node) {
+ switch (node->opcode()) {
+ case IrOpcode::kJSLoadNamed:
+ return ReduceJSLoadNamed(node);
+ default:
+ break;
+ }
+ return NoChange();
+}
+
+
+Reduction JSTypeFeedbackLowering::ReduceJSLoadNamed(Node* node) {
+ DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode());
+ Node* receiver = NodeProperties::GetValueInput(node, 0);
+ Type* receiver_type = NodeProperties::GetBounds(receiver).upper;
+ Node* frame_state = NodeProperties::GetFrameStateInput(node, 1);
+ Node* effect = NodeProperties::GetEffectInput(node);
+ Node* control = NodeProperties::GetControlInput(node);
+ // We need to make optimistic assumptions to continue.
+ if (!(flags() & kDeoptimizationEnabled)) return NoChange();
+ LoadNamedParameters const& p = LoadNamedParametersOf(node->op());
+ Handle<TypeFeedbackVector> vector;
+ if (!p.feedback().vector().ToHandle(&vector)) return NoChange();
+ if (p.name().handle().is_identical_to(factory()->length_string())) {
+ LoadICNexus nexus(vector, p.feedback().slot());
+ MapHandleList maps;
+ if (nexus.ExtractMaps(&maps) > 0) {
+ for (Handle<Map> map : maps) {
+ if (map->instance_type() >= FIRST_NONSTRING_TYPE) return NoChange();
+ }
+ // Optimistic optimization for "length" property of strings.
+ if (receiver_type->Maybe(Type::TaggedSigned())) {
+ Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
+ Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse),
+ check, control);
+ Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+ Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state,
+ effect, if_true);
+ // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+ NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+ control = graph()->NewNode(common()->IfFalse(), branch);
+ }
+ Node* receiver_map = effect =
+ graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+ receiver, effect, control);
+ Node* receiver_instance_type = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
+ receiver_map, effect, control);
+ Node* check =
+ graph()->NewNode(machine()->Uint32LessThan(), receiver_instance_type,
+ jsgraph()->Uint32Constant(FIRST_NONSTRING_TYPE));
+ Node* branch =
+ graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control);
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* deoptimize = graph()->NewNode(common()->Deoptimize(), frame_state,
+ effect, if_false);
+ // TODO(bmeurer): This should be on the AdvancedReducer somehow.
+ NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
+ control = graph()->NewNode(common()->IfTrue(), branch);
+ Node* value = effect =
+ graph()->NewNode(simplified()->LoadField(
+ AccessBuilder::ForStringLength(graph()->zone())),
+ receiver, effect, control);
+ ReplaceWithValue(node, value, effect, control);
+ return Replace(value);
+ }
+ }
+ return NoChange();
+}
+
+
+Factory* JSTypeFeedbackLowering::factory() const {
+ return isolate()->factory();
+}
+
+
+CommonOperatorBuilder* JSTypeFeedbackLowering::common() const {
+ return jsgraph()->common();
+}
+
+
+Graph* JSTypeFeedbackLowering::graph() const { return jsgraph()->graph(); }
+
+
+Isolate* JSTypeFeedbackLowering::isolate() const {
+ return jsgraph()->isolate();
+}
+
+
+MachineOperatorBuilder* JSTypeFeedbackLowering::machine() const {
+ return jsgraph()->machine();
+}
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8