Commit 05437821 authored by Daniel Clifford's avatar Daniel Clifford Committed by Commit Bot

Introduce protector cell helper functions in CSA

Change-Id: Iac4a95a0c094472d887d89bbf5d6189988c56f7c
Reviewed-on: https://chromium-review.googlesource.com/692016
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48253}
parent b380525b
...@@ -753,11 +753,8 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { ...@@ -753,11 +753,8 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
Int32Constant(JS_ARRAY_TYPE)), Int32Constant(JS_ARRAY_TYPE)),
&runtime); &runtime);
Node* const native_context = LoadNativeContext(context()); GotoIfNot(IsPrototypeInitialArrayPrototype(context(), original_map),
Node* const initial_array_prototype = LoadContextElement( &runtime);
native_context, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
Node* proto = LoadMapPrototype(original_map);
GotoIf(WordNotEqual(proto, initial_array_prototype), &runtime);
Node* species_protector = SpeciesProtectorConstant(); Node* species_protector = SpeciesProtectorConstant();
Node* value = Node* value =
...@@ -774,6 +771,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler { ...@@ -774,6 +771,7 @@ class ArrayBuiltinCodeStubAssembler : public CodeStubAssembler {
// element in the input array (maybe the callback deletes an element). // element in the input array (maybe the callback deletes an element).
const ElementsKind elements_kind = const ElementsKind elements_kind =
GetHoleyElementsKind(GetInitialFastElementsKind()); GetHoleyElementsKind(GetInitialFastElementsKind());
Node* const native_context = LoadNativeContext(context());
Node* array_map = LoadJSArrayElementsMap(elements_kind, native_context); Node* array_map = LoadJSArrayElementsMap(elements_kind, native_context);
a_.Bind(AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, len, len, nullptr, a_.Bind(AllocateJSArray(PACKED_SMI_ELEMENTS, array_map, len, len, nullptr,
CodeStubAssembler::SMI_PARAMETERS)); CodeStubAssembler::SMI_PARAMETERS));
......
...@@ -153,17 +153,9 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithArrayLike( ...@@ -153,17 +153,9 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithArrayLike(
{ {
// For holey JSArrays we need to check that the array prototype chain // For holey JSArrays we need to check that the array prototype chain
// protector is intact and our prototype is the Array.prototype actually. // protector is intact and our prototype is the Array.prototype actually.
Node* arguments_list_prototype = LoadMapPrototype(arguments_list_map); GotoIfNot(IsPrototypeInitialArrayPrototype(context, arguments_list_map),
Node* initial_array_prototype = LoadContextElement(
native_context, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
GotoIfNot(WordEqual(arguments_list_prototype, initial_array_prototype),
&if_runtime); &if_runtime);
Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); Branch(IsArrayProtectorCellInvalid(), &if_runtime, &if_done);
DCHECK(isolate()->heap()->array_protector()->IsPropertyCell());
Branch(
WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
SmiConstant(Isolate::kProtectorValid)),
&if_done, &if_runtime);
} }
BIND(&if_arguments); BIND(&if_arguments);
...@@ -285,13 +277,8 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread( ...@@ -285,13 +277,8 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread(
Node* spread_map = LoadMap(spread); Node* spread_map = LoadMap(spread);
GotoIfNot(IsJSArrayMap(spread_map), &if_runtime); GotoIfNot(IsJSArrayMap(spread_map), &if_runtime);
Node* native_context = LoadNativeContext(context);
// Check that we have the original ArrayPrototype. // Check that we have the original ArrayPrototype.
Node* prototype = LoadMapPrototype(spread_map); GotoIfNot(IsPrototypeInitialArrayPrototype(context, spread_map), &if_runtime);
Node* array_prototype = LoadContextElement(
native_context, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
GotoIfNot(WordEqual(prototype, array_prototype), &if_runtime);
// Check that the ArrayPrototype hasn't been modified in a way that would // Check that the ArrayPrototype hasn't been modified in a way that would
// affect iteration. // affect iteration.
...@@ -303,6 +290,7 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread( ...@@ -303,6 +290,7 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread(
&if_runtime); &if_runtime);
// Check that the map of the initial array iterator hasn't changed. // Check that the map of the initial array iterator hasn't changed.
Node* native_context = LoadNativeContext(context);
Node* arr_it_proto_map = LoadMap(LoadContextElement( Node* arr_it_proto_map = LoadMap(LoadContextElement(
native_context, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX)); native_context, Context::INITIAL_ARRAY_ITERATOR_PROTOTYPE_INDEX));
Node* initial_map = LoadContextElement( Node* initial_map = LoadContextElement(
...@@ -325,14 +313,7 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread( ...@@ -325,14 +313,7 @@ void CallOrConstructBuiltinsAssembler::CallOrConstructWithSpread(
// Check the ArrayProtector cell for holey arrays. // Check the ArrayProtector cell for holey arrays.
BIND(&if_holey); BIND(&if_holey);
{ { Branch(IsArrayProtectorCellInvalid(), &if_runtime, &if_done); }
Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex);
DCHECK(isolate()->heap()->array_protector()->IsPropertyCell());
Branch(
WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
SmiConstant(Isolate::kProtectorValid)),
&if_done, &if_runtime);
}
BIND(&if_runtime); BIND(&if_runtime);
{ {
......
...@@ -3577,6 +3577,22 @@ Node* CodeStubAssembler::IsArrayProtectorCellInvalid() { ...@@ -3577,6 +3577,22 @@ Node* CodeStubAssembler::IsArrayProtectorCellInvalid() {
return WordEqual(cell_value, invalid); return WordEqual(cell_value, invalid);
} }
Node* CodeStubAssembler::IsSpeciesProtectorCellInvalid() {
Node* invalid = SmiConstant(Isolate::kProtectorInvalid);
Node* cell = LoadRoot(Heap::kSpeciesProtectorRootIndex);
Node* cell_value = LoadObjectField(cell, PropertyCell::kValueOffset);
return WordEqual(cell_value, invalid);
}
Node* CodeStubAssembler::IsPrototypeInitialArrayPrototype(Node* context,
Node* map) {
Node* const native_context = LoadNativeContext(context);
Node* const initial_array_prototype = LoadContextElement(
native_context, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
Node* proto = LoadMapPrototype(map);
return WordEqual(proto, initial_array_prototype);
}
Node* CodeStubAssembler::IsCallable(Node* object) { Node* CodeStubAssembler::IsCallable(Node* object) {
return IsCallableMap(LoadMap(object)); return IsCallableMap(LoadMap(object));
} }
...@@ -9644,12 +9660,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map, ...@@ -9644,12 +9660,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
// its initial state (because the protector cell is only tracked for // its initial state (because the protector cell is only tracked for
// initial the Array and Object prototypes). Check these conditions // initial the Array and Object prototypes). Check these conditions
// here, and take the slow path if any fail. // here, and take the slow path if any fail.
Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); GotoIf(IsArrayProtectorCellInvalid(), &if_isslow);
DCHECK(isolate()->heap()->array_protector()->IsPropertyCell());
GotoIfNot(WordEqual(LoadObjectField(protector_cell,
PropertyCell::kValueOffset),
SmiConstant(Isolate::kProtectorValid)),
&if_isslow);
Node* native_context = LoadNativeContext(context); Node* native_context = LoadNativeContext(context);
......
...@@ -943,6 +943,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -943,6 +943,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* IsWeakCell(Node* object); Node* IsWeakCell(Node* object);
Node* IsUndetectableMap(Node* map); Node* IsUndetectableMap(Node* map);
Node* IsArrayProtectorCellInvalid(); Node* IsArrayProtectorCellInvalid();
Node* IsSpeciesProtectorCellInvalid();
Node* IsPrototypeInitialArrayPrototype(Node* context, Node* map);
// True iff |object| is a Smi or a HeapNumber. // True iff |object| is a Smi or a HeapNumber.
Node* IsNumber(Node* object); Node* IsNumber(Node* object);
......
...@@ -246,12 +246,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase( ...@@ -246,12 +246,7 @@ void AccessorAssembler::HandleLoadICSmiHandlerCase(
{ {
Comment("convert hole"); Comment("convert hole");
GotoIfNot(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss); GotoIfNot(IsSetWord<LoadHandler::ConvertHoleBits>(handler_word), miss);
Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex); GotoIf(IsArrayProtectorCellInvalid(), miss);
DCHECK(isolate()->heap()->array_protector()->IsPropertyCell());
GotoIfNot(
WordEqual(LoadObjectField(protector_cell, PropertyCell::kValueOffset),
SmiConstant(Isolate::kProtectorValid)),
miss);
exit_point->Return(UndefinedConstant()); exit_point->Return(UndefinedConstant());
} }
......
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