Revert "Handlify JSObject::AddProperty method" for performance.

TBR=verwaest@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16655 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6790b837
...@@ -1900,20 +1900,6 @@ MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, ...@@ -1900,20 +1900,6 @@ MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
} }
void JSObject::AddFastProperty(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
StoreFromKeyed store_mode,
ValueType value_type,
TransitionFlag flag) {
CALL_HEAP_FUNCTION_VOID(
object->GetIsolate(),
object->AddFastProperty(
*name, *value, attributes, store_mode, value_type, flag));
}
MaybeObject* JSObject::AddFastProperty(Name* name, MaybeObject* JSObject::AddFastProperty(Name* name,
Object* value, Object* value,
PropertyAttributes attributes, PropertyAttributes attributes,
...@@ -1959,17 +1945,6 @@ MaybeObject* JSObject::AddFastProperty(Name* name, ...@@ -1959,17 +1945,6 @@ MaybeObject* JSObject::AddFastProperty(Name* name,
} }
void JSObject::AddConstantProperty(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> constant,
PropertyAttributes attributes,
TransitionFlag flag) {
CALL_HEAP_FUNCTION_VOID(
object->GetIsolate(),
object->AddConstantProperty(*name, *constant, attributes, flag));
}
MaybeObject* JSObject::AddConstantProperty( MaybeObject* JSObject::AddConstantProperty(
Name* name, Name* name,
Object* constant, Object* constant,
...@@ -1996,15 +1971,7 @@ MaybeObject* JSObject::AddConstantProperty( ...@@ -1996,15 +1971,7 @@ MaybeObject* JSObject::AddConstantProperty(
} }
void JSObject::AddSlowProperty(Handle<JSObject> object, // Add property in slow mode
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes) {
CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
object->AddSlowProperty(*name, *value, attributes));
}
MaybeObject* JSObject::AddSlowProperty(Name* name, MaybeObject* JSObject::AddSlowProperty(Name* name,
Object* value, Object* value,
PropertyAttributes attributes) { PropertyAttributes attributes) {
...@@ -2046,61 +2013,69 @@ MaybeObject* JSObject::AddSlowProperty(Name* name, ...@@ -2046,61 +2013,69 @@ MaybeObject* JSObject::AddSlowProperty(Name* name,
} }
Handle<Object> JSObject::AddProperty(Handle<JSObject> object, MaybeObject* JSObject::AddProperty(Name* name,
Handle<Name> name, Object* value,
Handle<Object> value, PropertyAttributes attributes,
PropertyAttributes attributes, StrictModeFlag strict_mode,
StrictModeFlag strict_mode, JSReceiver::StoreFromKeyed store_mode,
JSReceiver::StoreFromKeyed store_mode, ExtensibilityCheck extensibility_check,
ExtensibilityCheck extensibility_check, ValueType value_type,
ValueType value_type, StoreMode mode,
StoreMode mode, TransitionFlag transition_flag) {
TransitionFlag transition_flag) { ASSERT(!IsJSGlobalProxy());
ASSERT(!object->IsJSGlobalProxy()); Map* map_of_this = map();
Isolate* isolate = object->GetIsolate(); Heap* heap = GetHeap();
Isolate* isolate = heap->isolate();
MaybeObject* result;
if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK &&
!object->map()->is_extensible()) { !map_of_this->is_extensible()) {
if (strict_mode == kNonStrictMode) { if (strict_mode == kNonStrictMode) {
return value; return value;
} else { } else {
Handle<Object> args[1] = { name }; Handle<Object> args[1] = {Handle<Name>(name)};
Handle<Object> error = isolate->factory()->NewTypeError( return isolate->Throw(
"object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); *isolate->factory()->NewTypeError("object_not_extensible",
isolate->Throw(*error); HandleVector(args, 1)));
return Handle<Object>();
} }
} }
if (object->HasFastProperties()) { if (HasFastProperties()) {
// Ensure the descriptor array does not get too big. // Ensure the descriptor array does not get too big.
if (object->map()->NumberOfOwnDescriptors() < if (map_of_this->NumberOfOwnDescriptors() <
DescriptorArray::kMaxNumberOfDescriptors) { DescriptorArray::kMaxNumberOfDescriptors) {
// TODO(verwaest): Support other constants. // TODO(verwaest): Support other constants.
// if (mode == ALLOW_AS_CONSTANT && // if (mode == ALLOW_AS_CONSTANT &&
// !value->IsTheHole() && // !value->IsTheHole() &&
// !value->IsConsString()) { // !value->IsConsString()) {
if (value->IsJSFunction()) { if (value->IsJSFunction()) {
AddConstantProperty(object, name, value, attributes, transition_flag); result = AddConstantProperty(name, value, attributes, transition_flag);
} else { } else {
AddFastProperty(object, name, value, attributes, store_mode, result = AddFastProperty(
value_type, transition_flag); name, value, attributes, store_mode, value_type, transition_flag);
} }
} else { } else {
// Normalize the object to prevent very large instance descriptors. // Normalize the object to prevent very large instance descriptors.
// This eliminates unwanted N^2 allocation and lookup behavior. // This eliminates unwanted N^2 allocation and lookup behavior.
NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); Object* obj;
AddSlowProperty(object, name, value, attributes); MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0);
if (!maybe->To(&obj)) return maybe;
result = AddSlowProperty(name, value, attributes);
} }
} else { } else {
AddSlowProperty(object, name, value, attributes); result = AddSlowProperty(name, value, attributes);
} }
if (FLAG_harmony_observation && object->map()->is_observed()) { Handle<Object> hresult;
Handle<Object> old_value = isolate->factory()->the_hole_value(); if (!result->ToHandle(&hresult, isolate)) return result;
EnqueueChangeRecord(object, "new", name, old_value);
if (FLAG_harmony_observation && map()->is_observed()) {
EnqueueChangeRecord(handle(this, isolate),
"new",
handle(name, isolate),
handle(heap->the_hole_value(), isolate));
} }
return value; return *hresult;
} }
...@@ -2140,32 +2115,29 @@ void JSObject::DeliverChangeRecords(Isolate* isolate) { ...@@ -2140,32 +2115,29 @@ void JSObject::DeliverChangeRecords(Isolate* isolate) {
} }
Handle<Object> JSObject::SetPropertyPostInterceptor( MaybeObject* JSObject::SetPropertyPostInterceptor(
Handle<JSObject> object, Name* name,
Handle<Name> name, Object* value,
Handle<Object> value,
PropertyAttributes attributes, PropertyAttributes attributes,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode,
StoreMode mode) {
// Check local property, ignore interceptor. // Check local property, ignore interceptor.
LookupResult result(object->GetIsolate()); LookupResult result(GetIsolate());
object->LocalLookupRealNamedProperty(*name, &result); LocalLookupRealNamedProperty(name, &result);
if (!result.IsFound()) { if (!result.IsFound()) map()->LookupTransition(this, name, &result);
object->map()->LookupTransition(*object, *name, &result);
}
if (result.IsFound()) { if (result.IsFound()) {
// An existing property or a map transition was found. Use set property to // An existing property or a map transition was found. Use set property to
// handle all these cases. // handle all these cases.
CALL_HEAP_FUNCTION(object->GetIsolate(), return SetProperty(&result, name, value, attributes, strict_mode);
object->SetProperty(
&result, *name, *value, attributes, strict_mode),
Object);
} }
bool done = false; bool done = false;
Handle<Object> result_object = SetPropertyViaPrototypes( MaybeObject* result_object =
object, name, value, attributes, strict_mode, &done); SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done);
if (done) return result_object; if (done) return result_object;
// Add a new real property. // Add a new real property.
return AddProperty(object, name, value, attributes, strict_mode); return AddProperty(name, value, attributes, strict_mode,
MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK,
OPTIMAL_REPRESENTATION, mode);
} }
...@@ -2731,36 +2703,41 @@ Map* Map::CurrentMapForDeprecated() { ...@@ -2731,36 +2703,41 @@ Map* Map::CurrentMapForDeprecated() {
} }
Handle<Object> JSObject::SetPropertyWithInterceptor( MaybeObject* JSObject::SetPropertyWithInterceptor(
Handle<JSObject> object, Name* name,
Handle<Name> name, Object* value,
Handle<Object> value,
PropertyAttributes attributes, PropertyAttributes attributes,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode) {
// TODO(rossberg): Support symbols in the API. // TODO(rossberg): Support symbols in the API.
if (name->IsSymbol()) return value; if (name->IsSymbol()) return value;
Isolate* isolate = object->GetIsolate(); Isolate* isolate = GetIsolate();
Handle<String> name_string = Handle<String>::cast(name); HandleScope scope(isolate);
Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); Handle<JSObject> this_handle(this);
Handle<String> name_handle(String::cast(name));
Handle<Object> value_handle(value, isolate);
Handle<InterceptorInfo> interceptor(GetNamedInterceptor());
if (!interceptor->setter()->IsUndefined()) { if (!interceptor->setter()->IsUndefined()) {
LOG(isolate, LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name));
ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
PropertyCallbackArguments args(
isolate, interceptor->data(), *object, *object);
v8::NamedPropertySetterCallback setter = v8::NamedPropertySetterCallback setter =
v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
Handle<Object> value_unhole = value->IsTheHole() Handle<Object> value_unhole(value->IsTheHole() ?
? Handle<Object>(isolate->factory()->undefined_value()) : value; isolate->heap()->undefined_value() :
value,
isolate);
v8::Handle<v8::Value> result = args.Call(setter, v8::Handle<v8::Value> result = args.Call(setter,
v8::Utils::ToLocal(name_string), v8::Utils::ToLocal(name_handle),
v8::Utils::ToLocal(value_unhole)); v8::Utils::ToLocal(value_unhole));
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); RETURN_IF_SCHEDULED_EXCEPTION(isolate);
if (!result.IsEmpty()) return value; if (!result.IsEmpty()) return *value_handle;
} }
Handle<Object> result = MaybeObject* raw_result =
SetPropertyPostInterceptor(object, name, value, attributes, strict_mode); this_handle->SetPropertyPostInterceptor(*name_handle,
RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); *value_handle,
return result; attributes,
strict_mode);
RETURN_IF_SCHEDULED_EXCEPTION(isolate);
return raw_result;
} }
...@@ -2953,20 +2930,21 @@ MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes( ...@@ -2953,20 +2930,21 @@ MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(
return heap->the_hole_value(); return heap->the_hole_value();
} }
Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, MaybeObject* JSObject::SetPropertyViaPrototypes(
Handle<Name> name, Name* name,
Handle<Object> value, Object* value,
PropertyAttributes attributes, PropertyAttributes attributes,
StrictModeFlag strict_mode, StrictModeFlag strict_mode,
bool* done) { bool* done) {
Isolate* isolate = object->GetIsolate(); Heap* heap = GetHeap();
Isolate* isolate = heap->isolate();
*done = false; *done = false;
// We could not find a local property so let's check whether there is an // We could not find a local property so let's check whether there is an
// accessor that wants to handle the property, or whether the property is // accessor that wants to handle the property, or whether the property is
// read-only on the prototype chain. // read-only on the prototype chain.
LookupResult result(isolate); LookupResult result(isolate);
object->LookupRealNamedPropertyInPrototypes(*name, &result); LookupRealNamedPropertyInPrototypes(name, &result);
if (result.IsFound()) { if (result.IsFound()) {
switch (result.type()) { switch (result.type()) {
case NORMAL: case NORMAL:
...@@ -2977,25 +2955,19 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, ...@@ -2977,25 +2955,19 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
case INTERCEPTOR: { case INTERCEPTOR: {
PropertyAttributes attr = PropertyAttributes attr =
result.holder()->GetPropertyAttributeWithInterceptor( result.holder()->GetPropertyAttributeWithInterceptor(
*object, *name, true); this, name, true);
*done = !!(attr & READ_ONLY); *done = !!(attr & READ_ONLY);
break; break;
} }
case CALLBACKS: { case CALLBACKS: {
if (!FLAG_es5_readonly && result.IsReadOnly()) break; if (!FLAG_es5_readonly && result.IsReadOnly()) break;
*done = true; *done = true;
CALL_HEAP_FUNCTION(isolate, return SetPropertyWithCallback(result.GetCallbackObject(),
object->SetPropertyWithCallback( name, value, result.holder(), strict_mode);
result.GetCallbackObject(),
*name, *value, result.holder(), strict_mode),
Object);
} }
case HANDLER: { case HANDLER: {
CALL_HEAP_FUNCTION(isolate, return result.proxy()->SetPropertyViaPrototypesWithHandler(
result.proxy()->SetPropertyViaPrototypesWithHandler( this, name, value, attributes, strict_mode, done);
*object, *name, *value, attributes, strict_mode,
done),
Object);
} }
case TRANSITION: case TRANSITION:
case NONEXISTENT: case NONEXISTENT:
...@@ -3008,13 +2980,12 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, ...@@ -3008,13 +2980,12 @@ Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object,
if (!FLAG_es5_readonly) *done = false; if (!FLAG_es5_readonly) *done = false;
if (*done) { if (*done) {
if (strict_mode == kNonStrictMode) return value; if (strict_mode == kNonStrictMode) return value;
Handle<Object> args[] = { name, object }; Handle<Object> args[] = { Handle<Object>(name, isolate),
Handle<Object> error = isolate->factory()->NewTypeError( Handle<Object>(this, isolate)};
"strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); return isolate->Throw(*isolate->factory()->NewTypeError(
isolate->Throw(*error); "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))));
return Handle<Object>();
} }
return isolate->factory()->the_hole_value(); return heap->the_hole_value();
} }
...@@ -3802,14 +3773,11 @@ static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup, ...@@ -3802,14 +3773,11 @@ static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup,
// AddProperty will either normalize the object, or create a new fast copy // AddProperty will either normalize the object, or create a new fast copy
// of the map. If we get a fast copy of the map, all field representations // of the map. If we get a fast copy of the map, all field representations
// will be tagged since the transition is omitted. // will be tagged since the transition is omitted.
Handle<JSObject> holder(lookup->holder()); return lookup->holder()->AddProperty(
Handle<Object> result = JSObject::AddProperty( *name, *value, attributes, kNonStrictMode,
holder, name, value, attributes, kNonStrictMode,
JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED,
JSReceiver::OMIT_EXTENSIBILITY_CHECK, JSReceiver::OMIT_EXTENSIBILITY_CHECK,
JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION);
RETURN_IF_EMPTY_HANDLE(holder->GetIsolate(), result);
return *result;
} }
// Keep the target CONSTANT if the same value is stored. // Keep the target CONSTANT if the same value is stored.
...@@ -3979,18 +3947,15 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, ...@@ -3979,18 +3947,15 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) { if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) {
bool done = false; bool done = false;
Handle<Object> result_object = SetPropertyViaPrototypes( MaybeObject* result_object = self->SetPropertyViaPrototypes(
self, name, value, attributes, strict_mode, &done); *name, *value, attributes, strict_mode, &done);
RETURN_IF_EMPTY_HANDLE(isolate, result_object); if (done) return result_object;
if (done) return *result_object;
} }
if (!lookup->IsFound()) { if (!lookup->IsFound()) {
// Neither properties nor transitions found. // Neither properties nor transitions found.
Handle<Object> result_object = AddProperty( return self->AddProperty(
self, name, value, attributes, strict_mode, store_mode); *name, *value, attributes, strict_mode, store_mode);
RETURN_IF_EMPTY_HANDLE(isolate, result_object);
return *result_object;
} }
if (lookup->IsProperty() && lookup->IsReadOnly()) { if (lookup->IsProperty() && lookup->IsReadOnly()) {
...@@ -4029,14 +3994,10 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, ...@@ -4029,14 +3994,10 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup,
return self->SetPropertyWithCallback( return self->SetPropertyWithCallback(
callback_object, *name, *value, lookup->holder(), strict_mode); callback_object, *name, *value, lookup->holder(), strict_mode);
} }
case INTERCEPTOR: { case INTERCEPTOR:
Handle<JSObject> holder(lookup->holder()); result = lookup->holder()->SetPropertyWithInterceptor(
Handle<Object> hresult = SetPropertyWithInterceptor( *name, *value, attributes, strict_mode);
holder, name, value, attributes, strict_mode);
RETURN_IF_EMPTY_HANDLE(isolate, hresult);
result = *hresult;
break; break;
}
case TRANSITION: { case TRANSITION: {
result = SetPropertyUsingTransition(lookup, name, value, attributes); result = SetPropertyUsingTransition(lookup, name, value, attributes);
break; break;
...@@ -4159,23 +4120,21 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( ...@@ -4159,23 +4120,21 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
LocalLookupRealNamedProperty(name_raw, &lookup); LocalLookupRealNamedProperty(name_raw, &lookup);
} }
// From this point on everything needs to be handlified.
HandleScope scope(isolate);
Handle<JSObject> self(this);
Handle<Name> name(name_raw);
Handle<Object> value(value_raw, isolate);
// Check for accessor in prototype chain removed here in clone. // Check for accessor in prototype chain removed here in clone.
if (!lookup.IsFound()) { if (!lookup.IsFound()) {
// Neither properties nor transitions found. // Neither properties nor transitions found.
Handle<Object> result = AddProperty( return AddProperty(
self, name, value, attributes, kNonStrictMode, name_raw, value_raw, attributes, kNonStrictMode,
MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode);
RETURN_IF_EMPTY_HANDLE(isolate, result);
return *result;
} }
Handle<Object> old_value = isolate->factory()->the_hole_value(); // From this point on everything needs to be handlified.
HandleScope scope(isolate);
Handle<JSObject> self(this);
Handle<Name> name(name_raw);
Handle<Object> value(value_raw, isolate);
Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate);
PropertyAttributes old_attributes = ABSENT; PropertyAttributes old_attributes = ABSENT;
bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); bool is_observed = FLAG_harmony_observation && self->map()->is_observed();
if (is_observed && lookup.IsProperty()) { if (is_observed && lookup.IsProperty()) {
......
...@@ -2145,12 +2145,17 @@ class JSObject: public JSReceiver { ...@@ -2145,12 +2145,17 @@ class JSObject: public JSReceiver {
Object* value, Object* value,
JSObject* holder, JSObject* holder,
StrictModeFlag strict_mode); StrictModeFlag strict_mode);
static Handle<Object> SetPropertyWithInterceptor( MUST_USE_RESULT MaybeObject* SetPropertyWithInterceptor(
Handle<JSObject> object, Name* name,
Handle<Name> name, Object* value,
Handle<Object> value,
PropertyAttributes attributes, PropertyAttributes attributes,
StrictModeFlag strict_mode); StrictModeFlag strict_mode);
MUST_USE_RESULT MaybeObject* SetPropertyPostInterceptor(
Name* name,
Object* value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
StoreMode mode = ALLOW_AS_CONSTANT);
static Handle<Object> SetLocalPropertyIgnoreAttributes( static Handle<Object> SetLocalPropertyIgnoreAttributes(
Handle<JSObject> object, Handle<JSObject> object,
...@@ -2471,7 +2476,6 @@ class JSObject: public JSReceiver { ...@@ -2471,7 +2476,6 @@ class JSObject: public JSReceiver {
// Add a property to a fast-case object using a map transition to // Add a property to a fast-case object using a map transition to
// new_map. // new_map.
// TODO(mstarzinger): Only public because of SetPropertyUsingTransition!
MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap( MUST_USE_RESULT MaybeObject* AddFastPropertyUsingMap(
Map* new_map, Map* new_map,
Name* name, Name* name,
...@@ -2479,6 +2483,18 @@ class JSObject: public JSReceiver { ...@@ -2479,6 +2483,18 @@ class JSObject: public JSReceiver {
int field_index, int field_index,
Representation representation); Representation representation);
// Add a constant function property to a fast-case object.
// This leaves a CONSTANT_TRANSITION in the old map, and
// if it is called on a second object with this map, a
// normal property is added instead, with a map transition.
// This avoids the creation of many maps with the same constant
// function, all orphaned.
MUST_USE_RESULT MaybeObject* AddConstantProperty(
Name* name,
Object* constant,
PropertyAttributes attributes,
TransitionFlag flag);
MUST_USE_RESULT MaybeObject* ReplaceSlowProperty( MUST_USE_RESULT MaybeObject* ReplaceSlowProperty(
Name* name, Name* name,
Object* value, Object* value,
...@@ -2506,12 +2522,24 @@ class JSObject: public JSReceiver { ...@@ -2506,12 +2522,24 @@ class JSObject: public JSReceiver {
Representation new_representation, Representation new_representation,
StoreMode store_mode); StoreMode store_mode);
// Add a property to an object. // Add a property to a fast-case object.
// TODO(mstarzinger): Only public because of SetPropertyUsingTransition! MUST_USE_RESULT MaybeObject* AddFastProperty(
static Handle<Object> AddProperty( Name* name,
Handle<JSObject> object, Object* value,
Handle<Name> name, PropertyAttributes attributes,
Handle<Object> value, StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
ValueType value_type = OPTIMAL_REPRESENTATION,
TransitionFlag flag = INSERT_TRANSITION);
// Add a property to a slow-case object.
MUST_USE_RESULT MaybeObject* AddSlowProperty(Name* name,
Object* value,
PropertyAttributes attributes);
// Add a property to an object. May cause GC.
MUST_USE_RESULT MaybeObject* AddProperty(
Name* name,
Object* value,
PropertyAttributes attributes, PropertyAttributes attributes,
StrictModeFlag strict_mode, StrictModeFlag strict_mode,
StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED, StoreFromKeyed store_mode = MAY_BE_STORE_FROM_KEYED,
...@@ -2746,62 +2774,13 @@ class JSObject: public JSReceiver { ...@@ -2746,62 +2774,13 @@ class JSObject: public JSReceiver {
// Searches the prototype chain for property 'name'. If it is found and // Searches the prototype chain for property 'name'. If it is found and
// has a setter, invoke it and set '*done' to true. If it is found and is // has a setter, invoke it and set '*done' to true. If it is found and is
// read-only, reject and set '*done' to true. Otherwise, set '*done' to // read-only, reject and set '*done' to true. Otherwise, set '*done' to
// false. Can throw and return an empty handle with '*done==true'. // false. Can cause GC and can return a failure result with '*done==true'.
static Handle<Object> SetPropertyViaPrototypes( MUST_USE_RESULT MaybeObject* SetPropertyViaPrototypes(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
StrictModeFlag strict_mode,
bool* done);
static Handle<Object> SetPropertyPostInterceptor(
Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes,
StrictModeFlag strict_mode);
// Add a constant function property to a fast-case object.
// This leaves a CONSTANT_TRANSITION in the old map, and
// if it is called on a second object with this map, a
// normal property is added instead, with a map transition.
// This avoids the creation of many maps with the same constant
// function, all orphaned.
static void AddConstantProperty(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> constant,
PropertyAttributes attributes,
TransitionFlag flag);
MUST_USE_RESULT MaybeObject* AddConstantProperty(
Name* name,
Object* constant,
PropertyAttributes attributes,
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,
ValueType value_type,
TransitionFlag flag);
MUST_USE_RESULT MaybeObject* AddFastProperty(
Name* name, Name* name,
Object* value, Object* value,
PropertyAttributes attributes, PropertyAttributes attributes,
StoreFromKeyed store_mode, StrictModeFlag strict_mode,
ValueType value_type, bool* done);
TransitionFlag flag);
// Add a property to a slow-case object.
static void AddSlowProperty(Handle<JSObject> object,
Handle<Name> name,
Handle<Object> value,
PropertyAttributes attributes);
MUST_USE_RESULT MaybeObject* AddSlowProperty(Name* name,
Object* value,
PropertyAttributes attributes);
static Handle<Object> DeleteProperty(Handle<JSObject> object, static Handle<Object> DeleteProperty(Handle<JSObject> object,
Handle<Name> name, Handle<Name> name,
......
...@@ -1404,19 +1404,17 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) { ...@@ -1404,19 +1404,17 @@ RUNTIME_FUNCTION(MaybeObject*, LoadPropertyWithInterceptorForCall) {
RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) { RUNTIME_FUNCTION(MaybeObject*, StoreInterceptorProperty) {
HandleScope scope(isolate);
ASSERT(args.length() == 4); ASSERT(args.length() == 4);
Handle<JSObject> recv(JSObject::cast(args[0])); JSObject* recv = JSObject::cast(args[0]);
Handle<Name> name(Name::cast(args[1])); Name* name = Name::cast(args[1]);
Handle<Object> value(args[2], isolate); Object* value = args[2];
ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode); ASSERT(args.smi_at(3) == kStrictMode || args.smi_at(3) == kNonStrictMode);
StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3)); StrictModeFlag strict_mode = static_cast<StrictModeFlag>(args.smi_at(3));
ASSERT(recv->HasNamedInterceptor()); ASSERT(recv->HasNamedInterceptor());
PropertyAttributes attr = NONE; PropertyAttributes attr = NONE;
Handle<Object> result = JSObject::SetPropertyWithInterceptor( MaybeObject* result = recv->SetPropertyWithInterceptor(
recv, name, value, attr, strict_mode); name, value, attr, strict_mode);
RETURN_IF_EMPTY_HANDLE(isolate, result); return result;
return *result;
} }
......
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