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:
mstarzinger 2015-08-31 04:37:35 -07:00 committed by Commit bot
parent fbad63669e
commit 51fa9e5295
4 changed files with 22 additions and 30 deletions

View File

@ -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());
}

View File

@ -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_;
};

View File

@ -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) {

View File

@ -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