summaryrefslogtreecommitdiffstats
path: root/chromium/v8/src/deoptimizer/deoptimizer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/deoptimizer/deoptimizer.cc')
-rw-r--r--chromium/v8/src/deoptimizer/deoptimizer.cc58
1 files changed, 49 insertions, 9 deletions
diff --git a/chromium/v8/src/deoptimizer/deoptimizer.cc b/chromium/v8/src/deoptimizer/deoptimizer.cc
index 52ee2d4f167..1024a3572a2 100644
--- a/chromium/v8/src/deoptimizer/deoptimizer.cc
+++ b/chromium/v8/src/deoptimizer/deoptimizer.cc
@@ -3550,7 +3550,8 @@ Address TranslatedState::DecompressIfNeeded(intptr_t value) {
}
}
-TranslatedState::TranslatedState(const JavaScriptFrame* frame) {
+TranslatedState::TranslatedState(const JavaScriptFrame* frame)
+ : purpose_(kFrameInspection) {
int deopt_index = Safepoint::kNoDeoptimizationIndex;
DeoptimizationData data =
static_cast<const OptimizedFrame*>(frame)->GetDeoptimizationData(
@@ -3947,25 +3948,63 @@ void TranslatedState::EnsureCapturedObjectAllocatedAt(
}
default:
- CHECK(map->IsJSObjectMap());
EnsureJSObjectAllocated(slot, map);
- TranslatedValue* properties_slot = &(frame->values_[value_index]);
- value_index++;
+ int remaining_children_count = slot->GetChildrenCount() - 1;
+
+ TranslatedValue* properties_slot = frame->ValueAt(value_index);
+ value_index++, remaining_children_count--;
if (properties_slot->kind() == TranslatedValue::kCapturedObject) {
- // If we are materializing the property array, make sure we put
- // the mutable heap numbers at the right places.
+ // We are materializing the property array, so make sure we put the
+ // mutable heap numbers at the right places.
EnsurePropertiesAllocatedAndMarked(properties_slot, map);
EnsureChildrenAllocated(properties_slot->GetChildrenCount(), frame,
&value_index, worklist);
+ } else {
+ CHECK_EQ(properties_slot->kind(), TranslatedValue::kTagged);
}
- // Make sure all the remaining children (after the map and properties) are
- // allocated.
- return EnsureChildrenAllocated(slot->GetChildrenCount() - 2, frame,
+
+ TranslatedValue* elements_slot = frame->ValueAt(value_index);
+ value_index++, remaining_children_count--;
+ if (elements_slot->kind() == TranslatedValue::kCapturedObject ||
+ !map->IsJSArrayMap()) {
+ // Handle this case with the other remaining children below.
+ value_index--, remaining_children_count++;
+ } else {
+ CHECK_EQ(elements_slot->kind(), TranslatedValue::kTagged);
+ elements_slot->GetValue();
+ if (purpose_ == kFrameInspection) {
+ // We are materializing a JSArray for the purpose of frame inspection.
+ // If we were to construct it with the above elements value then an
+ // actual deopt later on might create another JSArray instance with
+ // the same elements store. That would violate the key assumption
+ // behind left-trimming.
+ elements_slot->ReplaceElementsArrayWithCopy();
+ }
+ }
+
+ // Make sure all the remaining children (after the map, properties store,
+ // and possibly elements store) are allocated.
+ return EnsureChildrenAllocated(remaining_children_count, frame,
&value_index, worklist);
}
UNREACHABLE();
}
+void TranslatedValue::ReplaceElementsArrayWithCopy() {
+ DCHECK_EQ(kind(), TranslatedValue::kTagged);
+ DCHECK_EQ(materialization_state(), TranslatedValue::kFinished);
+ auto elements = Handle<FixedArrayBase>::cast(GetValue());
+ DCHECK(elements->IsFixedArray() || elements->IsFixedDoubleArray());
+ if (elements->IsFixedDoubleArray()) {
+ DCHECK(!elements->IsCowArray());
+ set_storage(isolate()->factory()->CopyFixedDoubleArray(
+ Handle<FixedDoubleArray>::cast(elements)));
+ } else if (!elements->IsCowArray()) {
+ set_storage(isolate()->factory()->CopyFixedArray(
+ Handle<FixedArray>::cast(elements)));
+ }
+}
+
void TranslatedState::EnsureChildrenAllocated(int count, TranslatedFrame* frame,
int* value_index,
std::stack<int>* worklist) {
@@ -4030,6 +4069,7 @@ Handle<ByteArray> TranslatedState::AllocateStorageFor(TranslatedValue* slot) {
void TranslatedState::EnsureJSObjectAllocated(TranslatedValue* slot,
Handle<Map> map) {
+ CHECK(map->IsJSObjectMap());
CHECK_EQ(map->instance_size(), slot->GetChildrenCount() * kTaggedSize);
Handle<ByteArray> object_storage = AllocateStorageFor(slot);