From 6e3b54ae360be8c3ccafe5ef7952b1432713a68c Mon Sep 17 00:00:00 2001 From: "svenpanne@chromium.org" Date: Thu, 2 Oct 2014 09:38:28 +0000 Subject: [PATCH] Merged FeedbackSlotInterface into AstNode, removing the need for a 2nd vtable. This tiny change shaves off 112MB from the peak memory usage in the bug mentioned below, more to come... BUG=417697 LOG=y R=mvstanton@chromium.org Review URL: https://codereview.chromium.org/611393004 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24390 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ast.h | 29 +++++++++++++++++++---------- src/feedback-slots.h | 27 --------------------------- src/hydrogen-instructions.h | 20 ++++++++------------ 3 files changed, 27 insertions(+), 49 deletions(-) delete mode 100644 src/feedback-slots.h diff --git a/src/ast.h b/src/ast.h index f695e12..c55505f 100644 --- a/src/ast.h +++ b/src/ast.h @@ -11,7 +11,6 @@ #include "src/ast-value-factory.h" #include "src/bailout-reason.h" #include "src/factory.h" -#include "src/feedback-slots.h" #include "src/interface.h" #include "src/isolate.h" #include "src/jsregexp.h" @@ -233,6 +232,17 @@ class AstNode: public ZoneObject { virtual IterationStatement* AsIterationStatement() { return NULL; } virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; } + // The interface for feedback slots, with default no-op implementations for + // node types which don't actually have this. Note that this is conceptually + // not really nice, but multiple inheritance would introduce yet another + // vtable entry per node, something we don't want for space reasons. + static const int kInvalidFeedbackSlot = -1; + virtual int ComputeFeedbackSlotCount() { + UNREACHABLE(); + return 0; + } + virtual void SetFirstFeedbackSlot(int slot) { UNREACHABLE(); } + protected: // Some nodes re-use bailout IDs for type feedback. static TypeFeedbackId reuse(BailoutId id) { @@ -914,8 +924,7 @@ class ForEachStatement : public IterationStatement { }; -class ForInStatement FINAL : public ForEachStatement, - public FeedbackSlotInterface { +class ForInStatement FINAL : public ForEachStatement { public: DECLARE_NODE_TYPE(ForInStatement) @@ -1628,7 +1637,7 @@ class ArrayLiteral FINAL : public MaterializedLiteral { }; -class VariableProxy FINAL : public Expression, public FeedbackSlotInterface { +class VariableProxy FINAL : public Expression { public: DECLARE_NODE_TYPE(VariableProxy) @@ -1672,7 +1681,7 @@ class VariableProxy FINAL : public Expression, public FeedbackSlotInterface { }; -class Property FINAL : public Expression, public FeedbackSlotInterface { +class Property FINAL : public Expression { public: DECLARE_NODE_TYPE(Property) @@ -1741,7 +1750,7 @@ class Property FINAL : public Expression, public FeedbackSlotInterface { }; -class Call FINAL : public Expression, public FeedbackSlotInterface { +class Call FINAL : public Expression { public: DECLARE_NODE_TYPE(Call) @@ -1844,7 +1853,7 @@ class Call FINAL : public Expression, public FeedbackSlotInterface { }; -class CallNew FINAL : public Expression, public FeedbackSlotInterface { +class CallNew FINAL : public Expression { public: DECLARE_NODE_TYPE(CallNew) @@ -1907,7 +1916,7 @@ class CallNew FINAL : public Expression, public FeedbackSlotInterface { // language construct. Instead it is used to call a C or JS function // with a set of arguments. This is used from the builtins that are // implemented in JavaScript (see "v8natives.js"). -class CallRuntime FINAL : public Expression, public FeedbackSlotInterface { +class CallRuntime FINAL : public Expression { public: DECLARE_NODE_TYPE(CallRuntime) @@ -2223,7 +2232,7 @@ class Assignment FINAL : public Expression { }; -class Yield FINAL : public Expression, public FeedbackSlotInterface { +class Yield FINAL : public Expression { public: DECLARE_NODE_TYPE(Yield) @@ -3038,7 +3047,7 @@ class AstConstructionVisitor BASE_EMBEDDED { dont_turbofan_reason_ = reason; } - void add_slot_node(FeedbackSlotInterface* slot_node) { + void add_slot_node(AstNode* slot_node) { int count = slot_node->ComputeFeedbackSlotCount(); if (count > 0) { slot_node->SetFirstFeedbackSlot(properties_.feedback_slots()); diff --git a/src/feedback-slots.h b/src/feedback-slots.h deleted file mode 100644 index 9951fc8..0000000 --- a/src/feedback-slots.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 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. - -#ifndef V8_FEEDBACK_SLOTS_H_ -#define V8_FEEDBACK_SLOTS_H_ - -#include "src/v8.h" - -#include "src/isolate.h" - -namespace v8 { -namespace internal { - -class FeedbackSlotInterface { - public: - static const int kInvalidFeedbackSlot = -1; - - virtual ~FeedbackSlotInterface() {} - - virtual int ComputeFeedbackSlotCount() = 0; - virtual void SetFirstFeedbackSlot(int slot) = 0; -}; - -} } // namespace v8::internal - -#endif // V8_FEEDBACK_SLOTS_H_ diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 3c0042de..aec7644 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -15,7 +15,6 @@ #include "src/conversions.h" #include "src/data-flow.h" #include "src/deoptimizer.h" -#include "src/feedback-slots.h" #include "src/hydrogen-types.h" #include "src/small-pointer-list.h" #include "src/unique.h" @@ -5475,8 +5474,7 @@ class HLoadGlobalGeneric FINAL : public HTemplateInstruction<2> { Handle name() const { return name_; } bool for_typeof() const { return for_typeof_; } int slot() const { - DCHECK(FLAG_vector_ics && - slot_ != FeedbackSlotInterface::kInvalidFeedbackSlot); + DCHECK(FLAG_vector_ics && slot_ != AstNode::kInvalidFeedbackSlot); return slot_; } Handle feedback_vector() const { return feedback_vector_; } @@ -5497,8 +5495,9 @@ class HLoadGlobalGeneric FINAL : public HTemplateInstruction<2> { private: HLoadGlobalGeneric(HValue* context, HValue* global_object, Handle name, bool for_typeof) - : name_(name), for_typeof_(for_typeof), - slot_(FeedbackSlotInterface::kInvalidFeedbackSlot) { + : name_(name), + for_typeof_(for_typeof), + slot_(AstNode::kInvalidFeedbackSlot) { SetOperandAt(0, context); SetOperandAt(1, global_object); set_representation(Representation::Tagged()); @@ -6478,8 +6477,7 @@ class HLoadNamedGeneric FINAL : public HTemplateInstruction<2> { Handle name() const { return name_; } int slot() const { - DCHECK(FLAG_vector_ics && - slot_ != FeedbackSlotInterface::kInvalidFeedbackSlot); + DCHECK(FLAG_vector_ics && slot_ != AstNode::kInvalidFeedbackSlot); return slot_; } Handle feedback_vector() const { return feedback_vector_; } @@ -6499,8 +6497,7 @@ class HLoadNamedGeneric FINAL : public HTemplateInstruction<2> { private: HLoadNamedGeneric(HValue* context, HValue* object, Handle name) - : name_(name), - slot_(FeedbackSlotInterface::kInvalidFeedbackSlot) { + : name_(name), slot_(AstNode::kInvalidFeedbackSlot) { SetOperandAt(0, context); SetOperandAt(1, object); set_representation(Representation::Tagged()); @@ -6756,8 +6753,7 @@ class HLoadKeyedGeneric FINAL : public HTemplateInstruction<3> { HValue* key() const { return OperandAt(1); } HValue* context() const { return OperandAt(2); } int slot() const { - DCHECK(FLAG_vector_ics && - slot_ != FeedbackSlotInterface::kInvalidFeedbackSlot); + DCHECK(FLAG_vector_ics && slot_ != AstNode::kInvalidFeedbackSlot); return slot_; } Handle feedback_vector() const { return feedback_vector_; } @@ -6780,7 +6776,7 @@ class HLoadKeyedGeneric FINAL : public HTemplateInstruction<3> { private: HLoadKeyedGeneric(HValue* context, HValue* obj, HValue* key) - : slot_(FeedbackSlotInterface::kInvalidFeedbackSlot) { + : slot_(AstNode::kInvalidFeedbackSlot) { set_representation(Representation::Tagged()); SetOperandAt(0, obj); SetOperandAt(1, key); -- 2.7.4