summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/js-native-context-specialization.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/js-native-context-specialization.cc')
-rw-r--r--deps/v8/src/compiler/js-native-context-specialization.cc134
1 files changed, 72 insertions, 62 deletions
diff --git a/deps/v8/src/compiler/js-native-context-specialization.cc b/deps/v8/src/compiler/js-native-context-specialization.cc
index 68d9fa05f0..2d105e55a8 100644
--- a/deps/v8/src/compiler/js-native-context-specialization.cc
+++ b/deps/v8/src/compiler/js-native-context-specialization.cc
@@ -802,9 +802,9 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
Node* node, Node* lookup_start_object, Node* receiver, Node* value,
NameRef const& name, AccessMode access_mode, Node* key,
PropertyCellRef const& property_cell, Node* effect) {
- Node* control = NodeProperties::GetControlInput(node);
- if (effect == nullptr) {
- effect = NodeProperties::GetEffectInput(node);
+ if (!property_cell.Serialize()) {
+ TRACE_BROKER_MISSING(broker(), "usable data for " << property_cell);
+ return NoChange();
}
ObjectRef property_cell_value = property_cell.value();
@@ -819,6 +819,11 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
PropertyCellType property_cell_type = property_details.cell_type();
DCHECK_EQ(kData, property_details.kind());
+ Node* control = NodeProperties::GetControlInput(node);
+ if (effect == nullptr) {
+ effect = NodeProperties::GetEffectInput(node);
+ }
+
// We have additional constraints for stores.
if (access_mode == AccessMode::kStore) {
DCHECK_EQ(receiver, lookup_start_object);
@@ -923,10 +928,6 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
DCHECK_EQ(receiver, lookup_start_object);
DCHECK(!property_details.IsReadOnly());
switch (property_details.cell_type()) {
- case PropertyCellType::kUndefined: {
- UNREACHABLE();
- break;
- }
case PropertyCellType::kConstant: {
// Record a code dependency on the cell, and just deoptimize if the new
// value doesn't match the previous value stored inside the cell.
@@ -997,6 +998,8 @@ Reduction JSNativeContextSpecialization::ReduceGlobalAccess(
jsgraph()->Constant(property_cell), value, effect, control);
break;
}
+ case PropertyCellType::kUndefined:
+ UNREACHABLE();
}
}
@@ -1950,26 +1953,36 @@ Reduction JSNativeContextSpecialization::ReduceElementLoadFromHeapConstant(
NumberMatcher mkey(key);
if (mkey.IsInteger() && mkey.IsInRange(0.0, kMaxUInt32 - 1.0)) {
uint32_t index = static_cast<uint32_t>(mkey.ResolvedValue());
- base::Optional<ObjectRef> element =
- receiver_ref.GetOwnConstantElement(index);
- if (!element.has_value() && receiver_ref.IsJSArray()) {
- // We didn't find a constant element, but if the receiver is a cow-array
- // we can exploit the fact that any future write to the element will
- // replace the whole elements storage.
- element = receiver_ref.AsJSArray().GetOwnCowElement(index);
- if (element.has_value()) {
- Node* elements = effect = graph()->NewNode(
- simplified()->LoadField(AccessBuilder::ForJSObjectElements()),
- receiver, effect, control);
- FixedArrayRef array_elements =
- receiver_ref.AsJSArray().elements().AsFixedArray();
- Node* check = graph()->NewNode(simplified()->ReferenceEqual(), elements,
- jsgraph()->Constant(array_elements));
- effect = graph()->NewNode(
- simplified()->CheckIf(DeoptimizeReason::kCowArrayElementsChanged),
- check, effect, control);
+ base::Optional<ObjectRef> element;
+
+ if (receiver_ref.IsJSObject()) {
+ element = receiver_ref.AsJSObject().GetOwnConstantElement(index);
+ if (!element.has_value() && receiver_ref.IsJSArray()) {
+ // We didn't find a constant element, but if the receiver is a cow-array
+ // we can exploit the fact that any future write to the element will
+ // replace the whole elements storage.
+ JSArrayRef array_ref = receiver_ref.AsJSArray();
+ base::Optional<FixedArrayBaseRef> array_elements = array_ref.elements();
+ if (array_elements.has_value()) {
+ element = array_ref.GetOwnCowElement(*array_elements, index);
+ if (element.has_value()) {
+ Node* elements = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForJSObjectElements()),
+ receiver, effect, control);
+ Node* check =
+ graph()->NewNode(simplified()->ReferenceEqual(), elements,
+ jsgraph()->Constant(*array_elements));
+ effect = graph()->NewNode(
+ simplified()->CheckIf(
+ DeoptimizeReason::kCowArrayElementsChanged),
+ check, effect, control);
+ }
+ }
}
+ } else if (receiver_ref.IsString()) {
+ element = receiver_ref.AsString().GetCharAsStringOrUndefined(index);
}
+
if (element.has_value()) {
Node* value = access_mode == AccessMode::kHas
? jsgraph()->TrueConstant()
@@ -2469,43 +2482,40 @@ JSNativeContextSpecialization::BuildPropertyStore(
value = effect =
graph()->NewNode(simplified()->CheckNumber(FeedbackSource()), value,
effect, control);
- if (!field_index.is_inobject() || !FLAG_unbox_double_fields) {
- if (access_info.HasTransitionMap()) {
- // Allocate a HeapNumber for the new property.
- AllocationBuilder a(jsgraph(), effect, control);
- a.Allocate(HeapNumber::kSize, AllocationType::kYoung,
- Type::OtherInternal());
- a.Store(AccessBuilder::ForMap(),
- MapRef(broker(), factory()->heap_number_map()));
- FieldAccess value_field_access =
- AccessBuilder::ForHeapNumberValue();
- value_field_access.const_field_info = field_access.const_field_info;
- a.Store(value_field_access, value);
- value = effect = a.Finish();
-
- field_access.type = Type::Any();
- field_access.machine_type = MachineType::TaggedPointer();
- field_access.write_barrier_kind = kPointerWriteBarrier;
- } else {
- // We just store directly to the HeapNumber.
- FieldAccess const storage_access = {
- kTaggedBase,
- field_index.offset(),
- name.object(),
- MaybeHandle<Map>(),
- Type::OtherInternal(),
- MachineType::TaggedPointer(),
- kPointerWriteBarrier,
- LoadSensitivity::kUnsafe,
- access_info.GetConstFieldInfo(),
- access_mode == AccessMode::kStoreInLiteral};
- storage = effect =
- graph()->NewNode(simplified()->LoadField(storage_access),
- storage, effect, control);
- field_access.offset = HeapNumber::kValueOffset;
- field_access.name = MaybeHandle<Name>();
- field_access.machine_type = MachineType::Float64();
- }
+ if (access_info.HasTransitionMap()) {
+ // Allocate a HeapNumber for the new property.
+ AllocationBuilder a(jsgraph(), effect, control);
+ a.Allocate(HeapNumber::kSize, AllocationType::kYoung,
+ Type::OtherInternal());
+ a.Store(AccessBuilder::ForMap(),
+ MapRef(broker(), factory()->heap_number_map()));
+ FieldAccess value_field_access = AccessBuilder::ForHeapNumberValue();
+ value_field_access.const_field_info = field_access.const_field_info;
+ a.Store(value_field_access, value);
+ value = effect = a.Finish();
+
+ field_access.type = Type::Any();
+ field_access.machine_type = MachineType::TaggedPointer();
+ field_access.write_barrier_kind = kPointerWriteBarrier;
+ } else {
+ // We just store directly to the HeapNumber.
+ FieldAccess const storage_access = {
+ kTaggedBase,
+ field_index.offset(),
+ name.object(),
+ MaybeHandle<Map>(),
+ Type::OtherInternal(),
+ MachineType::TaggedPointer(),
+ kPointerWriteBarrier,
+ LoadSensitivity::kUnsafe,
+ access_info.GetConstFieldInfo(),
+ access_mode == AccessMode::kStoreInLiteral};
+ storage = effect =
+ graph()->NewNode(simplified()->LoadField(storage_access), storage,
+ effect, control);
+ field_access.offset = HeapNumber::kValueOffset;
+ field_access.name = MaybeHandle<Name>();
+ field_access.machine_type = MachineType::Float64();
}
if (store_to_existing_constant_field) {
DCHECK(!access_info.HasTransitionMap());