Commit e61f7277 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Rewriting SetOwnPropertyIgnoreAttributes using the LookupIterator

BUG=
R=jkummerow@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23163 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d0fc03b5
......@@ -126,6 +126,31 @@ void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
}
void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
PropertyAttributes attributes) {
DCHECK(has_property_);
DCHECK(HolderIsReceiverOrHiddenPrototype());
Handle<JSObject> holder = GetHolder<JSObject>();
if (property_encoding_ != DICTIONARY) {
holder_map_ = Map::ReconfigureDataProperty(holder_map_, descriptor_number(),
attributes);
JSObject::MigrateToMap(holder, holder_map_);
}
// Reload property information and update the descriptor if in dictionary
// mode.
if (holder_map_->is_dictionary_map()) {
property_encoding_ = DICTIONARY;
PropertyDetails details(attributes, NORMAL, 0);
JSObject::SetNormalizedProperty(holder, name(), value, details);
} else {
property_encoding_ = DESCRIPTOR;
}
CHECK(HasProperty());
}
void LookupIterator::TransitionToDataProperty(
Handle<Object> value, PropertyAttributes attributes,
Object::StoreFromKeyed store_mode) {
......@@ -136,10 +161,6 @@ void LookupIterator::TransitionToDataProperty(
// observable.
Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver());
// Properties have to be added to context extension objects through
// SetOwnPropertyIgnoreAttributes.
DCHECK(!receiver->IsJSContextExtensionObject());
if (receiver->IsJSGlobalProxy()) {
PrototypeIterator iter(isolate(), receiver);
receiver =
......@@ -162,6 +183,8 @@ void LookupIterator::TransitionToDataProperty(
bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
// Optimization that only works if configuration_ is not mutable.
if (!check_derived()) return true;
DisallowHeapAllocation no_gc;
Handle<Object> receiver = GetReceiver();
if (!receiver->IsJSReceiver()) return false;
......@@ -182,6 +205,16 @@ bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const {
}
bool LookupIterator::HolderIsNonGlobalHiddenPrototype() const {
if (!HolderIsReceiverOrHiddenPrototype()) return false;
Handle<Object> receiver = GetReceiver();
Handle<JSReceiver> holder = GetHolder<JSReceiver>();
if (receiver.is_identical_to(holder)) return false;
if (receiver->IsJSGlobalProxy()) return !holder->IsJSGlobalObject();
return true;
}
Handle<Object> LookupIterator::FetchValue() const {
Object* result = NULL;
Handle<JSObject> holder = GetHolder<JSObject>();
......
......@@ -20,10 +20,10 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
CHECK_DERIVED = 1 << 1,
CHECK_INTERCEPTOR = 1 << 2,
CHECK_ACCESS_CHECK = 1 << 3,
CHECK_ALL = CHECK_HIDDEN | CHECK_DERIVED |
CHECK_INTERCEPTOR | CHECK_ACCESS_CHECK,
SKIP_INTERCEPTOR = CHECK_ALL ^ CHECK_INTERCEPTOR,
CHECK_OWN = CHECK_ALL ^ CHECK_DERIVED
CHECK_HIDDEN_ACCESS = CHECK_HIDDEN | CHECK_ACCESS_CHECK,
SKIP_INTERCEPTOR = CHECK_HIDDEN_ACCESS | CHECK_DERIVED,
CHECK_ALL = SKIP_INTERCEPTOR | CHECK_INTERCEPTOR,
CHECK_OWN = CHECK_HIDDEN_ACCESS | CHECK_INTERCEPTOR
};
enum State {
......@@ -90,7 +90,7 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
Heap* heap() const { return isolate_->heap(); }
Factory* factory() const { return isolate_->factory(); }
Handle<Object> GetReceiver() const {
return Handle<Object>::cast(maybe_receiver_.ToHandleChecked());
return maybe_receiver_.ToHandleChecked();
}
Handle<Map> holder_map() const { return holder_map_; }
template <class T>
......@@ -100,16 +100,7 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
}
Handle<JSReceiver> GetRoot() const;
bool HolderIsReceiverOrHiddenPrototype() const;
/* Dynamically reduce the trapped types. */
void skip_interceptor() {
configuration_ = static_cast<Configuration>(
configuration_ & ~CHECK_INTERCEPTOR);
}
void skip_access_check() {
configuration_ = static_cast<Configuration>(
configuration_ & ~CHECK_ACCESS_CHECK);
}
bool HolderIsNonGlobalHiddenPrototype() const;
/* ACCESS_CHECK */
bool HasAccess(v8::AccessType access_type) const;
......@@ -123,6 +114,8 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
void TransitionToDataProperty(Handle<Object> value,
PropertyAttributes attributes,
Object::StoreFromKeyed store_mode);
void ReconfigureDataProperty(Handle<Object> value,
PropertyAttributes attributes);
PropertyKind property_kind() const {
DCHECK(has_property_);
return property_kind_;
......@@ -196,6 +189,8 @@ class LookupIterator V8_FINAL BASE_EMBEDDED {
}
}
// If configuration_ becomes mutable, update
// HolderIsReceiverOrHiddenPrototype.
Configuration configuration_;
State state_;
bool has_property_;
......
This diff is collapsed.
......@@ -247,6 +247,14 @@ enum PropertyNormalizationMode {
};
// Internal properties (e.g. the hidden properties dictionary) might
// be added even though the receiver is non-extensible.
enum ExtensibilityCheck {
PERFORM_EXTENSIBILITY_CHECK,
OMIT_EXTENSIBILITY_CHECK
};
// Indicates how aggressively the prototype should be optimized. FAST_PROTOTYPE
// will give the fastest result by tailoring the map to the prototype, but that
// will cause polymorphism with other objects. REGULAR_PROTOTYPE is to be used
......@@ -1492,7 +1500,8 @@ class Object {
LookupIterator* it, Handle<Object> value);
MUST_USE_RESULT static MaybeHandle<Object> AddDataProperty(
LookupIterator* it, Handle<Object> value, PropertyAttributes attributes,
StrictMode strict_mode, StoreFromKeyed store_mode);
StrictMode strict_mode, StoreFromKeyed store_mode,
ExtensibilityCheck check);
MUST_USE_RESULT static inline MaybeHandle<Object> GetPropertyOrElement(
Handle<Object> object,
Handle<Name> key);
......@@ -1936,13 +1945,6 @@ class JSReceiver: public HeapObject {
FORCE_DELETION
};
// Internal properties (e.g. the hidden properties dictionary) might
// be added even though the receiver is non-extensible.
enum ExtensibilityCheck {
PERFORM_EXTENSIBILITY_CHECK,
OMIT_EXTENSIBILITY_CHECK
};
DECLARE_CAST(JSReceiver)
MUST_USE_RESULT static MaybeHandle<Object> SetElement(
......@@ -2172,12 +2174,6 @@ class JSObject: public JSReceiver {
static Handle<Object> GetNormalizedProperty(Handle<JSObject> object,
const LookupResult* result);
// Sets the property value in a normalized object given a lookup result.
// Handles the special representation of JS global objects.
static void SetNormalizedProperty(Handle<JSObject> object,
const LookupResult* result,
Handle<Object> value);
// Sets the property value in a normalized object given (key, value, details).
// Handles the special representation of JS global objects.
static void SetNormalizedProperty(Handle<JSObject> object,
......@@ -2621,17 +2617,6 @@ class JSObject: public JSReceiver {
Handle<Map> new_map,
int expected_additional_properties);
static void SetPropertyToField(LookupResult* lookup, Handle<Object> value);
static void ConvertAndSetOwnProperty(LookupResult* lookup,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes);
static void SetPropertyToFieldWithAttributes(LookupResult* lookup,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes);
static void GeneralizeFieldRepresentation(Handle<JSObject> object,
int modify_index,
Representation new_representation,
......@@ -2705,29 +2690,9 @@ class JSObject: public JSReceiver {
StrictMode strict_mode,
bool check_prototype = true);
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyUsingTransition(
Handle<JSObject> object,
LookupResult* lookup,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes);
MUST_USE_RESULT static MaybeHandle<Object> SetPropertyWithFailedAccessCheck(
LookupIterator* it, Handle<Object> value, StrictMode strict_mode);
// Add a property to an object.
MUST_USE_RESULT static MaybeHandle<Object> AddPropertyInternal(
Handle<JSObject> object, Handle<Name> name, Handle<Object> value,
PropertyAttributes attributes, StoreFromKeyed store_mode,
ExtensibilityCheck extensibility_check, TransitionFlag flag);
// Add a property to a fast-case object.
static void AddFastProperty(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
StoreFromKeyed store_mode,
TransitionFlag flag);
// Add a property to a slow-case object.
static void AddSlowProperty(Handle<JSObject> object,
Handle<Name> name,
......@@ -6517,6 +6482,8 @@ class Map: public HeapObject {
Handle<Object> value,
PropertyAttributes attributes,
StoreFromKeyed store_mode);
static Handle<Map> ReconfigureDataProperty(Handle<Map> map, int descriptor,
PropertyAttributes attributes);
inline void AppendDescriptor(Descriptor* desc);
......
......@@ -5041,10 +5041,8 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyUnchecked) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
JSObject::SetOwnPropertyIgnoreAttributes(
js_object, name, obj_value, attr,
JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
JSReceiver::MAY_BE_STORE_FROM_KEYED,
JSObject::DONT_FORCE_FIELD));
js_object, name, obj_value, attr, PERFORM_EXTENSIBILITY_CHECK,
JSReceiver::MAY_BE_STORE_FROM_KEYED, JSObject::DONT_FORCE_FIELD));
return *result;
}
......@@ -5198,7 +5196,7 @@ MaybeHandle<Object> Runtime::DefineObjectProperty(
} else {
if (name->IsString()) name = String::Flatten(Handle<String>::cast(name));
return JSObject::SetOwnPropertyIgnoreAttributes(
js_object, name, value, attr, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
js_object, name, value, attr, PERFORM_EXTENSIBILITY_CHECK,
store_from_keyed);
}
}
......@@ -5214,7 +5212,7 @@ MaybeHandle<Object> Runtime::DefineObjectProperty(
SLOPPY, false, DEFINE_PROPERTY);
} else {
return JSObject::SetOwnPropertyIgnoreAttributes(
js_object, name, value, attr, JSReceiver::PERFORM_EXTENSIBILITY_CHECK,
js_object, name, value, attr, PERFORM_EXTENSIBILITY_CHECK,
store_from_keyed);
}
}
......
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