Commit d4f70f8c authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Revive the VectorSlotPair and also put feedback on JSCallFunction.

We resurrect the VectorSlotPair in order to be able to separate the
feedback input for the compiler from the actual type feedback vector
that is required to meet the IC requirements at runtime. This will allow
us to for example use feedback from a different context or divide the
type feedback vector into two separate vectors, without having to touch
the compiler. It'll allow use to load the vector from the shared
function info at runtime, while still consuming feedback in the
compiler (i.e. we don't rely on the feedback vector node to be a heap
constant).

R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/1198983002

Cr-Commit-Position: refs/heads/master@{#29185}
parent 42f30f4d
This diff is collapsed.
......@@ -236,9 +236,8 @@ class AstGraphBuilder : public AstVisitor {
Node** EnsureInputBufferSize(int size);
// Named and keyed loads require a ResolvedFeedbackSlot for successful
// lowering.
ResolvedFeedbackSlot ResolveFeedbackSlot(FeedbackVectorICSlot slot) const;
// Named and keyed loads require a VectorSlotPair for successful lowering.
VectorSlotPair CreateVectorSlotPair(FeedbackVectorICSlot slot) const;
// Determine which contexts need to be checked for extension objects that
// might shadow the optimistic declaration of dynamic lookup variables.
......@@ -269,8 +268,7 @@ class AstGraphBuilder : public AstVisitor {
// Builders for variable load and assignment.
Node* BuildVariableAssignment(Variable* variable, Node* value,
Token::Value op,
const ResolvedFeedbackSlot& slot,
Token::Value op, const VectorSlotPair& slot,
BailoutId bailout_id,
FrameStateBeforeAndAfter& states,
OutputFrameStateCombine framestate_combine =
......@@ -279,22 +277,20 @@ class AstGraphBuilder : public AstVisitor {
OutputFrameStateCombine framestate_combine);
Node* BuildVariableLoad(Variable* variable, BailoutId bailout_id,
FrameStateBeforeAndAfter& states,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
OutputFrameStateCombine framestate_combine,
ContextualMode mode = CONTEXTUAL);
// Builders for property loads and stores.
Node* BuildKeyedLoad(Node* receiver, Node* key,
const ResolvedFeedbackSlot& feedback);
const VectorSlotPair& feedback);
Node* BuildNamedLoad(Node* receiver, Handle<Name> name,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
ContextualMode mode = NOT_CONTEXTUAL);
Node* BuildKeyedStore(Node* receiver, Node* key, Node* value,
const ResolvedFeedbackSlot& feedback,
TypeFeedbackId id);
const VectorSlotPair& feedback, TypeFeedbackId id);
Node* BuildNamedStore(Node* receiver, Handle<Name>, Node* value,
const ResolvedFeedbackSlot& feedback,
TypeFeedbackId id);
const VectorSlotPair& feedback, TypeFeedbackId id);
// Builders for super property loads and stores.
Node* BuildKeyedSuperStore(Node* receiver, Node* home_object, Node* key,
......@@ -302,10 +298,9 @@ class AstGraphBuilder : public AstVisitor {
Node* BuildNamedSuperStore(Node* receiver, Node* home_object,
Handle<Name> name, Node* value, TypeFeedbackId id);
Node* BuildNamedSuperLoad(Node* receiver, Node* home_object,
Handle<Name> name,
const ResolvedFeedbackSlot& feedback);
Handle<Name> name, const VectorSlotPair& feedback);
Node* BuildKeyedSuperLoad(Node* receiver, Node* home_object, Node* key,
const ResolvedFeedbackSlot& feedback);
const VectorSlotPair& feedback);
// Builders for accessing the function context.
Node* BuildLoadBuiltinsObject();
......@@ -326,7 +321,7 @@ class AstGraphBuilder : public AstVisitor {
// Builder for adding the [[HomeObject]] to a value if the value came from a
// function literal and needs a home object. Do nothing otherwise.
Node* BuildSetHomeObject(Node* value, Node* home_object, Expression* expr,
const ResolvedFeedbackSlot& slot);
const VectorSlotPair& feedback);
// Builders for error reporting at runtime.
Node* BuildThrowError(Node* exception, BailoutId bailout_id);
......@@ -392,7 +387,7 @@ class AstGraphBuilder : public AstVisitor {
// Dispatched from VisitForInStatement.
void VisitForInAssignment(Expression* expr, Node* value,
const ResolvedFeedbackSlot& slot,
const VectorSlotPair& feedback,
BailoutId bailout_id);
// Dispatched from VisitClassLiteral.
......
......@@ -14,6 +14,21 @@ namespace v8 {
namespace internal {
namespace compiler {
bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
return lhs.slot() == rhs.slot() && lhs.vector() == rhs.vector();
}
bool operator!=(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
return !(lhs == rhs);
}
size_t hash_value(VectorSlotPair const& p) {
return base::hash_combine(p.slot(), p.vector());
}
std::ostream& operator<<(std::ostream& os, CallFunctionParameters const& p) {
return os << p.arity() << ", " << p.flags() << ", " << p.language_mode();
}
......@@ -93,7 +108,7 @@ ContextAccess const& ContextAccessOf(Operator const* op) {
DynamicGlobalAccess::DynamicGlobalAccess(const Handle<String>& name,
uint32_t check_bitset,
const ResolvedFeedbackSlot& feedback,
const VectorSlotPair& feedback,
ContextualMode mode)
: name_(name),
check_bitset_(check_bitset),
......@@ -175,18 +190,6 @@ DynamicContextAccess const& DynamicContextAccessOf(Operator const* op) {
}
bool operator==(ResolvedFeedbackSlot const& lhs,
ResolvedFeedbackSlot const& rhs) {
return lhs.slot().ToInt() == rhs.slot().ToInt();
}
size_t hash_value(ResolvedFeedbackSlot const& p) {
base::hash<int> h;
return h(p.slot().ToInt());
}
bool operator==(LoadNamedParameters const& lhs,
LoadNamedParameters const& rhs) {
return lhs.name() == rhs.name() &&
......@@ -452,10 +455,10 @@ CACHED_OP_LIST_WITH_LANGUAGE_MODE(CACHED_WITH_LANGUAGE_MODE)
#undef CACHED_WITH_LANGUAGE_MODE
const Operator* JSOperatorBuilder::CallFunction(size_t arity,
CallFunctionFlags flags,
LanguageMode language_mode) {
CallFunctionParameters parameters(arity, flags, language_mode);
const Operator* JSOperatorBuilder::CallFunction(
size_t arity, CallFunctionFlags flags, LanguageMode language_mode,
VectorSlotPair const& feedback) {
CallFunctionParameters parameters(arity, flags, language_mode, feedback);
return new (zone()) Operator1<CallFunctionParameters>( // --
IrOpcode::kJSCallFunction, Operator::kNoProperties, // opcode
"JSCallFunction", // name
......@@ -486,9 +489,9 @@ const Operator* JSOperatorBuilder::CallConstruct(int arguments) {
}
const Operator* JSOperatorBuilder::LoadNamed(
const Unique<Name>& name, const ResolvedFeedbackSlot& feedback,
ContextualMode contextual_mode) {
const Operator* JSOperatorBuilder::LoadNamed(const Unique<Name>& name,
const VectorSlotPair& feedback,
ContextualMode contextual_mode) {
LoadNamedParameters parameters(name, feedback, contextual_mode);
return new (zone()) Operator1<LoadNamedParameters>( // --
IrOpcode::kJSLoadNamed, Operator::kNoProperties, // opcode
......@@ -499,7 +502,7 @@ const Operator* JSOperatorBuilder::LoadNamed(
const Operator* JSOperatorBuilder::LoadProperty(
const ResolvedFeedbackSlot& feedback) {
const VectorSlotPair& feedback) {
LoadPropertyParameters parameters(feedback);
return new (zone()) Operator1<LoadPropertyParameters>( // --
IrOpcode::kJSLoadProperty, Operator::kNoProperties, // opcode
......@@ -509,9 +512,9 @@ const Operator* JSOperatorBuilder::LoadProperty(
}
const Operator* JSOperatorBuilder::StoreNamed(
LanguageMode language_mode, const Unique<Name>& name,
const ResolvedFeedbackSlot& feedback) {
const Operator* JSOperatorBuilder::StoreNamed(LanguageMode language_mode,
const Unique<Name>& name,
const VectorSlotPair& feedback) {
StoreNamedParameters parameters(language_mode, feedback, name);
return new (zone()) Operator1<StoreNamedParameters>( // --
IrOpcode::kJSStoreNamed, Operator::kNoProperties, // opcode
......@@ -522,7 +525,7 @@ const Operator* JSOperatorBuilder::StoreNamed(
const Operator* JSOperatorBuilder::StoreProperty(
LanguageMode language_mode, const ResolvedFeedbackSlot& feedback) {
LanguageMode language_mode, const VectorSlotPair& feedback) {
StorePropertyParameters parameters(language_mode, feedback);
return new (zone()) Operator1<StorePropertyParameters>( // --
IrOpcode::kJSStoreProperty, Operator::kNoProperties, // opcode
......@@ -566,7 +569,7 @@ const Operator* JSOperatorBuilder::StoreContext(size_t depth, size_t index) {
const Operator* JSOperatorBuilder::LoadDynamicGlobal(
const Handle<String>& name, uint32_t check_bitset,
const ResolvedFeedbackSlot& feedback, ContextualMode mode) {
const VectorSlotPair& feedback, ContextualMode mode) {
DynamicGlobalAccess access(name, check_bitset, feedback, mode);
return new (zone()) Operator1<DynamicGlobalAccess>( // --
IrOpcode::kJSLoadDynamicGlobal, Operator::kNoProperties, // opcode
......
This diff is collapsed.
......@@ -9,7 +9,6 @@
namespace v8 {
namespace internal {
int HandleScope::NumberOfHandles(Isolate* isolate) {
HandleScopeImplementer* impl = isolate->handle_scope_implementer();
int n = impl->blocks()->length();
......
......@@ -66,14 +66,32 @@ class MaybeHandle {
bool is_null() const { return location_ == NULL; }
template <typename S>
bool operator==(MaybeHandle<S> that) const {
return this->location_ == that.location_;
}
template <typename S>
bool operator!=(MaybeHandle<S> that) const {
return !(*this == that);
}
protected:
T** location_;
// MaybeHandles of different classes are allowed to access each
// other's location_.
template<class S> friend class MaybeHandle;
template <typename S>
friend size_t hash_value(MaybeHandle<S>);
};
template <typename S>
inline size_t hash_value(MaybeHandle<S> maybe_handle) {
return bit_cast<size_t>(maybe_handle.location_);
}
// ----------------------------------------------------------------------------
// A Handle provides a reference to an object that survives relocation by
// the garbage collector.
......
......@@ -1047,17 +1047,19 @@ template <int dummy_parameter>
class VectorSlot {
public:
explicit VectorSlot(int id) : id_(id) {}
int ToInt() const { return id_; }
static VectorSlot Invalid() { return VectorSlot(kInvalidSlot); }
bool IsInvalid() const { return id_ == kInvalidSlot; }
VectorSlot next() const {
DCHECK(id_ != kInvalidSlot);
DCHECK_NE(kInvalidSlot, id_);
return VectorSlot(id_ + 1);
}
bool operator==(const VectorSlot& other) const { return id_ == other.id_; }
bool operator==(VectorSlot that) const { return this->id_ == that.id_; }
bool operator!=(VectorSlot that) const { return !(*this == that); }
private:
static const int kInvalidSlot = -1;
......@@ -1066,6 +1068,12 @@ class VectorSlot {
};
template <int dummy_parameter>
size_t hash_value(VectorSlot<dummy_parameter> slot) {
return slot.ToInt();
}
typedef VectorSlot<0> FeedbackVectorSlot;
typedef VectorSlot<1> FeedbackVectorICSlot;
......
......@@ -77,7 +77,7 @@ class JSTypeFeedbackTest : public TypedGraphTest {
Node* ReturnLoadNamedFromGlobal(
const char* string, Node* effect, Node* control,
JSTypeFeedbackSpecializer::DeoptimizationMode mode) {
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
Node* global = Parameter(Type::GlobalObject());
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
......
......@@ -648,7 +648,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) {
double backing_store[kLength];
Handle<JSArrayBuffer> buffer =
NewArrayBuffer(backing_store, sizeof(backing_store));
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Handle<JSTypedArray> array =
factory()->NewJSTypedArray(type, buffer, 0, kLength);
......@@ -687,7 +687,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArrayWithSafeKey) {
double backing_store[kLength];
Handle<JSArrayBuffer> buffer =
NewArrayBuffer(backing_store, sizeof(backing_store));
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) {
Handle<JSTypedArray> array =
factory()->NewJSTypedArray(type, buffer, 0, kLength);
......@@ -739,9 +739,9 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) {
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
ResolvedFeedbackSlot slot;
VectorSlotPair feedback;
Node* node =
graph()->NewNode(javascript()->StoreProperty(language_mode, slot),
graph()->NewNode(javascript()->StoreProperty(language_mode, feedback),
base, key, value, context);
for (int i = 0;
i < OperatorProperties::GetFrameStateInputCount(node->op()); i++) {
......@@ -787,9 +787,9 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithConversion) {
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
ResolvedFeedbackSlot slot;
VectorSlotPair feedback;
Node* node =
graph()->NewNode(javascript()->StoreProperty(language_mode, slot),
graph()->NewNode(javascript()->StoreProperty(language_mode, feedback),
base, key, value, context);
for (int i = 0;
i < OperatorProperties::GetFrameStateInputCount(node->op()); i++) {
......@@ -848,9 +848,9 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArrayWithSafeKey) {
Node* context = UndefinedConstant();
Node* effect = graph()->start();
Node* control = graph()->start();
ResolvedFeedbackSlot slot;
VectorSlotPair feedback;
Node* node =
graph()->NewNode(javascript()->StoreProperty(language_mode, slot),
graph()->NewNode(javascript()->StoreProperty(language_mode, feedback),
base, key, value, context);
for (int i = 0;
i < OperatorProperties::GetFrameStateInputCount(node->op()); i++) {
......@@ -884,7 +884,7 @@ TEST_F(JSTypedLoweringTest, JSLoadNamedGlobalConstants) {
IsNumberConstant(IsNaN()) // --
};
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
Node* global = Parameter(Type::GlobalObject());
Node* vector = UndefinedConstant();
Node* context = UndefinedConstant();
......@@ -914,7 +914,7 @@ TEST_F(JSTypedLoweringTest, JSLoadDynamicGlobal) {
Node* const effect = graph()->start();
Node* const control = graph()->start();
Handle<String> name = factory()->object_string();
ResolvedFeedbackSlot feedback;
VectorSlotPair feedback;
for (int i = 0; i < DynamicGlobalAccess::kMaxCheckDepth; ++i) {
uint32_t bitset = 1 << i; // Only single check.
Reduction r = Reduce(graph()->NewNode(
......
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