[cleanup] Rename "array protector" to "no elements protector".

The "array protector" now guards the Object.prototype, the
Array.prototype and the String.prototype, so the name was a
bit misleading nowadays. So the new name "no elements protector"
was chosen.

Bug: v8:6936, v8:7014, v8:7027
Change-Id: I9a9d7caa2caf0ac9e78cc6658de2f0506970dfa2
Reviewed-on: https://chromium-review.googlesource.com/778162
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49471}
This commit is contained in:
Benedikt Meurer 2017-11-20 09:42:53 +01:00 committed by Benedikt Meurer
parent 8a91be5b05
commit a9a1671345
17 changed files with 61 additions and 60 deletions

View File

@ -1101,7 +1101,7 @@ class FastArraySliceCodeStubAssembler : public CodeStubAssembler {
// Check prototype chain if receiver does not have packed elements
GotoIfNot(IsPrototypeInitialArrayPrototype(context, map), slow);
GotoIf(IsArrayProtectorCellInvalid(), slow);
GotoIf(IsNoElementsProtectorCellInvalid(), slow);
GotoIf(IsSpeciesProtectorCellInvalid(), slow);
@ -1562,7 +1562,7 @@ TF_BUILTIN(ExtractFastJSArray, ArrayBuiltinCodeStubAssembler) {
Node* count = TaggedToParameter(Parameter(Descriptor::kCount), mode);
CSA_ASSERT(this, IsJSArray(array));
CSA_ASSERT(this, Word32BinaryNot(IsArrayProtectorCellInvalid()));
CSA_ASSERT(this, Word32BinaryNot(IsNoElementsProtectorCellInvalid()));
Return(ExtractFastJSArray(context, array, begin, count, mode));
}
@ -1572,7 +1572,7 @@ TF_BUILTIN(CloneFastJSArray, ArrayBuiltinCodeStubAssembler) {
Node* array = Parameter(Descriptor::kSource);
CSA_ASSERT(this, IsJSArray(array));
CSA_ASSERT(this, Word32BinaryNot(IsArrayProtectorCellInvalid()));
CSA_ASSERT(this, Word32BinaryNot(IsNoElementsProtectorCellInvalid()));
ParameterMode mode = OptimalParameterMode();
Return(CloneFastJSArray(context, array, mode));
@ -2705,8 +2705,9 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
BIND(&holey_object_values);
{
// Check the array_protector cell, and take the slow path if it's invalid.
GotoIf(IsArrayProtectorCellInvalid(), &generic_values);
// Check the no_elements_protector cell, and take the slow path if it's
// invalid.
GotoIf(IsNoElementsProtectorCellInvalid(), &generic_values);
var_value.Bind(UndefinedConstant());
Node* value = LoadFixedArrayElement(elements, index, 0, SMI_PARAMETERS);
@ -2717,8 +2718,9 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
BIND(&holey_double_values);
{
// Check the array_protector cell, and take the slow path if it's invalid.
GotoIf(IsArrayProtectorCellInvalid(), &generic_values);
// Check the no_elements_protector cell, and take the slow path if it's
// invalid.
GotoIf(IsNoElementsProtectorCellInvalid(), &generic_values);
var_value.Bind(UndefinedConstant());
Node* value = LoadFixedDoubleArrayElement(

View File

@ -155,7 +155,7 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithArrayLike(
// protector is intact and our prototype is the Array.prototype actually.
GotoIfNot(IsPrototypeInitialArrayPrototype(context, arguments_list_map),
&if_runtime);
Branch(IsArrayProtectorCellInvalid(), &if_runtime, &if_done);
Branch(IsNoElementsProtectorCellInvalid(), &if_runtime, &if_done);
}
BIND(&if_arguments);
@ -310,9 +310,9 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread(
&if_runtime);
Branch(Word32And(kind, Int32Constant(1)), &if_holey, &if_done);
// Check the ArrayProtector cell for holey arrays.
// Check the NoElementsProtector cell for holey arrays.
BIND(&if_holey);
{ Branch(IsArrayProtectorCellInvalid(), &if_runtime, &if_done); }
{ Branch(IsNoElementsProtectorCellInvalid(), &if_runtime, &if_done); }
BIND(&if_runtime);
{

View File

@ -885,7 +885,7 @@ void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context,
// Check prototype chain if receiver does not have packed elements
GotoIfNot(IsPrototypeInitialArrayPrototype(context, map), if_false);
Branch(IsArrayProtectorCellInvalid(), if_false, if_true);
Branch(IsNoElementsProtectorCellInvalid(), if_false, if_true);
}
void CodeStubAssembler::BranchIfFastJSArrayForCopy(Node* object, Node* context,
@ -4059,9 +4059,9 @@ Node* CodeStubAssembler::IsUndetectableMap(Node* map) {
return IsSetWord32(LoadMapBitField(map), 1 << Map::kIsUndetectable);
}
Node* CodeStubAssembler::IsArrayProtectorCellInvalid() {
Node* CodeStubAssembler::IsNoElementsProtectorCellInvalid() {
Node* invalid = SmiConstant(Isolate::kProtectorInvalid);
Node* cell = LoadRoot(Heap::kArrayProtectorRootIndex);
Node* cell = LoadRoot(Heap::kNoElementsProtectorRootIndex);
Node* cell_value = LoadObjectField(cell, PropertyCell::kValueOffset);
return WordEqual(cell_value, invalid);
}
@ -10245,7 +10245,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
// its initial state (because the protector cell is only tracked for
// initial the Array and Object prototypes). Check these conditions
// here, and take the slow path if any fail.
GotoIf(IsArrayProtectorCellInvalid(), &if_isslow);
GotoIf(IsNoElementsProtectorCellInvalid(), &if_isslow);
Node* native_context = LoadNativeContext(context);

View File

@ -1029,7 +1029,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* IsAllocationSite(Node* object);
Node* IsAnyHeapNumber(Node* object);
Node* IsArrayIteratorInstanceType(Node* instance_type);
Node* IsArrayProtectorCellInvalid();
Node* IsNoElementsProtectorCellInvalid();
Node* IsBigIntInstanceType(Node* instance_type);
Node* IsBigInt(Node* object);
Node* IsBoolean(Node* object);

View File

@ -149,7 +149,7 @@ bool CanInlineArrayResizeOperation(Handle<Map> receiver_map) {
IsFastElementsKind(receiver_map->elements_kind()) &&
!receiver_map->is_dictionary_map() && receiver_map->is_extensible() &&
(!receiver_map->is_prototype_map() || receiver_map->is_stable()) &&
isolate->IsFastArrayConstructorPrototypeChainIntact() &&
isolate->IsNoElementsProtectorIntact() &&
isolate->IsAnyInitialArrayPrototype(receiver_prototype) &&
!IsReadOnlyLengthDescriptor(receiver_map);
}
@ -175,11 +175,12 @@ bool CanInlineJSArrayIteration(Handle<Map> receiver_map) {
if (!current->map()->is_stable()) return false;
}
// For holey Arrays, ensure that the array_protector cell is valid (must be
// a CompilationDependency), and the JSArray prototype has not been altered.
// For holey Arrays, ensure that the no_elements_protector cell is valid (must
// be a CompilationDependency), and the JSArray prototype has not been
// altered.
return receiver_map->instance_type() == JS_ARRAY_TYPE &&
(!receiver_map->is_dictionary_map() || receiver_map->is_stable()) &&
isolate->IsFastArrayConstructorPrototypeChainIntact() &&
isolate->IsNoElementsProtectorIntact() &&
isolate->IsAnyInitialArrayPrototype(receiver_prototype);
}
@ -330,12 +331,12 @@ Reduction JSBuiltinReducer::ReduceFastArrayIteratorNext(
iterator_map->instance_type());
if (IsHoleyElementsKind(elements_kind)) {
if (!isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
if (!isolate()->IsNoElementsProtectorIntact()) {
return NoChange();
} else {
Handle<JSObject> initial_array_prototype(
native_context()->initial_array_prototype(), isolate());
dependencies()->AssumePropertyCell(factory()->array_protector());
dependencies()->AssumePropertyCell(factory()->no_elements_protector());
}
}
@ -908,7 +909,7 @@ Reduction JSBuiltinReducer::ReduceArrayPop(Node* node) {
receiver_map->elements_kind() != HOLEY_DOUBLE_ELEMENTS) {
// Install code dependencies on the {receiver} prototype maps and the
// global array protector cell.
dependencies()->AssumePropertyCell(factory()->array_protector());
dependencies()->AssumePropertyCell(factory()->no_elements_protector());
dependencies()->AssumePrototypeMapsStable(receiver_map);
// Load the "length" property of the {receiver}.
@ -1012,7 +1013,7 @@ Reduction JSBuiltinReducer::ReduceArrayPush(Node* node) {
// Install code dependencies on the {receiver} prototype maps and the
// global array protector cell.
dependencies()->AssumePropertyCell(factory()->array_protector());
dependencies()->AssumePropertyCell(factory()->no_elements_protector());
dependencies()->AssumePrototypeMapsStable(receiver_map);
// If the {receiver_maps} information is not reliable, we need
@ -1128,7 +1129,7 @@ Reduction JSBuiltinReducer::ReduceArrayShift(Node* node) {
receiver_map->elements_kind() != HOLEY_DOUBLE_ELEMENTS) {
// Install code dependencies on the {receiver} prototype maps and the
// global array protector cell.
dependencies()->AssumePropertyCell(factory()->array_protector());
dependencies()->AssumePropertyCell(factory()->no_elements_protector());
dependencies()->AssumePrototypeMapsStable(receiver_map);
// Load length of the {receiver}.

View File

@ -856,7 +856,7 @@ bool CanInlineArrayIteratingBuiltin(Handle<Map> receiver_map) {
return receiver_map->instance_type() == JS_ARRAY_TYPE &&
IsFastElementsKind(receiver_map->elements_kind()) &&
(!receiver_map->is_prototype_map() || receiver_map->is_stable()) &&
isolate->IsFastArrayConstructorPrototypeChainIntact() &&
isolate->IsNoElementsProtectorIntact() &&
isolate->IsAnyInitialArrayPrototype(receiver_prototype);
}
@ -908,7 +908,7 @@ Reduction JSCallReducer::ReduceArrayForEach(Handle<JSFunction> function,
// Install code dependencies on the {receiver} prototype maps and the
// global array protector cell.
dependencies()->AssumePropertyCell(factory()->array_protector());
dependencies()->AssumePropertyCell(factory()->no_elements_protector());
Node* k = jsgraph()->ZeroConstant();

View File

@ -2488,9 +2488,9 @@ Node* JSNativeContextSpecialization::BuildIndexedStringLoad(
Node* receiver, Node* index, Node* length, Node** effect, Node** control,
KeyedAccessLoadMode load_mode) {
if (load_mode == LOAD_IGNORE_OUT_OF_BOUNDS &&
isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
isolate()->IsNoElementsProtectorIntact()) {
// Add a code dependency on the "no elements" protector.
dependencies()->AssumePropertyCell(factory()->array_protector());
dependencies()->AssumePropertyCell(factory()->no_elements_protector());
// Ensure that the {index} is a valid String length.
index = *effect = graph()->NewNode(simplified()->CheckBounds(), index,
@ -2618,10 +2618,10 @@ bool JSNativeContextSpecialization::CanTreatHoleAsUndefined(
}
// Check if the array prototype chain is intact.
if (!isolate()->IsFastArrayConstructorPrototypeChainIntact()) return false;
if (!isolate()->IsNoElementsProtectorIntact()) return false;
// Install code dependency on the array protector cell.
dependencies()->AssumePropertyCell(factory()->array_protector());
dependencies()->AssumePropertyCell(factory()->no_elements_protector());
return true;
}

View File

@ -911,7 +911,7 @@ class ElementsAccessorBase : public ElementsAccessor {
// Array optimizations rely on the prototype lookups of Array objects
// always returning undefined. If there is a store to the initial
// prototype object, make sure all of these optimizations are invalidated.
object->GetIsolate()->UpdateArrayProtectorOnSetLength(object);
object->GetIsolate()->UpdateNoElementsProtectorOnSetLength(object);
}
Handle<FixedArrayBase> old_elements(object->elements());
// This method should only be called if there's a reason to update the
@ -1885,7 +1885,7 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
// normalizing.
if (IsSmiOrObjectElementsKind(kind) ||
kind == FAST_STRING_WRAPPER_ELEMENTS) {
isolate->UpdateArrayProtectorOnNormalizeElements(object);
isolate->UpdateNoElementsProtectorOnNormalizeElements(object);
}
int capacity = object->GetFastElementsUsage();
@ -3280,7 +3280,7 @@ class TypedElementsAccessor
if (!isolate->is_initial_array_prototype(JSObject::cast(source_proto))) {
return true;
}
return !isolate->IsFastArrayConstructorPrototypeChainIntact();
return !isolate->IsNoElementsProtectorIntact();
}
static bool TryCopyElementsHandleFastNumber(Handle<JSArray> source,
@ -4151,7 +4151,7 @@ class StringWrapperElementsAccessor
// objects always returning undefined. If there's a store to the
// initial String.prototype object, make sure all the optimizations
// are invalidated.
object->GetIsolate()->UpdateArrayProtectorOnSetLength(object);
object->GetIsolate()->UpdateNoElementsProtectorOnSetLength(object);
}
// This method should only be called if there's a reason to update the
// elements.

View File

@ -200,7 +200,7 @@ using v8::MemoryPressureLevel;
V(InterceptorInfo, noop_interceptor_info, NoOpInterceptorInfo) \
/* Protectors */ \
V(Cell, array_constructor_protector, ArrayConstructorProtector) \
V(PropertyCell, array_protector, ArrayProtector) \
V(PropertyCell, no_elements_protector, NoElementsProtector) \
V(Cell, is_concat_spreadable_protector, IsConcatSpreadableProtector) \
V(PropertyCell, species_protector, SpeciesProtector) \
V(Cell, string_length_protector, StringLengthProtector) \
@ -283,7 +283,7 @@ using v8::MemoryPressureLevel;
V(ArgumentsMarkerMap) \
V(ArrayBufferNeuteringProtector) \
V(ArrayIteratorProtector) \
V(ArrayProtector) \
V(NoElementsProtector) \
V(BigIntMap) \
V(BlockContextMap) \
V(BooleanMap) \

View File

@ -606,7 +606,7 @@ void Heap::CreateInitialObjects() {
Handle<PropertyCell> cell = factory->NewPropertyCell(factory->empty_string());
cell->set_value(Smi::FromInt(Isolate::kProtectorValid));
set_array_protector(*cell);
set_no_elements_protector(*cell);
cell = factory->NewPropertyCell(factory->empty_string());
cell->set_value(the_hole_value());

View File

@ -289,7 +289,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
{
Comment("convert hole");
GotoIfNot(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss);
GotoIf(IsArrayProtectorCellInvalid(), miss);
GotoIf(IsNoElementsProtectorCellInvalid(), miss);
exit_point->Return(UndefinedConstant());
}
@ -309,9 +309,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
Node* allow_out_of_bounds =
IsSetWord<LoadHandler::AllowOutOfBoundsBits>(handler_word);
GotoIfNot(allow_out_of_bounds, miss);
// TODO(bmeurer): This is going to be renamed to NoElementsProtector
// in a follow-up CL.
GotoIf(IsArrayProtectorCellInvalid(), miss);
GotoIf(IsNoElementsProtectorCellInvalid(), miss);
Return(UndefinedConstant());
}

View File

@ -1141,7 +1141,7 @@ KeyedAccessLoadMode GetLoadMode(Handle<Object> receiver, uint32_t index) {
// For other {receiver}s we need to check the "no elements" protector.
Isolate* isolate = Handle<HeapObject>::cast(receiver)->GetIsolate();
if (isolate->IsFastArrayConstructorPrototypeChainIntact()) {
if (isolate->IsNoElementsProtectorIntact()) {
if (receiver->IsString()) {
// ToObject(receiver) will have the initial String.prototype.
return LOAD_IGNORE_OUT_OF_BOUNDS;

View File

@ -3126,8 +3126,8 @@ bool Isolate::IsInAnyContext(Object* object, uint32_t index) {
return false;
}
bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
PropertyCell* no_elements_cell = heap()->array_protector();
bool Isolate::IsNoElementsProtectorIntact() {
PropertyCell* no_elements_cell = heap()->no_elements_protector();
bool cell_reports_intact =
no_elements_cell->value()->IsSmi() &&
Smi::ToInt(no_elements_cell->value()) == kProtectorValid;
@ -3236,13 +3236,13 @@ bool Isolate::IsIsConcatSpreadableLookupChainIntact(JSReceiver* receiver) {
return !receiver->HasProxyInPrototype(this);
}
void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) {
void Isolate::UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object) {
DisallowHeapAllocation no_gc;
if (!object->map()->is_prototype_map()) return;
if (!IsFastArrayConstructorPrototypeChainIntact()) return;
if (!IsNoElementsProtectorIntact()) return;
if (!IsArrayOrObjectOrStringPrototype(*object)) return;
PropertyCell::SetValueWithInvalidation(
factory()->array_protector(),
factory()->no_elements_protector(),
handle(Smi::FromInt(kProtectorInvalid), this));
}

View File

@ -1087,7 +1087,7 @@ class Isolate {
static const int kProtectorInvalid = 0;
inline bool IsArrayConstructorIntact();
bool IsFastArrayConstructorPrototypeChainIntact();
bool IsNoElementsProtectorIntact();
inline bool IsArraySpeciesLookupChainIntact();
bool IsIsConcatSpreadableLookupChainIntact();
bool IsIsConcatSpreadableLookupChainIntact(JSReceiver* receiver);
@ -1104,15 +1104,15 @@ class Isolate {
// notifications occur if the set is on the elements of the array or
// object prototype. Also ensure that changes to prototype chain between
// Array and Object fire notifications.
void UpdateArrayProtectorOnSetElement(Handle<JSObject> object);
void UpdateArrayProtectorOnSetLength(Handle<JSObject> object) {
UpdateArrayProtectorOnSetElement(object);
void UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object);
void UpdateNoElementsProtectorOnSetLength(Handle<JSObject> object) {
UpdateNoElementsProtectorOnSetElement(object);
}
void UpdateArrayProtectorOnSetPrototype(Handle<JSObject> object) {
UpdateArrayProtectorOnSetElement(object);
void UpdateNoElementsProtectorOnSetPrototype(Handle<JSObject> object) {
UpdateNoElementsProtectorOnSetElement(object);
}
void UpdateArrayProtectorOnNormalizeElements(Handle<JSObject> object) {
UpdateArrayProtectorOnSetElement(object);
void UpdateNoElementsProtectorOnNormalizeElements(Handle<JSObject> object) {
UpdateNoElementsProtectorOnSetElement(object);
}
void InvalidateArrayConstructorProtector();
void InvalidateArraySpeciesProtector();

View File

@ -2636,7 +2636,7 @@ bool Object::IterationHasObservableEffects() {
// the prototype. This could have different results if the prototype has been
// changed.
if (IsHoleyElementsKind(array_kind) &&
isolate->IsFastArrayConstructorPrototypeChainIntact()) {
isolate->IsNoElementsProtectorIntact()) {
return false;
}
return true;
@ -15132,7 +15132,7 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
// Set the new prototype of the object.
isolate->UpdateArrayProtectorOnSetPrototype(real_receiver);
isolate->UpdateNoElementsProtectorOnSetPrototype(real_receiver);
Handle<Map> new_map = Map::TransitionToPrototype(map, value);
DCHECK(new_map->prototype() == *value);

View File

@ -20061,10 +20061,10 @@ static void BreakArrayGuarantees(const char* script) {
v8::Context::Scope context_scope(context);
v8::internal::Isolate* i_isolate =
reinterpret_cast<v8::internal::Isolate*>(isolate1);
CHECK(i_isolate->IsFastArrayConstructorPrototypeChainIntact());
CHECK(i_isolate->IsNoElementsProtectorIntact());
// Run something in new isolate.
CompileRun(script);
CHECK(!i_isolate->IsFastArrayConstructorPrototypeChainIntact());
CHECK(!i_isolate->IsNoElementsProtectorIntact());
}
isolate1->Exit();
isolate1->Dispose();

View File

@ -315,7 +315,7 @@ KNOWN_OBJECTS = {
("OLD_SPACE", 0x028a9): "EmptyOrderedHashSet",
("OLD_SPACE", 0x028d1): "EmptyPropertyCell",
("OLD_SPACE", 0x028f9): "EmptyWeakCell",
("OLD_SPACE", 0x02969): "ArrayProtector",
("OLD_SPACE", 0x02969): "NoElementsProtector",
("OLD_SPACE", 0x02991): "IsConcatSpreadableProtector",
("OLD_SPACE", 0x029a1): "SpeciesProtector",
("OLD_SPACE", 0x029c9): "StringLengthProtector",