Commit ada13dfc authored by rafaelw@chromium.org's avatar rafaelw@chromium.org

Remove calls to JSObject::SetLocalPropertyIgnoreAttributesTrampoline within objects.cc

This includes handlifing:
-SetHiddenPropertiesHashTable
-ObjectHashSet::Add/Remove
-ObjectHashTable::Put

And splitting the following methods which previously took "allow creation" enum arguments to into side-effect-free getters and GetOrCreate*-handlfied getters.

-GetHash (now GetHash & handlified GetOrCreateHash)
-GetIdentityHash (now GetIdentityHash & handlified GetOrCreateIdentityHash)
-GetHiddenPropertiesHashTable (now GetHiddenPropertiesHashTable & handlified GetOrCreateaHiddenPropertiesHashTable)

BUG=v8:2877
R=mstarzinger@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17477 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 4a8319c7
......@@ -3689,7 +3689,8 @@ int v8::Object::GetIdentityHash() {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
return i::JSObject::GetIdentityHash(self);
return i::Handle<i::Smi>::cast(
i::JSReceiver::GetOrCreateIdentityHash(self))->value();
}
......
......@@ -132,11 +132,14 @@ Handle<ObjectHashSet> Factory::NewObjectHashSet(int at_least_space_for) {
}
Handle<ObjectHashTable> Factory::NewObjectHashTable(int at_least_space_for) {
Handle<ObjectHashTable> Factory::NewObjectHashTable(
int at_least_space_for,
MinimumCapacity capacity_option) {
ASSERT(0 <= at_least_space_for);
CALL_HEAP_FUNCTION(isolate(),
ObjectHashTable::Allocate(isolate()->heap(),
at_least_space_for),
at_least_space_for,
capacity_option),
ObjectHashTable);
}
......@@ -147,7 +150,7 @@ Handle<WeakHashTable> Factory::NewWeakHashTable(int at_least_space_for) {
isolate(),
WeakHashTable::Allocate(isolate()->heap(),
at_least_space_for,
WeakHashTable::USE_DEFAULT_MINIMUM_CAPACITY,
USE_DEFAULT_MINIMUM_CAPACITY,
TENURED),
WeakHashTable);
}
......
......@@ -74,7 +74,9 @@ class Factory {
Handle<ObjectHashSet> NewObjectHashSet(int at_least_space_for);
Handle<ObjectHashTable> NewObjectHashTable(int at_least_space_for);
Handle<ObjectHashTable> NewObjectHashTable(
int at_least_space_for,
MinimumCapacity capacity_option = USE_DEFAULT_MINIMUM_CAPACITY);
Handle<WeakHashTable> NewWeakHashTable(int at_least_space_for);
......
......@@ -767,31 +767,6 @@ Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
}
Handle<ObjectHashSet> ObjectHashSetAdd(Handle<ObjectHashSet> table,
Handle<Object> key) {
CALL_HEAP_FUNCTION(table->GetIsolate(),
table->Add(*key),
ObjectHashSet);
}
Handle<ObjectHashSet> ObjectHashSetRemove(Handle<ObjectHashSet> table,
Handle<Object> key) {
CALL_HEAP_FUNCTION(table->GetIsolate(),
table->Remove(*key),
ObjectHashSet);
}
Handle<ObjectHashTable> PutIntoObjectHashTable(Handle<ObjectHashTable> table,
Handle<Object> key,
Handle<Object> value) {
CALL_HEAP_FUNCTION(table->GetIsolate(),
table->Put(*key, *value),
ObjectHashTable);
}
DeferredHandleScope::DeferredHandleScope(Isolate* isolate)
: impl_(isolate->handle_scope_implementer()) {
impl_->BeginDeferredScope();
......
......@@ -303,16 +303,6 @@ Handle<JSGlobalProxy> ReinitializeJSGlobalProxy(
Handle<JSFunction> constructor,
Handle<JSGlobalProxy> global);
Handle<ObjectHashSet> ObjectHashSetAdd(Handle<ObjectHashSet> table,
Handle<Object> key);
Handle<ObjectHashSet> ObjectHashSetRemove(Handle<ObjectHashSet> table,
Handle<Object> key);
Handle<ObjectHashTable> PutIntoObjectHashTable(Handle<ObjectHashTable> table,
Handle<Object> key,
Handle<Object> value);
void AddWeakObjectToCodeDependency(Heap* heap,
Handle<Object> object,
Handle<Code> code);
......
......@@ -5851,10 +5851,17 @@ Object* JSObject::BypassGlobalProxy() {
}
MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
Handle<Object> JSReceiver::GetOrCreateIdentityHash(Handle<JSReceiver> object) {
return object->IsJSProxy()
? JSProxy::GetOrCreateIdentityHash(Handle<JSProxy>::cast(object))
: JSObject::GetOrCreateIdentityHash(Handle<JSObject>::cast(object));
}
Object* JSReceiver::GetIdentityHash() {
return IsJSProxy()
? JSProxy::cast(this)->GetIdentityHash(flag)
: JSObject::cast(this)->GetIdentityHash(flag);
? JSProxy::cast(this)->GetIdentityHash()
: JSObject::cast(this)->GetIdentityHash();
}
......@@ -6054,16 +6061,14 @@ bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
template <int entrysize>
uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
return Smi::cast(maybe_hash->ToObjectChecked())->value();
return Smi::cast(key->GetHash())->value();
}
template <int entrysize>
uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
Object* other) {
MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
return Smi::cast(maybe_hash->ToObjectChecked())->value();
return Smi::cast(other->GetHash())->value();
}
......
This diff is collapsed.
......@@ -255,13 +255,6 @@ enum NormalizedMapSharingMode {
};
// Indicates whether a get method should implicitly create the object looked up.
enum CreationFlag {
ALLOW_CREATION,
OMIT_CREATION
};
// Indicates whether transitions can be added to a source map or not.
enum TransitionFlag {
INSERT_TRANSITION,
......@@ -1509,10 +1502,17 @@ class Object : public MaybeObject {
// Return the object's prototype (might be Heap::null_value()).
Object* GetPrototype(Isolate* isolate);
// Returns the permanent hash code associated with this object. May return
// undefined if not yet created.
Object* GetHash();
// Returns the permanent hash code associated with this object depending on
// the actual object type. Might return a failure in case no hash was
// created yet or GC was caused by creation.
MUST_USE_RESULT MaybeObject* GetHash(CreationFlag flag);
// the actual object type. May create and store a hash code if needed and none
// exists.
// TODO(rafaelw): Remove isolate parameter when objects.cc is fully
// handlified.
static Handle<Object> GetOrCreateHash(Handle<Object> object,
Isolate* isolate);
// Checks whether this object has the same value as the given one. This
// function is implemented according to ES5, section 9.12 and can be used
......@@ -2003,8 +2003,13 @@ class JSReceiver: public HeapObject {
inline Object* GetConstructor();
// Retrieves a permanent object identity hash code. The undefined value might
// be returned in case no hash was created yet and OMIT_CREATION was used.
inline MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
// be returned in case no hash was created yet.
inline Object* GetIdentityHash();
// Retrieves a permanent object identity hash code. May create and store a
// hash code if needed and none exists.
inline static Handle<Object> GetOrCreateIdentityHash(
Handle<JSReceiver> object);
// Lookup a property. If found, the result is valid and has
// detailed information.
......@@ -2036,6 +2041,9 @@ class JSReceiver: public HeapObject {
DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
};
// Forward declaration for JSObject::GetOrCreateHiddenPropertiesHashTable.
class ObjectHashTable;
// The JSObject describes real heap allocated JavaScript objects with
// properties.
// Note that the map of JSObject changes during execution to enable inline
......@@ -2287,11 +2295,9 @@ class JSObject: public JSReceiver {
// Sets a hidden property on this object. Returns this object if successful,
// undefined if called on a detached proxy.
static Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
static Handle<Object> SetHiddenProperty(Handle<JSObject> object,
Handle<Name> key,
Handle<Object> value);
// Returns a failure if a GC is required.
MUST_USE_RESULT MaybeObject* SetHiddenProperty(Name* key, Object* value);
// Gets the value of a hidden property with the given key. Returns the hole
// if the property doesn't exist (or if called on a detached proxy),
// otherwise returns the value set for the key.
......@@ -2303,8 +2309,7 @@ class JSObject: public JSReceiver {
// Returns true if the object has a property with the hidden string as name.
bool HasHiddenProperties();
static int GetIdentityHash(Handle<JSObject> object);
static void SetIdentityHash(Handle<JSObject> object, Smi* hash);
static void SetIdentityHash(Handle<JSObject> object, Handle<Smi> hash);
inline void ValidateElements();
......@@ -2858,23 +2863,25 @@ class JSObject: public JSReceiver {
Handle<Object> accessor,
PropertyAttributes attributes);
enum InitializeHiddenProperties {
CREATE_NEW_IF_ABSENT,
ONLY_RETURN_INLINE_VALUE
};
// If create_if_absent is true, return the hash table backing store
// for hidden properties. If there is no backing store, allocate one.
// If create_if_absent is false, return the hash table backing store
// or the inline stored identity hash, whatever is found.
MUST_USE_RESULT MaybeObject* GetHiddenPropertiesHashTable(
InitializeHiddenProperties init_option);
// Return the hash table backing store or the inline stored identity hash,
// whatever is found.
MUST_USE_RESULT Object* GetHiddenPropertiesHashTable();
// Return the hash table backing store for hidden properties. If there is no
// backing store, allocate one.
static Handle<ObjectHashTable> GetOrCreateHiddenPropertiesHashtable(
Handle<JSObject> object);
// Set the hidden property backing store to either a hash table or
// the inline-stored identity hash.
MUST_USE_RESULT MaybeObject* SetHiddenPropertiesHashTable(
Object* value);
static Handle<Object> SetHiddenPropertiesHashTable(
Handle<JSObject> object,
Handle<Object> value);
MUST_USE_RESULT Object* GetIdentityHash();
MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
static Handle<Object> GetOrCreateIdentityHash(Handle<JSObject> object);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
};
......@@ -3484,11 +3491,6 @@ class BaseShape {
template<typename Shape, typename Key>
class HashTable: public FixedArray {
public:
enum MinimumCapacity {
USE_DEFAULT_MINIMUM_CAPACITY,
USE_CUSTOM_MINIMUM_CAPACITY
};
// Wrapper methods
inline uint32_t Hash(Key key) {
if (Shape::UsesSeed) {
......@@ -3599,6 +3601,9 @@ class HashTable: public FixedArray {
void Rehash(Key key);
protected:
friend class ObjectHashSet;
friend class ObjectHashTable;
// Find the entry at which to insert element with the given key that
// has the given hash value.
uint32_t FindInsertionEntry(uint32_t hash);
......@@ -4062,11 +4067,23 @@ class ObjectHashSet: public HashTable<ObjectHashTableShape<1>, Object*> {
// Looks up whether the given key is part of this hash set.
bool Contains(Object* key);
static Handle<ObjectHashSet> EnsureCapacity(
Handle<ObjectHashSet> table,
int n,
Handle<Object> key,
PretenureFlag pretenure = NOT_TENURED);
// Attempt to shrink hash table after removal of key.
static Handle<ObjectHashSet> Shrink(Handle<ObjectHashSet> table,
Handle<Object> key);
// Adds the given key to this hash set.
MUST_USE_RESULT MaybeObject* Add(Object* key);
static Handle<ObjectHashSet> Add(Handle<ObjectHashSet> table,
Handle<Object> key);
// Removes the given key from this hash set.
MUST_USE_RESULT MaybeObject* Remove(Object* key);
static Handle<ObjectHashSet> Remove(Handle<ObjectHashSet> table,
Handle<Object> key);
};
......@@ -4079,13 +4096,25 @@ class ObjectHashTable: public HashTable<ObjectHashTableShape<2>, Object*> {
return reinterpret_cast<ObjectHashTable*>(obj);
}
static Handle<ObjectHashTable> EnsureCapacity(
Handle<ObjectHashTable> table,
int n,
Handle<Object> key,
PretenureFlag pretenure = NOT_TENURED);
// Attempt to shrink hash table after removal of key.
static Handle<ObjectHashTable> Shrink(Handle<ObjectHashTable> table,
Handle<Object> key);
// Looks up the value associated with the given key. The hole value is
// returned in case the key is not present.
Object* Lookup(Object* key);
// Adds (or overwrites) the value associated with the given key. Mapping a
// key to the hole value causes removal of the whole entry.
MUST_USE_RESULT MaybeObject* Put(Object* key, Object* value);
static Handle<ObjectHashTable> Put(Handle<ObjectHashTable> table,
Handle<Object> key,
Handle<Object> value);
private:
friend class MarkCompactCollector;
......@@ -9368,9 +9397,9 @@ class JSProxy: public JSReceiver {
uint32_t index,
DeleteMode mode);
MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
static Handle<Object> GetIdentityHash(Handle<JSProxy> proxy,
CreationFlag flag);
MUST_USE_RESULT Object* GetIdentityHash();
static Handle<Object> GetOrCreateIdentityHash(Handle<JSProxy> proxy);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSProxy);
};
......
......@@ -1387,7 +1387,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetAdd) {
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<Object> key(args[1], isolate);
Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
table = ObjectHashSetAdd(table, key);
table = ObjectHashSet::Add(table, key);
holder->set_table(*table);
return isolate->heap()->undefined_value();
}
......@@ -1409,7 +1409,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SetDelete) {
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<Object> key(args[1], isolate);
Handle<ObjectHashSet> table(ObjectHashSet::cast(holder->table()));
table = ObjectHashSetRemove(table, key);
table = ObjectHashSet::Remove(table, key);
holder->set_table(*table);
return isolate->heap()->undefined_value();
}
......@@ -1464,7 +1464,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapDelete) {
Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
Handle<Object> lookup(table->Lookup(*key), isolate);
Handle<ObjectHashTable> new_table =
PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value());
holder->set_table(*new_table);
return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
......@@ -1477,7 +1477,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapSet) {
CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
Handle<ObjectHashTable> table(ObjectHashTable::cast(holder->table()));
Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
holder->set_table(*new_table);
return isolate->heap()->undefined_value();
}
......@@ -1543,7 +1543,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionDelete) {
weak_collection->table()));
Handle<Object> lookup(table->Lookup(*key), isolate);
Handle<ObjectHashTable> new_table =
PutIntoObjectHashTable(table, key, isolate->factory()->the_hole_value());
ObjectHashTable::Put(table, key, isolate->factory()->the_hole_value());
weak_collection->set_table(*new_table);
return isolate->heap()->ToBoolean(!lookup->IsTheHole());
}
......@@ -1557,7 +1557,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakCollectionSet) {
Handle<Object> value(args[2], isolate);
Handle<ObjectHashTable> table(
ObjectHashTable::cast(weak_collection->table()));
Handle<ObjectHashTable> new_table = PutIntoObjectHashTable(table, key, value);
Handle<ObjectHashTable> new_table = ObjectHashTable::Put(table, key, value);
weak_collection->set_table(*new_table);
return isolate->heap()->undefined_value();
}
......
......@@ -199,6 +199,11 @@ const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
// allows).
enum PretenureFlag { NOT_TENURED, TENURED };
enum MinimumCapacity {
USE_DEFAULT_MINIMUM_CAPACITY,
USE_CUSTOM_MINIMUM_CAPACITY
};
enum GarbageCollector { SCAVENGER, MARK_COMPACTOR };
enum Executability { NOT_EXECUTABLE, EXECUTABLE };
......
......@@ -47,7 +47,7 @@ TEST(ObjectHashTable) {
Handle<ObjectHashTable> table = factory->NewObjectHashTable(23);
Handle<JSObject> a = factory->NewJSArray(7);
Handle<JSObject> b = factory->NewJSArray(11);
table = PutIntoObjectHashTable(table, a, b);
table = ObjectHashTable::Put(table, a, b);
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_EQ(table->Lookup(*a), *b);
CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value());
......@@ -59,12 +59,12 @@ TEST(ObjectHashTable) {
CHECK_EQ(table->Lookup(*b), CcTest::heap()->the_hole_value());
// Keys that are overwritten should not change number of elements.
table = PutIntoObjectHashTable(table, a, factory->NewJSArray(13));
table = ObjectHashTable::Put(table, a, factory->NewJSArray(13));
CHECK_EQ(table->NumberOfElements(), 1);
CHECK_NE(table->Lookup(*a), *b);
// Keys mapped to the hole should be removed permanently.
table = PutIntoObjectHashTable(table, a, factory->the_hole_value());
table = ObjectHashTable::Put(table, a, factory->the_hole_value());
CHECK_EQ(table->NumberOfElements(), 0);
CHECK_EQ(table->NumberOfDeletedElements(), 1);
CHECK_EQ(table->Lookup(*a), CcTest::heap()->the_hole_value());
......@@ -74,21 +74,21 @@ TEST(ObjectHashTable) {
for (int i = 0; i < 100; i++) {
Handle<JSReceiver> key = factory->NewJSArray(7);
Handle<JSObject> value = factory->NewJSArray(11);
table = PutIntoObjectHashTable(table, key, value);
table = ObjectHashTable::Put(table, key, value);
CHECK_EQ(table->NumberOfElements(), i + 1);
CHECK_NE(table->FindEntry(*key), ObjectHashTable::kNotFound);
CHECK_EQ(table->Lookup(*key), *value);
CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi());
CHECK(key->GetIdentityHash()->IsSmi());
}
// Keys never added to the map which already have an identity hash
// code should not be found.
for (int i = 0; i < 100; i++) {
Handle<JSReceiver> key = factory->NewJSArray(7);
CHECK(key->GetIdentityHash(ALLOW_CREATION)->ToObjectChecked()->IsSmi());
CHECK(JSReceiver::GetOrCreateIdentityHash(key)->IsSmi());
CHECK_EQ(table->FindEntry(*key), ObjectHashTable::kNotFound);
CHECK_EQ(table->Lookup(*key), CcTest::heap()->the_hole_value());
CHECK(key->GetIdentityHash(OMIT_CREATION)->ToObjectChecked()->IsSmi());
CHECK(key->GetIdentityHash()->IsSmi());
}
// Keys that don't have an identity hash should not be found and also
......@@ -96,7 +96,7 @@ TEST(ObjectHashTable) {
for (int i = 0; i < 100; i++) {
Handle<JSReceiver> key = factory->NewJSArray(7);
CHECK_EQ(table->Lookup(*key), CcTest::heap()->the_hole_value());
CHECK_EQ(key->GetIdentityHash(OMIT_CREATION),
CHECK_EQ(key->GetIdentityHash(),
CcTest::heap()->undefined_value());
}
}
......@@ -175,13 +175,17 @@ TEST(ObjectHashSetCausesGC) {
SimulateFullSpace(CcTest::heap()->old_pointer_space());
// Calling Contains() should not cause GC ever.
int gc_count = isolate->heap()->gc_count();
CHECK(!table->Contains(*key));
CHECK(gc_count == isolate->heap()->gc_count());
// Calling Remove() should not cause GC ever.
CHECK(!table->Remove(*key)->IsFailure());
// Calling Remove() will not cause GC in this case.
table = ObjectHashSet::Remove(table, key);
CHECK(gc_count == isolate->heap()->gc_count());
// Calling Add() should request GC by returning a failure.
CHECK(table->Add(*key)->IsRetryAfterGC());
// Calling Add() should cause GC.
table = ObjectHashSet::Add(table, key);
CHECK(gc_count < isolate->heap()->gc_count());
}
#endif
......@@ -211,6 +215,8 @@ TEST(ObjectHashTableCausesGC) {
CHECK(table->Lookup(*key)->IsTheHole());
// Calling Put() should request GC by returning a failure.
CHECK(table->Put(*key, *key)->IsRetryAfterGC());
int gc_count = isolate->heap()->gc_count();
ObjectHashTable::Put(table, key, key);
CHECK(gc_count < isolate->heap()->gc_count());
}
#endif
......@@ -2759,7 +2759,7 @@ TEST(Regress2211) {
// In the first iteration, set hidden value first and identity hash second.
// In the second iteration, reverse the order.
if (i == 0) obj->SetHiddenValue(v8_str("key string"), value);
JSObject::SetIdentityHash(internal_obj, hash);
JSObject::SetIdentityHash(internal_obj, handle(hash, CcTest::i_isolate()));
if (i == 1) obj->SetHiddenValue(v8_str("key string"), value);
// Check values.
......
......@@ -56,7 +56,7 @@ static Handle<JSWeakMap> AllocateJSWeakMap(Isolate* isolate) {
static void PutIntoWeakMap(Handle<JSWeakMap> weakmap,
Handle<JSObject> key,
Handle<Object> value) {
Handle<ObjectHashTable> table = PutIntoObjectHashTable(
Handle<ObjectHashTable> table = ObjectHashTable::Put(
Handle<ObjectHashTable>(ObjectHashTable::cast(weakmap->table())),
Handle<JSObject>(JSObject::cast(*key)),
value);
......
......@@ -56,7 +56,7 @@ static Handle<JSWeakSet> AllocateJSWeakSet(Isolate* isolate) {
static void PutIntoWeakSet(Handle<JSWeakSet> weakset,
Handle<JSObject> key,
Handle<Object> value) {
Handle<ObjectHashTable> table = PutIntoObjectHashTable(
Handle<ObjectHashTable> table = ObjectHashTable::Put(
Handle<ObjectHashTable>(ObjectHashTable::cast(weakset->table())),
Handle<JSObject>(JSObject::cast(*key)),
value);
......
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