[ptr-compr] Pass Isolate to JSObject::MigrateToMap() and friends

Tbr: ulan@chromium.org
Bug: v8:9353
Change-Id: I99533e21fd186f6d0191f4f500d1a3055a0f92c1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1648260
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62082}
This commit is contained in:
Igor Sheludko 2019-06-07 10:39:21 +02:00 committed by Commit Bot
parent 4d70d33c27
commit d0d877067e
11 changed files with 74 additions and 86 deletions

View File

@ -128,7 +128,7 @@ void DisableAccessChecks(Isolate* isolate, Handle<JSObject> object) {
// Copy map so it won't interfere constructor's initial map.
Handle<Map> new_map = Map::Copy(isolate, old_map, "DisableAccessChecks");
new_map->set_is_access_check_needed(false);
JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
JSObject::MigrateToMap(isolate, Handle<JSObject>::cast(object), new_map);
}
void EnableAccessChecks(Isolate* isolate, Handle<JSObject> object) {
@ -137,7 +137,7 @@ void EnableAccessChecks(Isolate* isolate, Handle<JSObject> object) {
Handle<Map> new_map = Map::Copy(isolate, old_map, "EnableAccessChecks");
new_map->set_is_access_check_needed(true);
new_map->set_may_have_interesting_symbols(true);
JSObject::MigrateToMap(object, new_map);
JSObject::MigrateToMap(isolate, object, new_map);
}
class AccessCheckDisableScope {

View File

@ -2755,7 +2755,7 @@ Handle<JSObject> Factory::NewJSObjectWithNullProto(AllocationType allocation) {
Handle<Map> new_map = Map::Copy(
isolate(), Handle<Map>(result->map(), isolate()), "ObjectWithNullProto");
Map::SetPrototype(isolate(), new_map, null_value());
JSObject::MigrateToMap(result, new_map);
JSObject::MigrateToMap(isolate(), result, new_map);
return result;
}
@ -2910,7 +2910,7 @@ Handle<JSObject> Factory::NewSlowJSObjectWithPropertiesAndElements(
DCHECK(elements->IsNumberDictionary());
object_map =
JSObject::GetElementsTransitionMap(object, DICTIONARY_ELEMENTS);
JSObject::MigrateToMap(object, object_map);
JSObject::MigrateToMap(isolate(), object, object_map);
object->set_elements(*elements);
}
return object;

View File

@ -567,23 +567,6 @@ class ElementsAccessorBase : public InternalElementsAccessor {
return true;
}
static void TryTransitionResultArrayToPacked(Handle<JSArray> array) {
if (!IsHoleyElementsKind(kind())) return;
Handle<FixedArrayBase> backing_store(array->elements(),
array->GetIsolate());
int length = Smi::ToInt(array->length());
if (!Subclass::IsPackedImpl(*array, *backing_store, 0, length)) return;
ElementsKind packed_kind = GetPackedElementsKind(kind());
Handle<Map> new_map =
JSObject::GetElementsTransitionMap(array, packed_kind);
JSObject::MigrateToMap(array, new_map);
if (FLAG_trace_elements_transitions) {
JSObject::PrintElementsTransition(stdout, array, kind(), backing_store,
packed_kind, backing_store);
}
}
bool HasElement(JSObject holder, uint32_t index, FixedArrayBase backing_store,
PropertyFilter filter) final {
return Subclass::HasElementImpl(holder.GetIsolate(), holder, index,
@ -806,7 +789,8 @@ class ElementsAccessorBase : public InternalElementsAccessor {
static void TransitionElementsKindImpl(Handle<JSObject> object,
Handle<Map> to_map) {
Handle<Map> from_map = handle(object->map(), object->GetIsolate());
Isolate* isolate = object->GetIsolate();
Handle<Map> from_map = handle(object->map(), isolate);
ElementsKind from_kind = from_map->elements_kind();
ElementsKind to_kind = to_map->elements_kind();
if (IsHoleyElementsKind(from_kind)) {
@ -818,14 +802,12 @@ class ElementsAccessorBase : public InternalElementsAccessor {
DCHECK(IsFastElementsKind(to_kind));
DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
Handle<FixedArrayBase> from_elements(object->elements(),
object->GetIsolate());
if (object->elements() ==
object->GetReadOnlyRoots().empty_fixed_array() ||
Handle<FixedArrayBase> from_elements(object->elements(), isolate);
if (object->elements() == ReadOnlyRoots(isolate).empty_fixed_array() ||
IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
// No change is needed to the elements() buffer, the transition
// only requires a map change.
JSObject::MigrateToMap(object, to_map);
JSObject::MigrateToMap(isolate, object, to_map);
} else {
DCHECK(
(IsSmiElementsKind(from_kind) && IsDoubleElementsKind(to_kind)) ||
@ -836,9 +818,9 @@ class ElementsAccessorBase : public InternalElementsAccessor {
JSObject::SetMapAndElements(object, to_map, elements);
}
if (FLAG_trace_elements_transitions) {
JSObject::PrintElementsTransition(
stdout, object, from_kind, from_elements, to_kind,
handle(object->elements(), object->GetIsolate()));
JSObject::PrintElementsTransition(stdout, object, from_kind,
from_elements, to_kind,
handle(object->elements(), isolate));
}
}
}
@ -2604,7 +2586,7 @@ class FastSealedObjectElementsAccessor
"SlowCopyForSetLengthImpl");
new_map->set_is_extensible(false);
new_map->set_elements_kind(DICTIONARY_ELEMENTS);
JSObject::MigrateToMap(array, new_map);
JSObject::MigrateToMap(isolate, array, new_map);
if (!new_element_dictionary.is_null()) {
array->set_elements(*new_element_dictionary);
@ -4339,7 +4321,7 @@ class FastSloppyArgumentsElementsAccessor
ConvertElementsWithCapacity(object, old_arguments, from_kind, capacity);
Handle<Map> new_map = JSObject::GetElementsTransitionMap(
object, FAST_SLOPPY_ARGUMENTS_ELEMENTS);
JSObject::MigrateToMap(object, new_map);
JSObject::MigrateToMap(isolate, object, new_map);
elements->set_arguments(FixedArray::cast(*arguments));
JSObject::ValidateElements(*object);
}

View File

@ -225,13 +225,14 @@ void JSObject::EnsureCanContainElements(Handle<JSObject> object,
void JSObject::SetMapAndElements(Handle<JSObject> object, Handle<Map> new_map,
Handle<FixedArrayBase> value) {
JSObject::MigrateToMap(object, new_map);
Isolate* isolate = object->GetIsolate();
JSObject::MigrateToMap(isolate, object, new_map);
DCHECK((object->map().has_fast_smi_or_object_elements() ||
(*value == object->GetReadOnlyRoots().empty_fixed_array()) ||
(*value == ReadOnlyRoots(isolate).empty_fixed_array()) ||
object->map().has_fast_string_wrapper_elements()) ==
(value->map() == object->GetReadOnlyRoots().fixed_array_map() ||
value->map() == object->GetReadOnlyRoots().fixed_cow_array_map()));
DCHECK((*value == object->GetReadOnlyRoots().empty_fixed_array()) ||
(value->map() == ReadOnlyRoots(isolate).fixed_array_map() ||
value->map() == ReadOnlyRoots(isolate).fixed_cow_array_map()));
DCHECK((*value == ReadOnlyRoots(isolate).empty_fixed_array()) ||
(object->map().has_fast_double_elements() ==
value->IsFixedDoubleArray()));
object->set_elements(*value);

View File

@ -2595,8 +2595,8 @@ namespace {
// to temporarily store the inobject properties.
// * If there are properties left in the backing store, install the backing
// store.
void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
Isolate* isolate = object->GetIsolate();
void MigrateFastToFast(Isolate* isolate, Handle<JSObject> object,
Handle<Map> new_map) {
Handle<Map> old_map(object->map(), isolate);
// In case of a regular transition.
if (new_map->GetBackPointer() == *old_map) {
@ -2818,7 +2818,8 @@ void MigrateFastToFast(Handle<JSObject> object, Handle<Map> new_map) {
object->synchronized_set_map(*new_map);
}
void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
void MigrateFastToSlow(Isolate* isolate, Handle<JSObject> object,
Handle<Map> new_map,
int expected_additional_properties) {
// The global object is always normalized.
DCHECK(!object->IsJSGlobalObject());
@ -2828,7 +2829,6 @@ void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
DCHECK_IMPLIES(new_map->is_prototype_map(),
Map::IsPrototypeChainInvalidated(*new_map));
Isolate* isolate = object->GetIsolate();
HandleScope scope(isolate);
Handle<Map> map(object->map(), isolate);
@ -2932,11 +2932,12 @@ void MigrateFastToSlow(Handle<JSObject> object, Handle<Map> new_map,
} // namespace
void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
void JSObject::MigrateToMap(Isolate* isolate, Handle<JSObject> object,
Handle<Map> new_map,
int expected_additional_properties) {
if (object->map() == *new_map) return;
Handle<Map> old_map(object->map(), object->GetIsolate());
NotifyMapChange(old_map, new_map, object->GetIsolate());
Handle<Map> old_map(object->map(), isolate);
NotifyMapChange(old_map, new_map, isolate);
if (old_map->is_dictionary_map()) {
// For slow-to-fast migrations JSObject::MigrateSlowToFast()
@ -2946,7 +2947,7 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
// Slow-to-slow migration is trivial.
object->synchronized_set_map(*new_map);
} else if (!new_map->is_dictionary_map()) {
MigrateFastToFast(object, new_map);
MigrateFastToFast(isolate, object, new_map);
if (old_map->is_prototype_map()) {
DCHECK(!old_map->is_stable());
DCHECK(new_map->is_stable());
@ -2958,13 +2959,12 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
old_map->set_owns_descriptors(false);
DCHECK(old_map->is_abandoned_prototype_map());
// Ensure that no transition was inserted for prototype migrations.
DCHECK_EQ(0, TransitionsAccessor(object->GetIsolate(), old_map)
.NumberOfTransitions());
DCHECK_EQ(0, TransitionsAccessor(isolate, old_map).NumberOfTransitions());
DCHECK(new_map->GetBackPointer().IsUndefined());
DCHECK(object->map() != *old_map);
}
} else {
MigrateFastToSlow(object, new_map, expected_additional_properties);
MigrateFastToSlow(isolate, object, new_map, expected_additional_properties);
}
// Careful: Don't allocate here!
@ -2978,11 +2978,11 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map,
void JSObject::ForceSetPrototype(Handle<JSObject> object,
Handle<HeapObject> proto) {
// object.__proto__ = proto;
Handle<Map> old_map = Handle<Map>(object->map(), object->GetIsolate());
Handle<Map> new_map =
Map::Copy(object->GetIsolate(), old_map, "ForceSetPrototype");
Map::SetPrototype(object->GetIsolate(), new_map, proto);
JSObject::MigrateToMap(object, new_map);
Isolate* isolate = object->GetIsolate();
Handle<Map> old_map = Handle<Map>(object->map(), isolate);
Handle<Map> new_map = Map::Copy(isolate, old_map, "ForceSetPrototype");
Map::SetPrototype(isolate, new_map, proto);
JSObject::MigrateToMap(isolate, object, new_map);
}
Maybe<bool> JSObject::SetPropertyWithInterceptor(
@ -3069,16 +3069,17 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
}
void JSObject::MigrateInstance(Handle<JSObject> object) {
Handle<Map> original_map(object->map(), object->GetIsolate());
Handle<Map> map = Map::Update(object->GetIsolate(), original_map);
Isolate* isolate = object->GetIsolate();
Handle<Map> original_map(object->map(), isolate);
Handle<Map> map = Map::Update(isolate, original_map);
map->set_is_migration_target(true);
MigrateToMap(object, map);
JSObject::MigrateToMap(isolate, object, map);
if (FLAG_trace_migration) {
object->PrintInstanceMigration(stdout, *original_map, *map);
}
#if VERIFY_HEAP
if (FLAG_verify_heap) {
object->JSObjectVerify(object->GetIsolate());
object->JSObjectVerify(isolate);
}
#endif
}
@ -3092,7 +3093,7 @@ bool JSObject::TryMigrateInstance(Handle<JSObject> object) {
if (!Map::TryUpdate(isolate, original_map).ToHandle(&new_map)) {
return false;
}
JSObject::MigrateToMap(object, new_map);
JSObject::MigrateToMap(isolate, object, new_map);
if (FLAG_trace_migration && *original_map != object->map()) {
object->PrintInstanceMigration(stdout, *original_map, object->map());
}
@ -3269,10 +3270,12 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
const char* reason) {
if (!object->HasFastProperties()) return;
Handle<Map> map(object->map(), object->GetIsolate());
Handle<Map> new_map = Map::Normalize(object->GetIsolate(), map, mode, reason);
Isolate* isolate = object->GetIsolate();
Handle<Map> map(object->map(), isolate);
Handle<Map> new_map = Map::Normalize(isolate, map, mode, reason);
MigrateToMap(object, new_map, expected_additional_properties);
JSObject::MigrateToMap(isolate, object, new_map,
expected_additional_properties);
}
void JSObject::MigrateSlowToFast(Handle<JSObject> object,
@ -3475,7 +3478,7 @@ Handle<NumberDictionary> JSObject::NormalizeElements(Handle<JSObject> object) {
: DICTIONARY_ELEMENTS;
Handle<Map> new_map = JSObject::GetElementsTransitionMap(object, target_kind);
// Set the new map first to satify the elements type assert in set_elements().
JSObject::MigrateToMap(object, new_map);
JSObject::MigrateToMap(isolate, object, new_map);
if (is_sloppy_arguments) {
SloppyArgumentsElements::cast(object->elements())
@ -3710,7 +3713,7 @@ Maybe<bool> JSObject::PreventExtensions(Handle<JSObject> object,
Map::Copy(isolate, handle(object->map(), isolate), "PreventExtensions");
new_map->set_is_extensible(false);
JSObject::MigrateToMap(object, new_map);
JSObject::MigrateToMap(isolate, object, new_map);
DCHECK(!object->map().is_extensible());
return Just(true);
@ -3836,12 +3839,12 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
transition_map->elements_kind() == SLOW_STRING_WRAPPER_ELEMENTS ||
transition_map->has_frozen_or_sealed_elements());
DCHECK(!transition_map->is_extensible());
JSObject::MigrateToMap(object, transition_map);
JSObject::MigrateToMap(isolate, object, transition_map);
} else if (transitions.CanHaveMoreTransitions()) {
// Create a new descriptor array with the appropriate property attributes
Handle<Map> new_map = Map::CopyForPreventExtensions(
isolate, old_map, attrs, transition_marker, "CopyForPreventExtensions");
JSObject::MigrateToMap(object, new_map);
JSObject::MigrateToMap(isolate, object, new_map);
} else {
DCHECK(old_map->is_dictionary_map() || !old_map->is_prototype_map());
// Slow path: need to normalize properties for safety
@ -3860,7 +3863,7 @@ Maybe<bool> JSObject::PreventExtensionsWithTransition(
: DICTIONARY_ELEMENTS;
new_map->set_elements_kind(new_kind);
}
JSObject::MigrateToMap(object, new_map);
JSObject::MigrateToMap(isolate, object, new_map);
if (attrs != NONE) {
ReadOnlyRoots roots(isolate);
@ -4185,10 +4188,10 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
}
} else {
Handle<Map> new_map = Map::Copy(object->GetIsolate(),
handle(object->map(), object->GetIsolate()),
"CopyAsPrototype");
JSObject::MigrateToMap(object, new_map);
Isolate* isolate = object->GetIsolate();
Handle<Map> new_map =
Map::Copy(isolate, handle(object->map(), isolate), "CopyAsPrototype");
JSObject::MigrateToMap(isolate, object, new_map);
object->map().set_is_prototype_map(true);
// Replace the pointer to the exact constructor with the Object function
@ -4447,7 +4450,7 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
Handle<Map> new_map =
Map::TransitionToPrototype(isolate, map, Handle<HeapObject>::cast(value));
DCHECK(new_map->prototype() == *value);
JSObject::MigrateToMap(real_receiver, new_map);
JSObject::MigrateToMap(isolate, real_receiver, new_map);
DCHECK(size == object->Size());
return Just(true);
@ -4654,14 +4657,15 @@ void JSObject::TransitionElementsKind(Handle<JSObject> object,
DCHECK_NE(TERMINAL_FAST_ELEMENTS_KIND, from_kind);
UpdateAllocationSite(object, to_kind);
if (object->elements() == object->GetReadOnlyRoots().empty_fixed_array() ||
Isolate* isolate = object->GetIsolate();
if (object->elements() == ReadOnlyRoots(isolate).empty_fixed_array() ||
IsDoubleElementsKind(from_kind) == IsDoubleElementsKind(to_kind)) {
// No change is needed to the elements() buffer, the transition
// only requires a map change.
Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
MigrateToMap(object, new_map);
JSObject::MigrateToMap(isolate, object, new_map);
if (FLAG_trace_elements_transitions) {
Handle<FixedArrayBase> elms(object->elements(), object->GetIsolate());
Handle<FixedArrayBase> elms(object->elements(), isolate);
PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
}
} else {
@ -5030,7 +5034,7 @@ void JSFunction::SetPrototype(Handle<JSFunction> function,
Handle<Map> new_map =
Map::Copy(isolate, handle(function->map(), isolate), "SetPrototype");
JSObject::MigrateToMap(function, new_map);
JSObject::MigrateToMap(isolate, function, new_map);
new_map->SetConstructor(*value);
new_map->set_has_non_instance_prototype(true);

View File

@ -596,7 +596,7 @@ class JSObject : public JSReceiver {
// |expected_additional_properties| is only used for fast-to-slow transitions
// and ignored otherwise.
V8_EXPORT_PRIVATE static void MigrateToMap(
Handle<JSObject> object, Handle<Map> new_map,
Isolate* isolate, Handle<JSObject> object, Handle<Map> new_map,
int expected_additional_properties = 0);
// Forces a prototype without any of the checks that the regular SetPrototype

View File

@ -498,7 +498,7 @@ void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
return;
}
JSObject::MigrateToMap(holder_obj, new_map);
JSObject::MigrateToMap(isolate_, holder_obj, new_map);
ReloadPropertyInformation<false>();
}
@ -532,7 +532,7 @@ void LookupIterator::ReconfigureDataProperty(Handle<Object> value,
new_map =
Map::PrepareForDataProperty(isolate(), new_map, descriptor_number(),
PropertyConstness::kMutable, value);
JSObject::MigrateToMap(holder_obj, new_map);
JSObject::MigrateToMap(isolate_, holder_obj, new_map);
ReloadPropertyInformation<false>();
}
@ -674,7 +674,8 @@ void LookupIterator::ApplyTransitionToDataProperty(
}
if (!receiver->IsJSProxy()) {
JSObject::MigrateToMap(Handle<JSObject>::cast(receiver), transition);
JSObject::MigrateToMap(isolate_, Handle<JSObject>::cast(receiver),
transition);
}
if (simple_transition) {
@ -761,7 +762,7 @@ void LookupIterator::TransitionToAccessorProperty(
Handle<Map> new_map = Map::TransitionToAccessorProperty(
isolate_, old_map, name_, descriptor, getter, setter, attributes);
bool simple_transition = new_map->GetBackPointer() == receiver->map();
JSObject::MigrateToMap(receiver, new_map);
JSObject::MigrateToMap(isolate_, receiver, new_map);
if (simple_transition) {
int number = new_map->LastAdded();

View File

@ -4924,7 +4924,7 @@ TEST(Regress388880) {
// Now everything is set up for crashing in JSObject::MigrateFastToFast()
// when it calls heap->AdjustLiveBytes(...).
JSObject::MigrateToMap(o, map2);
JSObject::MigrateToMap(isolate, o, map2);
}

View File

@ -345,7 +345,7 @@ HEAP_TEST(InvalidatedSlotsFastToSlow) {
Handle<Map> map(obj->map(), isolate);
Handle<Map> normalized_map =
Map::Normalize(isolate, map, CLEAR_INOBJECT_PROPERTIES, "testing");
JSObject::MigrateToMap(obj, normalized_map);
JSObject::MigrateToMap(isolate, obj, normalized_map);
}
CcTest::CollectGarbage(i::NEW_SPACE);
CcTest::CollectGarbage(i::OLD_SPACE);

View File

@ -521,7 +521,7 @@ TEST(ReconfigureAccessorToNonExistingDataField) {
// that the data property is uninitialized.
Factory* factory = isolate->factory();
Handle<JSObject> obj = factory->NewJSObjectFromMap(map);
JSObject::MigrateToMap(obj, prepared_map);
JSObject::MigrateToMap(isolate, obj, prepared_map);
FieldIndex index = FieldIndex::ForDescriptor(*prepared_map, 0);
CHECK(obj->RawFastPropertyAt(index).IsUninitialized(isolate));
#ifdef VERIFY_HEAP

View File

@ -972,7 +972,7 @@ TEST(Regress436816) {
Handle<Map> normalized_map =
Map::Normalize(isolate, map, KEEP_INOBJECT_PROPERTIES, "testing");
JSObject::MigrateToMap(object, normalized_map);
JSObject::MigrateToMap(isolate, object, normalized_map);
CHECK(!object->HasFastProperties());
CHECK(object->map().HasFastPointerLayout());
@ -1470,7 +1470,7 @@ static void TestWriteBarrier(Handle<Map> map, Handle<Map> new_map,
// Migrate |obj| to |new_map| which should shift fields and put the
// |boom_value| to the slot that was earlier recorded by write barrier.
JSObject::MigrateToMap(obj, new_map);
JSObject::MigrateToMap(isolate, obj, new_map);
Address fake_object = obj_value->ptr() + kTaggedSize;
uint64_t boom_value = bit_cast<uint64_t>(fake_object);
@ -1553,7 +1553,7 @@ static void TestIncrementalWriteBarrier(Handle<Map> map, Handle<Map> new_map,
// Migrate |obj| to |new_map| which should shift fields and put the
// |boom_value| to the slot that was earlier recorded by incremental write
// barrier.
JSObject::MigrateToMap(obj, new_map);
JSObject::MigrateToMap(isolate, obj, new_map);
uint64_t boom_value = UINT64_C(0xBAAD0176A37C28E1);