Drop ambiguous MaybeHandle comparison and hashing ops.
The default equality comparison operators and hashing functions for Handles are ambiguous. The intended semantics might have either been based on Handle locations or on object identity. This is why such operators do not exist on Handle. The same argument applies to the MaybeHandle class as well. Comments in that regard were also added. R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/1319383002 Cr-Commit-Position: refs/heads/master@{#30468}
This commit is contained in:
parent
fbad63669e
commit
51fa9e5295
@ -15,7 +15,8 @@ namespace internal {
|
||||
namespace compiler {
|
||||
|
||||
bool operator==(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
|
||||
return lhs.slot() == rhs.slot() && lhs.vector() == rhs.vector();
|
||||
return lhs.slot() == rhs.slot() &&
|
||||
lhs.vector().location() == rhs.vector().location();
|
||||
}
|
||||
|
||||
|
||||
@ -25,7 +26,7 @@ bool operator!=(VectorSlotPair const& lhs, VectorSlotPair const& rhs) {
|
||||
|
||||
|
||||
size_t hash_value(VectorSlotPair const& p) {
|
||||
return base::hash_combine(p.slot(), p.vector());
|
||||
return base::hash_combine(p.slot(), p.vector().location());
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,16 +27,15 @@ class VectorSlotPair {
|
||||
|
||||
bool IsValid() const { return !vector_.is_null(); }
|
||||
|
||||
MaybeHandle<TypeFeedbackVector> vector() const { return vector_; }
|
||||
Handle<TypeFeedbackVector> vector() const { return vector_; }
|
||||
FeedbackVectorICSlot slot() const { return slot_; }
|
||||
|
||||
int index() const {
|
||||
Handle<TypeFeedbackVector> vector;
|
||||
return vector_.ToHandle(&vector) ? vector->GetIndex(slot_) : -1;
|
||||
return vector_.is_null() ? -1 : vector_->GetIndex(slot_);
|
||||
}
|
||||
|
||||
private:
|
||||
const MaybeHandle<TypeFeedbackVector> vector_;
|
||||
const Handle<TypeFeedbackVector> vector_;
|
||||
const FeedbackVectorICSlot slot_;
|
||||
};
|
||||
|
||||
|
@ -41,10 +41,9 @@ Reduction JSTypeFeedbackLowering::ReduceJSLoadNamed(Node* 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.feedback().vector().is_null()) return NoChange();
|
||||
if (p.name().is_identical_to(factory()->length_string())) {
|
||||
LoadICNexus nexus(vector, p.feedback().slot());
|
||||
LoadICNexus nexus(p.feedback().vector(), p.feedback().slot());
|
||||
MapHandleList maps;
|
||||
if (nexus.ExtractMaps(&maps) > 0) {
|
||||
for (Handle<Map> map : maps) {
|
||||
|
@ -71,8 +71,14 @@ class HandleBase {
|
||||
// ----------------------------------------------------------------------------
|
||||
// A Handle provides a reference to an object that survives relocation by
|
||||
// the garbage collector.
|
||||
// Handles are only valid within a HandleScope.
|
||||
// When a handle is created for an object a cell is allocated in the heap.
|
||||
//
|
||||
// Handles are only valid within a HandleScope. When a handle is created
|
||||
// for an object a cell is allocated in the current HandleScope.
|
||||
//
|
||||
// Also note that Handles do not provide default equality comparison or hashing
|
||||
// operators on purpose. Such operators would be misleading, because intended
|
||||
// semantics is ambiguous between Handle location and object identity. Instead
|
||||
// use either {is_identical_to} or {location} explicitly.
|
||||
template <typename T>
|
||||
class Handle final : public HandleBase {
|
||||
public:
|
||||
@ -160,7 +166,12 @@ V8_INLINE Handle<T> handle(T* object) {
|
||||
// A Handle can be converted into a MaybeHandle. Converting a MaybeHandle
|
||||
// into a Handle requires checking that it does not point to NULL. This
|
||||
// ensures NULL checks before use.
|
||||
//
|
||||
// Do not use MaybeHandle as argument type.
|
||||
//
|
||||
// Also note that Handles do not provide default equality comparison or hashing
|
||||
// operators on purpose. Such operators would be misleading, because intended
|
||||
// semantics is ambiguous between Handle location and object identity.
|
||||
template <typename T>
|
||||
class MaybeHandle final {
|
||||
public:
|
||||
@ -211,15 +222,6 @@ class MaybeHandle final {
|
||||
|
||||
bool is_null() const { return location_ == nullptr; }
|
||||
|
||||
template <typename S>
|
||||
V8_INLINE bool operator==(MaybeHandle<S> that) const {
|
||||
return this->location_ == that.location_;
|
||||
}
|
||||
template <typename S>
|
||||
V8_INLINE bool operator!=(MaybeHandle<S> that) const {
|
||||
return this->location_ != that.location_;
|
||||
}
|
||||
|
||||
protected:
|
||||
T** location_ = nullptr;
|
||||
|
||||
@ -227,19 +229,10 @@ class MaybeHandle final {
|
||||
// other's location_.
|
||||
template <typename>
|
||||
friend class MaybeHandle;
|
||||
// Utility functions are allowed to access location_.
|
||||
template <typename S>
|
||||
friend size_t hash_value(MaybeHandle<S>);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
V8_INLINE size_t hash_value(MaybeHandle<T> maybe_handle) {
|
||||
uintptr_t v = bit_cast<uintptr_t>(maybe_handle.location_);
|
||||
DCHECK_EQ(0u, v & ((1u << kPointerSizeLog2) - 1));
|
||||
return v >> kPointerSizeLog2;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// A stack-allocated class that governs a number of local handles.
|
||||
// After a handle scope has been created, all local handles will be
|
||||
// allocated within that handle scope until either the handle scope is
|
||||
|
Loading…
Reference in New Issue
Block a user