Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 202fb5ce9ffaf3c5ed3a17a6a5da22850152e168..6ce8e0dd54a3dd4396e665b35ff56c9e520cd7fe 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -2621,24 +2621,6 @@ void JSObject::AddSlowProperty(Handle<JSObject> object, |
} |
-MaybeHandle<Object> JSObject::EnqueueChangeRecord(Handle<JSObject> object, |
- const char* type_str, |
- Handle<Name> name, |
- Handle<Object> old_value) { |
- DCHECK(!object->IsJSGlobalProxy()); |
- DCHECK(!object->IsJSGlobalObject()); |
- Isolate* isolate = object->GetIsolate(); |
- HandleScope scope(isolate); |
- Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); |
- Handle<Object> args[] = { type, object, name, old_value }; |
- int argc = name.is_null() ? 2 : old_value->IsTheHole() ? 3 : 4; |
- |
- return Execution::Call(isolate, |
- Handle<JSFunction>(isolate->observers_notify_change()), |
- isolate->factory()->undefined_value(), argc, args); |
-} |
- |
- |
const char* Representation::Mnemonic() const { |
switch (kind_) { |
case kNone: return "v"; |
@@ -4390,14 +4372,6 @@ Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) { |
// Store on the holder which may be hidden behind the receiver. |
DCHECK(it->HolderIsReceiverOrHiddenPrototype()); |
- // Old value for the observation change record. |
- // Fetch before transforming the object since the encoding may become |
- // incompatible with what's cached in |it|. |
- bool is_observed = receiver->map()->is_observed() && |
- (it->IsElement() || !it->name()->IsPrivate()); |
- MaybeHandle<Object> maybe_old; |
- if (is_observed) maybe_old = it->GetDataValue(); |
- |
Handle<Object> to_assign = value; |
// Convert the incoming value to a number for storing into typed arrays. |
if (it->IsElement() && receiver->HasFixedTypedArrayElements()) { |
@@ -4420,15 +4394,6 @@ Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) { |
// Write the property value. |
it->WriteDataValue(to_assign); |
- // Send the change record if there are observers. |
- if (is_observed && !value->SameValue(*maybe_old.ToHandleChecked())) { |
- RETURN_ON_EXCEPTION_VALUE( |
- it->isolate(), |
- JSObject::EnqueueChangeRecord(receiver, "update", it->GetName(), |
- maybe_old.ToHandleChecked()), |
- Nothing<bool>()); |
- } |
- |
#if VERIFY_HEAP |
if (FLAG_verify_heap) { |
receiver->JSObjectVerify(); |
@@ -4438,47 +4403,6 @@ Maybe<bool> Object::SetDataProperty(LookupIterator* it, Handle<Object> value) { |
} |
-MUST_USE_RESULT static MaybeHandle<Object> BeginPerformSplice( |
- Handle<JSArray> object) { |
- Isolate* isolate = object->GetIsolate(); |
- HandleScope scope(isolate); |
- Handle<Object> args[] = {object}; |
- |
- return Execution::Call( |
- isolate, Handle<JSFunction>(isolate->observers_begin_perform_splice()), |
- isolate->factory()->undefined_value(), arraysize(args), args); |
-} |
- |
- |
-MUST_USE_RESULT static MaybeHandle<Object> EndPerformSplice( |
- Handle<JSArray> object) { |
- Isolate* isolate = object->GetIsolate(); |
- HandleScope scope(isolate); |
- Handle<Object> args[] = {object}; |
- |
- return Execution::Call( |
- isolate, Handle<JSFunction>(isolate->observers_end_perform_splice()), |
- isolate->factory()->undefined_value(), arraysize(args), args); |
-} |
- |
- |
-MUST_USE_RESULT static MaybeHandle<Object> EnqueueSpliceRecord( |
- Handle<JSArray> object, uint32_t index, Handle<JSArray> deleted, |
- uint32_t add_count) { |
- Isolate* isolate = object->GetIsolate(); |
- HandleScope scope(isolate); |
- Handle<Object> index_object = isolate->factory()->NewNumberFromUint(index); |
- Handle<Object> add_count_object = |
- isolate->factory()->NewNumberFromUint(add_count); |
- |
- Handle<Object> args[] = {object, index_object, deleted, add_count_object}; |
- |
- return Execution::Call( |
- isolate, Handle<JSFunction>(isolate->observers_enqueue_splice()), |
- isolate->factory()->undefined_value(), arraysize(args), args); |
-} |
- |
- |
Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value, |
PropertyAttributes attributes, |
ShouldThrow should_throw, |
@@ -4549,13 +4473,6 @@ Maybe<bool> Object::AddDataProperty(LookupIterator* it, Handle<Object> value, |
it->WriteDataValue(value); |
} |
- // Send the change record if there are observers. |
- if (receiver->map()->is_observed() && !it->name()->IsPrivate()) { |
- RETURN_ON_EXCEPTION_VALUE(isolate, JSObject::EnqueueChangeRecord( |
- receiver, "add", it->name(), |
- it->factory()->the_hole_value()), |
- Nothing<bool>()); |
- } |
#if VERIFY_HEAP |
if (FLAG_verify_heap) { |
receiver->JSObjectVerify(); |
@@ -5311,8 +5228,6 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes( |
ShouldThrow should_throw, AccessorInfoHandling handling) { |
it->UpdateProtector(); |
Handle<JSObject> object = Handle<JSObject>::cast(it->GetReceiver()); |
- bool is_observed = object->map()->is_observed() && |
- (it->IsElement() || !it->name()->IsPrivate()); |
for (; it->IsFound(); it->Next()) { |
switch (it->state()) { |
@@ -5372,14 +5287,6 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes( |
it->ReconfigureDataProperty(value, attributes); |
} |
- if (is_observed) { |
- RETURN_ON_EXCEPTION_VALUE( |
- it->isolate(), |
- EnqueueChangeRecord(object, "reconfigure", it->GetName(), |
- it->factory()->the_hole_value()), |
- Nothing<bool>()); |
- } |
- |
return Just(true); |
} |
case LookupIterator::INTEGER_INDEXED_EXOTIC: |
@@ -5400,20 +5307,8 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes( |
} |
// Reconfigure the data property if the attributes mismatch. |
- Handle<Object> old_value = it->factory()->the_hole_value(); |
- if (is_observed) old_value = it->GetDataValue(); |
- |
it->ReconfigureDataProperty(value, attributes); |
- if (is_observed) { |
- if (old_value->SameValue(*value)) { |
- old_value = it->factory()->the_hole_value(); |
- } |
- RETURN_ON_EXCEPTION_VALUE( |
- it->isolate(), EnqueueChangeRecord(object, "reconfigure", |
- it->GetName(), old_value), |
- Nothing<bool>()); |
- } |
return Just(true); |
} |
} |
@@ -6143,11 +6038,6 @@ Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it, |
} |
Handle<JSObject> receiver = Handle<JSObject>::cast(it->GetReceiver()); |
- bool is_observed = receiver->map()->is_observed() && |
- (it->IsElement() || !it->name()->IsPrivate()); |
- |
- Handle<Object> old_value = it->factory()->the_hole_value(); |
- |
for (; it->IsFound(); it->Next()) { |
switch (it->state()) { |
case LookupIterator::JSPROXY: |
@@ -6175,10 +6065,6 @@ Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it, |
case LookupIterator::INTEGER_INDEXED_EXOTIC: |
return Just(true); |
case LookupIterator::DATA: |
- if (is_observed) { |
- old_value = it->GetDataValue(); |
- } |
- // Fall through. |
case LookupIterator::ACCESSOR: { |
if (!it->IsConfigurable()) { |
// Fail if the property is not configurable. |
@@ -6193,13 +6079,6 @@ Maybe<bool> JSReceiver::DeleteProperty(LookupIterator* it, |
it->Delete(); |
- if (is_observed) { |
- RETURN_ON_EXCEPTION_VALUE( |
- isolate, JSObject::EnqueueChangeRecord(receiver, "delete", |
- it->GetName(), old_value), |
- Nothing<bool>()); |
- } |
- |
return Just(true); |
} |
} |
@@ -6948,10 +6827,7 @@ Maybe<bool> JSArray::ArraySetLength(Isolate* isolate, Handle<JSArray> a, |
// (Not needed.) |
} |
// Most of steps 16 through 19 is implemented by JSArray::SetLength. |
- if (JSArray::ObservableSetLength(a, new_len).is_null()) { |
- DCHECK(isolate->has_pending_exception()); |
- return Nothing<bool>(); |
- } |
+ JSArray::SetLength(a, new_len); |
// Steps 19d-ii, 20. |
if (!new_writable) { |
PropertyDescriptor readonly; |
@@ -7458,8 +7334,7 @@ Maybe<bool> JSReceiver::SetIntegrityLevel(Handle<JSReceiver> receiver, |
if (receiver->IsJSObject()) { |
Handle<JSObject> object = Handle<JSObject>::cast(receiver); |
- if (!object->HasSloppyArgumentsElements() && |
- !object->map()->is_observed()) { // Fast path. |
+ if (!object->HasSloppyArgumentsElements()) { // Fast path. |
if (level == SEALED) { |
return JSObject::PreventExtensionsWithTransition<SEALED>(object, |
should_throw); |
@@ -7610,7 +7485,7 @@ Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object, |
ShouldThrow should_throw) { |
Isolate* isolate = object->GetIsolate(); |
- if (!object->HasSloppyArgumentsElements() && !object->map()->is_observed()) { |
+ if (!object->HasSloppyArgumentsElements()) { |
return PreventExtensionsWithTransition<NONE>(object, should_throw); |
} |
@@ -7651,13 +7526,6 @@ Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object, |
JSObject::MigrateToMap(object, new_map); |
DCHECK(!object->map()->is_extensible()); |
- if (object->map()->is_observed()) { |
- RETURN_ON_EXCEPTION_VALUE( |
- isolate, |
- EnqueueChangeRecord(object, "preventExtensions", Handle<Name>(), |
- isolate->factory()->the_hole_value()), |
- Nothing<bool>()); |
- } |
return Just(true); |
} |
@@ -7758,7 +7626,6 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition( |
// Sealing/freezing sloppy arguments should be handled elsewhere. |
DCHECK(!object->HasSloppyArgumentsElements()); |
- DCHECK(!object->map()->is_observed()); |
Isolate* isolate = object->GetIsolate(); |
if (object->IsAccessCheckNeeded() && |
@@ -7877,28 +7744,6 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition( |
} |
-void JSObject::SetObserved(Handle<JSObject> object) { |
- DCHECK(!object->IsJSGlobalProxy()); |
- DCHECK(!object->IsJSGlobalObject()); |
- Isolate* isolate = object->GetIsolate(); |
- Handle<Map> new_map; |
- Handle<Map> old_map(object->map(), isolate); |
- DCHECK(!old_map->is_observed()); |
- Map* transition = TransitionArray::SearchSpecial( |
- *old_map, isolate->heap()->observed_symbol()); |
- if (transition != NULL) { |
- new_map = handle(transition, isolate); |
- DCHECK(new_map->is_observed()); |
- } else if (TransitionArray::CanHaveMoreTransitions(old_map)) { |
- new_map = Map::CopyForObserved(old_map); |
- } else { |
- new_map = Map::Copy(old_map, "SlowObserved"); |
- new_map->set_is_observed(); |
- } |
- JSObject::MigrateToMap(object, new_map); |
-} |
- |
- |
Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, |
Representation representation, |
FieldIndex index) { |
@@ -8996,19 +8841,6 @@ MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it, |
return it->factory()->undefined_value(); |
} |
- Handle<Object> old_value = isolate->factory()->the_hole_value(); |
- bool is_observed = object->map()->is_observed() && |
- (it->IsElement() || !it->name()->IsPrivate()); |
- bool preexists = false; |
- if (is_observed) { |
- CHECK(GetPropertyAttributes(it).IsJust()); |
- preexists = it->IsFound(); |
- if (preexists && (it->state() == LookupIterator::DATA || |
- it->GetAccessors()->IsAccessorInfo())) { |
- old_value = Object::GetProperty(it).ToHandleChecked(); |
- } |
- } |
- |
DCHECK(getter->IsCallable() || getter->IsUndefined() || getter->IsNull() || |
getter->IsFunctionTemplateInfo()); |
DCHECK(setter->IsCallable() || setter->IsUndefined() || setter->IsNull() || |
@@ -9022,15 +8854,6 @@ MaybeHandle<Object> JSObject::DefineAccessor(LookupIterator* it, |
it->TransitionToAccessorProperty(ACCESSOR_SETTER, setter, attributes); |
} |
- if (is_observed) { |
- // Make sure the top context isn't changed. |
- AssertNoContextChange ncc(isolate); |
- const char* type = preexists ? "reconfigure" : "add"; |
- RETURN_ON_EXCEPTION( |
- isolate, EnqueueChangeRecord(object, type, it->GetName(), old_value), |
- Object); |
- } |
- |
return isolate->factory()->undefined_value(); |
} |
@@ -9639,30 +9462,6 @@ Handle<Map> Map::AsLanguageMode(Handle<Map> initial_map, |
} |
-Handle<Map> Map::CopyForObserved(Handle<Map> map) { |
- DCHECK(!map->is_observed()); |
- |
- Isolate* isolate = map->GetIsolate(); |
- |
- bool insert_transition = |
- TransitionArray::CanHaveMoreTransitions(map) && !map->is_prototype_map(); |
- |
- if (insert_transition) { |
- Handle<Map> new_map = CopyForTransition(map, "CopyForObserved"); |
- new_map->set_is_observed(); |
- |
- Handle<Name> name = isolate->factory()->observed_symbol(); |
- ConnectTransition(map, new_map, name, SPECIAL_TRANSITION); |
- return new_map; |
- } |
- |
- // Create a new free-floating map only if we are not allowed to store it. |
- Handle<Map> new_map = Map::Copy(map, "CopyForObserved"); |
- new_map->set_is_observed(); |
- return new_map; |
-} |
- |
- |
Handle<Map> Map::CopyForTransition(Handle<Map> map, const char* reason) { |
DCHECK(!map->is_prototype_map()); |
Handle<Map> new_map = CopyDropDescriptors(map); |
@@ -14723,28 +14522,6 @@ void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) { |
} |
-// Returns false if the passed-in index is marked non-configurable, which will |
-// cause the truncation operation to halt, and thus no further old values need |
-// be collected. |
-static bool GetOldValue(Isolate* isolate, |
- Handle<JSObject> object, |
- uint32_t index, |
- List<Handle<Object> >* old_values, |
- List<uint32_t>* indices) { |
- LookupIterator it(isolate, object, index, object, LookupIterator::HIDDEN); |
- CHECK(JSReceiver::GetPropertyAttributes(&it).IsJust()); |
- DCHECK(it.IsFound()); |
- if (!it.IsConfigurable()) return false; |
- Handle<Object> value = |
- it.state() == LookupIterator::ACCESSOR |
- ? Handle<Object>::cast(isolate->factory()->the_hole_value()) |
- : JSReceiver::GetDataProperty(&it); |
- old_values->Add(value); |
- indices->Add(index); |
- return true; |
-} |
- |
- |
void JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) { |
// We should never end in here with a pixel or external array. |
DCHECK(array->AllowsSetLength()); |
@@ -14755,91 +14532,6 @@ void JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) { |
} |
-MaybeHandle<Object> JSArray::ObservableSetLength(Handle<JSArray> array, |
- uint32_t new_length) { |
- if (!array->map()->is_observed()) { |
- SetLength(array, new_length); |
- return array; |
- } |
- |
- Isolate* isolate = array->GetIsolate(); |
- List<uint32_t> indices; |
- List<Handle<Object> > old_values; |
- Handle<Object> old_length_handle(array->length(), isolate); |
- uint32_t old_length = 0; |
- CHECK(old_length_handle->ToArrayLength(&old_length)); |
- |
- int num_elements = array->NumberOfOwnElements(ALL_PROPERTIES); |
- if (num_elements > 0) { |
- if (old_length == static_cast<uint32_t>(num_elements)) { |
- // Simple case for arrays without holes. |
- for (uint32_t i = old_length - 1; i + 1 > new_length; --i) { |
- if (!GetOldValue(isolate, array, i, &old_values, &indices)) break; |
- } |
- } else { |
- // For sparse arrays, only iterate over existing elements. |
- // TODO(rafaelw): For fast, sparse arrays, we can avoid iterating over |
- // the to-be-removed indices twice. |
- Handle<FixedArray> keys = isolate->factory()->NewFixedArray(num_elements); |
- array->GetOwnElementKeys(*keys, ALL_PROPERTIES); |
- while (num_elements-- > 0) { |
- uint32_t index = NumberToUint32(keys->get(num_elements)); |
- if (index < new_length) break; |
- if (!GetOldValue(isolate, array, index, &old_values, &indices)) break; |
- } |
- } |
- } |
- |
- SetLength(array, new_length); |
- |
- CHECK(array->length()->ToArrayLength(&new_length)); |
- if (old_length == new_length) return array; |
- |
- RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); |
- |
- for (int i = 0; i < indices.length(); ++i) { |
- // For deletions where the property was an accessor, old_values[i] |
- // will be the hole, which instructs EnqueueChangeRecord to elide |
- // the "oldValue" property. |
- RETURN_ON_EXCEPTION( |
- isolate, |
- JSObject::EnqueueChangeRecord( |
- array, "delete", isolate->factory()->Uint32ToString(indices[i]), |
- old_values[i]), |
- Object); |
- } |
- |
- RETURN_ON_EXCEPTION(isolate, |
- JSObject::EnqueueChangeRecord( |
- array, "update", isolate->factory()->length_string(), |
- old_length_handle), |
- Object); |
- |
- RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object); |
- |
- uint32_t index = Min(old_length, new_length); |
- uint32_t add_count = new_length > old_length ? new_length - old_length : 0; |
- uint32_t delete_count = new_length < old_length ? old_length - new_length : 0; |
- Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
- if (delete_count > 0) { |
- for (int i = indices.length() - 1; i >= 0; i--) { |
- // Skip deletions where the property was an accessor, leaving holes |
- // in the array of old values. |
- if (old_values[i]->IsTheHole()) continue; |
- JSObject::AddDataElement(deleted, indices[i] - index, old_values[i], NONE) |
- .Assert(); |
- } |
- |
- JSArray::SetLength(deleted, delete_count); |
- } |
- |
- RETURN_ON_EXCEPTION( |
- isolate, EnqueueSpliceRecord(array, index, deleted, add_count), Object); |
- |
- return array; |
-} |
- |
- |
// static |
void Map::AddDependentCode(Handle<Map> map, |
DependentCode::DependencyGroup group, |
@@ -15248,46 +14940,10 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object, |
isolate->InvalidateArraySpeciesProtector(); |
} |
- const bool observed = from_javascript && object->map()->is_observed(); |
- Handle<Object> old_value; |
- if (observed) { |
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, old_value, |
- JSReceiver::GetPrototype(isolate, object), |
- Nothing<bool>()); |
- } |
- |
- Maybe<bool> result = |
- SetPrototypeUnobserved(object, value, from_javascript, should_throw); |
- MAYBE_RETURN(result, Nothing<bool>()); |
- |
- if (result.FromJust() && observed) { |
- Handle<Object> new_value; |
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, new_value, |
- JSReceiver::GetPrototype(isolate, object), |
- Nothing<bool>()); |
- if (!new_value->SameValue(*old_value)) { |
- RETURN_ON_EXCEPTION_VALUE( |
- isolate, JSObject::EnqueueChangeRecord( |
- object, "setPrototype", |
- isolate->factory()->proto_string(), old_value), |
- Nothing<bool>()); |
- } |
- } |
- |
- return result; |
-} |
- |
- |
-Maybe<bool> JSObject::SetPrototypeUnobserved(Handle<JSObject> object, |
- Handle<Object> value, |
- bool from_javascript, |
- ShouldThrow should_throw) { |
#ifdef DEBUG |
int size = object->Size(); |
#endif |
- Isolate* isolate = object->GetIsolate(); |
- |
if (from_javascript) { |
if (object->IsAccessCheckNeeded() && |
!isolate->MayAccess(handle(isolate->context()), object)) { |
@@ -15523,12 +15179,8 @@ Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index, |
uint32_t old_length = 0; |
uint32_t new_capacity = 0; |
- Handle<Object> old_length_handle; |
if (object->IsJSArray()) { |
CHECK(JSArray::cast(*object)->length()->ToArrayLength(&old_length)); |
- if (object->map()->is_observed()) { |
- old_length_handle = handle(JSArray::cast(*object)->length(), isolate); |
- } |
} |
ElementsKind kind = object->GetElementsKind(); |
@@ -15572,38 +15224,6 @@ Maybe<bool> JSObject::AddDataElement(Handle<JSObject> object, uint32_t index, |
JSArray::cast(*object)->set_length(*new_length_handle); |
} |
- if (!old_length_handle.is_null() && new_length != old_length) { |
- // |old_length_handle| is kept null above unless the object is observed. |
- DCHECK(object->map()->is_observed()); |
- Handle<JSArray> array = Handle<JSArray>::cast(object); |
- Handle<String> name = isolate->factory()->Uint32ToString(index); |
- |
- RETURN_ON_EXCEPTION_VALUE(isolate, BeginPerformSplice(array), |
- Nothing<bool>()); |
- RETURN_ON_EXCEPTION_VALUE( |
- isolate, EnqueueChangeRecord(array, "add", name, |
- isolate->factory()->the_hole_value()), |
- Nothing<bool>()); |
- RETURN_ON_EXCEPTION_VALUE( |
- isolate, EnqueueChangeRecord(array, "update", |
- isolate->factory()->length_string(), |
- old_length_handle), |
- Nothing<bool>()); |
- RETURN_ON_EXCEPTION_VALUE(isolate, EndPerformSplice(array), |
- Nothing<bool>()); |
- Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
- RETURN_ON_EXCEPTION_VALUE(isolate, |
- EnqueueSpliceRecord(array, old_length, deleted, |
- new_length - old_length), |
- Nothing<bool>()); |
- } else if (object->map()->is_observed()) { |
- Handle<String> name = isolate->factory()->Uint32ToString(index); |
- RETURN_ON_EXCEPTION_VALUE( |
- isolate, EnqueueChangeRecord(object, "add", name, |
- isolate->factory()->the_hole_value()), |
- Nothing<bool>()); |
- } |
- |
return Just(true); |
} |
@@ -17254,8 +16874,7 @@ Handle<Object> JSObject::PrepareSlowElementsForSort( |
Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object, |
uint32_t limit) { |
Isolate* isolate = object->GetIsolate(); |
- if (object->HasSloppyArgumentsElements() || |
- object->map()->is_observed()) { |
+ if (object->HasSloppyArgumentsElements()) { |
return handle(Smi::FromInt(-1), isolate); |
} |