Commit 8e31371d authored by lrn@chromium.org's avatar lrn@chromium.org

Move logic for hidden properties into the JSObject.

Previously, the logic using the hidden properties backing object was
spread accross use sites. Now it's all contained in JSObject, with
only simple accessors available.
Also change the backing object to be a StringDictionary rather than a JSObject.
There's still room for improvement by making a hash-table that don't
store property details as well.

Review URL: http://codereview.chromium.org/8050013

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9510 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 4750f0c3
......@@ -3210,21 +3210,10 @@ bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> hidden_props(i::GetHiddenProperties(
self,
i::ALLOW_CREATION));
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj = i::SetProperty(
hidden_props,
key_obj,
value_obj,
static_cast<PropertyAttributes>(None),
i::kNonStrictMode);
has_pending_exception = obj.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, false);
return true;
i::Handle<i::Object> result = i::SetHiddenProperty(self, key_obj, value_obj);
return *result == *self;
}
......@@ -3234,20 +3223,9 @@ v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
return Local<v8::Value>());
ENTER_V8(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> hidden_props(i::GetHiddenProperties(
self,
i::OMIT_CREATION));
if (hidden_props->IsUndefined()) {
return v8::Local<v8::Value>();
}
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> result = i::GetProperty(hidden_props, key_obj);
has_pending_exception = result.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, v8::Local<v8::Value>());
if (result->IsUndefined()) {
return v8::Local<v8::Value>();
}
i::Handle<i::Object> result(self->GetHiddenProperty(*key_obj));
if (result->IsUndefined()) return v8::Local<v8::Value>();
return Utils::ToLocal(result);
}
......@@ -3258,15 +3236,9 @@ bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> hidden_props(i::GetHiddenProperties(
self,
i::OMIT_CREATION));
if (hidden_props->IsUndefined()) {
return true;
}
i::Handle<i::JSObject> js_obj(i::JSObject::cast(*hidden_props));
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
return i::DeleteProperty(js_obj, key_obj)->IsTrue();
self->DeleteHiddenProperty(*key_obj);
return true;
}
......
......@@ -421,9 +421,11 @@ Handle<Object> PreventExtensions(Handle<JSObject> object) {
}
Handle<Object> GetHiddenProperties(Handle<JSObject> obj, CreationFlag flag) {
Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
Handle<String> key,
Handle<Object> value) {
CALL_HEAP_FUNCTION(obj->GetIsolate(),
obj->GetHiddenProperties(flag),
obj->SetHiddenProperty(*key, *value),
Object);
}
......
......@@ -265,11 +265,11 @@ Handle<Object> GetPrototype(Handle<Object> obj);
Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value);
// Return the object's hidden properties object. If the object has no hidden
// properties and HiddenPropertiesFlag::ALLOW_CREATION is passed, then a new
// hidden property object will be allocated. Otherwise Heap::undefined_value
// is returned.
Handle<Object> GetHiddenProperties(Handle<JSObject> obj, CreationFlag flag);
// Sets a hidden property on an object. Returns obj on success, undefined
// if trying to set the property on a detached proxy.
Handle<Object> SetHiddenProperty(Handle<JSObject> obj,
Handle<String> key,
Handle<Object> value);
int GetIdentityHash(Handle<JSReceiver> obj);
......
......@@ -4347,42 +4347,6 @@ MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
}
bool JSObject::HasHiddenPropertiesObject() {
ASSERT(!IsJSGlobalProxy());
return GetPropertyAttributePostInterceptor(this,
GetHeap()->hidden_symbol(),
false) != ABSENT;
}
Object* JSObject::GetHiddenPropertiesObject() {
ASSERT(!IsJSGlobalProxy());
PropertyAttributes attributes;
// You can't install a getter on a property indexed by the hidden symbol,
// so we can be sure that GetLocalPropertyPostInterceptor returns a real
// object.
Object* result =
GetLocalPropertyPostInterceptor(this,
GetHeap()->hidden_symbol(),
&attributes)->ToObjectUnchecked();
return result;
}
MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ASSERT(!IsJSGlobalProxy());
return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
hidden_obj,
DONT_ENUM,
kNonStrictMode);
}
bool JSObject::HasHiddenProperties() {
return !GetHiddenProperties(OMIT_CREATION)->ToObjectChecked()->IsUndefined();
}
bool JSReceiver::HasElement(uint32_t index) {
if (IsJSProxy()) {
return JSProxy::cast(this)->HasElementWithHandler(index);
......
This diff is collapsed.
......@@ -1577,27 +1577,25 @@ class JSObject: public JSReceiver {
// Accessors for hidden properties object.
//
// Hidden properties are not local properties of the object itself.
// Instead they are stored on an auxiliary JSObject stored as a local
// Instead they are stored in an auxiliary structure kept as a local
// property with a special name Heap::hidden_symbol(). But if the
// receiver is a JSGlobalProxy then the auxiliary object is a property
// of its prototype.
//
// Has/Get/SetHiddenPropertiesObject methods don't allow the holder to be
// a JSGlobalProxy. Use BypassGlobalProxy method above to get to the real
// holder.
//
// These accessors do not touch interceptors or accessors.
inline bool HasHiddenPropertiesObject();
inline Object* GetHiddenPropertiesObject();
MUST_USE_RESULT inline MaybeObject* SetHiddenPropertiesObject(
Object* hidden_obj);
// Retrieves the hidden properties object.
//
// The undefined value might be returned in case no hidden properties object
// is present and creation was omitted.
inline bool HasHiddenProperties();
MUST_USE_RESULT MaybeObject* GetHiddenProperties(CreationFlag flag);
// of its prototype, and if it's a detached proxy, then you can't have
// hidden properties.
// Sets a hidden property on this object. Returns this object if successful,
// undefined if called on a detached proxy, and a failure if a GC
// is required
MaybeObject* SetHiddenProperty(String* key, Object* value);
// Gets the value of a hidden property with the given key. Returns undefined
// if the property doesn't exist (or if called on a detached proxy),
// otherwise returns the value set for the key.
Object* GetHiddenProperty(String* key);
// Deletes a hidden property. Deleting a non-existing property is
// considered successful.
void DeleteHiddenProperty(String* key);
// Returns true if the object has a property with the hidden symbol as name.
bool HasHiddenProperties();
MUST_USE_RESULT MaybeObject* GetIdentityHash(CreationFlag flag);
MUST_USE_RESULT MaybeObject* SetIdentityHash(Object* hash, CreationFlag flag);
......@@ -2038,6 +2036,15 @@ class JSObject: public JSReceiver {
void LookupInDescriptor(String* name, LookupResult* result);
// Returns the hidden properties backing store object, currently
// a StringDictionary, stored on this object.
// If no hidden properties object has been put on this object,
// return undefined, unless create_if_absent is true, in which case
// a new dictionary is created, added to this object, and returned.
MaybeObject* GetHiddenPropertiesDictionary(bool create_if_absent);
// Updates the existing hidden properties dictionary.
MaybeObject* SetHiddenPropertiesDictionary(StringDictionary* dictionary);
DISALLOW_IMPLICIT_CONSTRUCTORS(JSObject);
};
......@@ -2863,7 +2870,7 @@ class StringDictionary: public Dictionary<StringDictionaryShape, String*> {
JSObject* obj,
int unused_property_fields);
// Find entry for key otherwise return kNotFound. Optimzed version of
// Find entry for key, otherwise return kNotFound. Optimized version of
// HashTable::FindEntry.
int FindEntry(String* key);
};
......
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