| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 5424fda025cb2ff2ee5d27978d27e3fb1abd518a..b389b2b5a046ffddbb9680974d06fe09b34673f1 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -1518,28 +1518,21 @@ Map* Object::GetRootMap(Isolate* isolate) {
|
| return isolate->heap()->null_value()->map();
|
| }
|
|
|
| +namespace {
|
|
|
| -Object* Object::GetHash() {
|
| - DisallowHeapAllocation no_gc;
|
| - Object* hash = GetSimpleHash();
|
| - if (hash->IsSmi()) return hash;
|
| -
|
| - DCHECK(IsJSReceiver());
|
| - JSReceiver* receiver = JSReceiver::cast(this);
|
| - Isolate* isolate = receiver->GetIsolate();
|
| - return *JSReceiver::GetIdentityHash(isolate, handle(receiver, isolate));
|
| -}
|
| -
|
| -
|
| -Object* Object::GetSimpleHash() {
|
| +// Returns a non-SMI for JSObjects, but returns the hash code for simple
|
| +// objects. This avoids a double lookup in the cases where we know we will
|
| +// add the hash to the JSObject if it does not already exist.
|
| +Object* GetSimpleHash(Object* object) {
|
| // The object is either a Smi, a HeapNumber, a name, an odd-ball,
|
| // a SIMD value type, a real JS object, or a Harmony proxy.
|
| - if (IsSmi()) {
|
| - uint32_t hash = ComputeIntegerHash(Smi::cast(this)->value(), kZeroHashSeed);
|
| + if (object->IsSmi()) {
|
| + uint32_t hash =
|
| + ComputeIntegerHash(Smi::cast(object)->value(), kZeroHashSeed);
|
| return Smi::FromInt(hash & Smi::kMaxValue);
|
| }
|
| - if (IsHeapNumber()) {
|
| - double num = HeapNumber::cast(this)->value();
|
| + if (object->IsHeapNumber()) {
|
| + double num = HeapNumber::cast(object)->value();
|
| if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue);
|
| if (i::IsMinusZero(num)) num = 0;
|
| if (IsSmiDouble(num)) {
|
| @@ -1548,30 +1541,43 @@ Object* Object::GetSimpleHash() {
|
| uint32_t hash = ComputeLongHash(double_to_uint64(num));
|
| return Smi::FromInt(hash & Smi::kMaxValue);
|
| }
|
| - if (IsName()) {
|
| - uint32_t hash = Name::cast(this)->Hash();
|
| + if (object->IsName()) {
|
| + uint32_t hash = Name::cast(object)->Hash();
|
| return Smi::FromInt(hash);
|
| }
|
| - if (IsOddball()) {
|
| - uint32_t hash = Oddball::cast(this)->to_string()->Hash();
|
| + if (object->IsOddball()) {
|
| + uint32_t hash = Oddball::cast(object)->to_string()->Hash();
|
| return Smi::FromInt(hash);
|
| }
|
| - if (IsSimd128Value()) {
|
| - uint32_t hash = Simd128Value::cast(this)->Hash();
|
| + if (object->IsSimd128Value()) {
|
| + uint32_t hash = Simd128Value::cast(object)->Hash();
|
| return Smi::FromInt(hash & Smi::kMaxValue);
|
| }
|
| + DCHECK(object->IsJSReceiver());
|
| + // Simply return the receiver as it is guaranteed to not be a SMI.
|
| + return object;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +Object* Object::GetHash() {
|
| + Object* hash = GetSimpleHash(this);
|
| + if (hash->IsSmi()) return hash;
|
| +
|
| + DisallowHeapAllocation no_gc;
|
| DCHECK(IsJSReceiver());
|
| JSReceiver* receiver = JSReceiver::cast(this);
|
| - return receiver->GetHeap()->undefined_value();
|
| + Isolate* isolate = receiver->GetIsolate();
|
| + return JSReceiver::GetIdentityHash(isolate, handle(receiver, isolate));
|
| }
|
|
|
| -
|
| -Handle<Smi> Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) {
|
| - Handle<Object> hash(object->GetSimpleHash(), isolate);
|
| - if (hash->IsSmi()) return Handle<Smi>::cast(hash);
|
| +Smi* Object::GetOrCreateHash(Isolate* isolate, Handle<Object> object) {
|
| + Object* hash = GetSimpleHash(*object);
|
| + if (hash->IsSmi()) return Smi::cast(hash);
|
|
|
| DCHECK(object->IsJSReceiver());
|
| - return JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver>::cast(object));
|
| + return JSReceiver::GetOrCreateIdentityHash(isolate,
|
| + Handle<JSReceiver>::cast(object));
|
| }
|
|
|
|
|
| @@ -5917,60 +5923,56 @@ static Smi* GenerateIdentityHash(Isolate* isolate) {
|
| return Smi::FromInt(hash_value);
|
| }
|
|
|
| +template <typename ProxyType>
|
| +static Smi* GetOrCreateIdentityHashHelper(Isolate* isolate,
|
| + Handle<ProxyType> proxy) {
|
| + Object* maybe_hash = proxy->hash();
|
| + if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash);
|
|
|
| -template<typename ProxyType>
|
| -static Handle<Smi> GetOrCreateIdentityHashHelper(Handle<ProxyType> proxy) {
|
| - Isolate* isolate = proxy->GetIsolate();
|
| -
|
| - Handle<Object> maybe_hash(proxy->hash(), isolate);
|
| - if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash);
|
| -
|
| - Handle<Smi> hash(GenerateIdentityHash(isolate), isolate);
|
| - proxy->set_hash(*hash);
|
| + Smi* hash = GenerateIdentityHash(isolate);
|
| + proxy->set_hash(hash);
|
| return hash;
|
| }
|
|
|
| // static
|
| -Handle<Object> JSObject::GetIdentityHash(Isolate* isolate,
|
| - Handle<JSObject> object) {
|
| +Object* JSObject::GetIdentityHash(Isolate* isolate, Handle<JSObject> object) {
|
| if (object->IsJSGlobalProxy()) {
|
| - return handle(JSGlobalProxy::cast(*object)->hash(), isolate);
|
| + return JSGlobalProxy::cast(*object)->hash();
|
| }
|
| Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol();
|
| - return JSReceiver::GetDataProperty(object, hash_code_symbol);
|
| + return *JSReceiver::GetDataProperty(object, hash_code_symbol);
|
| }
|
|
|
| // static
|
| -Handle<Smi> JSObject::GetOrCreateIdentityHash(Handle<JSObject> object) {
|
| +Smi* JSObject::GetOrCreateIdentityHash(Isolate* isolate,
|
| + Handle<JSObject> object) {
|
| if (object->IsJSGlobalProxy()) {
|
| - return GetOrCreateIdentityHashHelper(Handle<JSGlobalProxy>::cast(object));
|
| + return GetOrCreateIdentityHashHelper(isolate,
|
| + Handle<JSGlobalProxy>::cast(object));
|
| }
|
| - Isolate* isolate = object->GetIsolate();
|
|
|
| Handle<Name> hash_code_symbol = isolate->factory()->hash_code_symbol();
|
| LookupIterator it(object, hash_code_symbol, object, LookupIterator::OWN);
|
| if (it.IsFound()) {
|
| DCHECK_EQ(LookupIterator::DATA, it.state());
|
| - Handle<Object> maybe_hash = it.GetDataValue();
|
| - if (maybe_hash->IsSmi()) return Handle<Smi>::cast(maybe_hash);
|
| + Object* maybe_hash = *it.GetDataValue();
|
| + if (maybe_hash->IsSmi()) return Smi::cast(maybe_hash);
|
| }
|
|
|
| - Handle<Smi> hash(GenerateIdentityHash(isolate), isolate);
|
| - CHECK(AddDataProperty(&it, hash, NONE, THROW_ON_ERROR,
|
| + Smi* hash = GenerateIdentityHash(isolate);
|
| + CHECK(AddDataProperty(&it, handle(hash, isolate), NONE, THROW_ON_ERROR,
|
| CERTAINLY_NOT_STORE_FROM_KEYED)
|
| .IsJust());
|
| return hash;
|
| }
|
|
|
| // static
|
| -Handle<Object> JSProxy::GetIdentityHash(Isolate* isolate,
|
| - Handle<JSProxy> proxy) {
|
| - return handle(proxy->hash(), isolate);
|
| +Object* JSProxy::GetIdentityHash(Handle<JSProxy> proxy) {
|
| + return proxy->hash();
|
| }
|
|
|
| -
|
| -Handle<Smi> JSProxy::GetOrCreateIdentityHash(Handle<JSProxy> proxy) {
|
| - return GetOrCreateIdentityHashHelper(proxy);
|
| +Smi* JSProxy::GetOrCreateIdentityHash(Isolate* isolate, Handle<JSProxy> proxy) {
|
| + return GetOrCreateIdentityHashHelper(isolate, proxy);
|
| }
|
|
|
|
|
|
|