@@ -3266,7 +3266,8 @@ Address TranslatedState::DecompressIfNeeded(intptr_t value) {
32663266 }
32673267}
32683268
3269- TranslatedState::TranslatedState (const JavaScriptFrame* frame) {
3269+ TranslatedState::TranslatedState (const JavaScriptFrame* frame)
3270+ : purpose_(kFrameInspection ) {
32703271 int deopt_index = Safepoint::kNoDeoptimizationIndex ;
32713272 DeoptimizationData data =
32723273 static_cast <const OptimizedFrame*>(frame)->GetDeoptimizationData (
@@ -3641,25 +3642,63 @@ void TranslatedState::EnsureCapturedObjectAllocatedAt(
36413642 }
36423643
36433644 default :
3644- CHECK (map->IsJSObjectMap ());
36453645 EnsureJSObjectAllocated (slot, map);
3646- TranslatedValue* properties_slot = &(frame->values_ [value_index]);
3647- value_index++;
3646+ int remaining_children_count = slot->GetChildrenCount () - 1 ;
3647+
3648+ TranslatedValue* properties_slot = frame->ValueAt (value_index);
3649+ value_index++, remaining_children_count--;
36483650 if (properties_slot->kind () == TranslatedValue::kCapturedObject ) {
3649- // If we are materializing the property array, make sure we put
3650- // the mutable heap numbers at the right places.
3651+ // We are materializing the property array, so make sure we put the
3652+ // mutable heap numbers at the right places.
36513653 EnsurePropertiesAllocatedAndMarked (properties_slot, map);
36523654 EnsureChildrenAllocated (properties_slot->GetChildrenCount (), frame,
36533655 &value_index, worklist);
3656+ } else {
3657+ CHECK_EQ (properties_slot->kind (), TranslatedValue::kTagged );
36543658 }
3655- // Make sure all the remaining children (after the map and properties) are
3656- // allocated.
3657- return EnsureChildrenAllocated (slot->GetChildrenCount () - 2 , frame,
3659+
3660+ TranslatedValue* elements_slot = frame->ValueAt (value_index);
3661+ value_index++, remaining_children_count--;
3662+ if (elements_slot->kind () == TranslatedValue::kCapturedObject ||
3663+ !map->IsJSArrayMap ()) {
3664+ // Handle this case with the other remaining children below.
3665+ value_index--, remaining_children_count++;
3666+ } else {
3667+ CHECK_EQ (elements_slot->kind (), TranslatedValue::kTagged );
3668+ elements_slot->GetValue ();
3669+ if (purpose_ == kFrameInspection ) {
3670+ // We are materializing a JSArray for the purpose of frame inspection.
3671+ // If we were to construct it with the above elements value then an
3672+ // actual deopt later on might create another JSArray instance with
3673+ // the same elements store. That would violate the key assumption
3674+ // behind left-trimming.
3675+ elements_slot->ReplaceElementsArrayWithCopy ();
3676+ }
3677+ }
3678+
3679+ // Make sure all the remaining children (after the map, properties store,
3680+ // and possibly elements store) are allocated.
3681+ return EnsureChildrenAllocated (remaining_children_count, frame,
36583682 &value_index, worklist);
36593683 }
36603684 UNREACHABLE ();
36613685}
36623686
3687+ void TranslatedValue::ReplaceElementsArrayWithCopy () {
3688+ DCHECK_EQ (kind (), TranslatedValue::kTagged );
3689+ DCHECK_EQ (materialization_state (), TranslatedValue::kFinished );
3690+ auto elements = Handle<FixedArrayBase>::cast (GetValue ());
3691+ DCHECK (elements->IsFixedArray () || elements->IsFixedDoubleArray ());
3692+ if (elements->IsFixedDoubleArray ()) {
3693+ DCHECK (!elements->IsCowArray ());
3694+ set_storage (isolate ()->factory ()->CopyFixedDoubleArray (
3695+ Handle<FixedDoubleArray>::cast (elements)));
3696+ } else if (!elements->IsCowArray ()) {
3697+ set_storage (isolate ()->factory ()->CopyFixedArray (
3698+ Handle<FixedArray>::cast (elements)));
3699+ }
3700+ }
3701+
36633702void TranslatedState::EnsureChildrenAllocated (int count, TranslatedFrame* frame,
36643703 int * value_index,
36653704 std::stack<int >* worklist) {
@@ -3724,6 +3763,7 @@ Handle<ByteArray> TranslatedState::AllocateStorageFor(TranslatedValue* slot) {
37243763
37253764void TranslatedState::EnsureJSObjectAllocated (TranslatedValue* slot,
37263765 Handle<Map> map) {
3766+ CHECK (map->IsJSObjectMap ());
37273767 CHECK_EQ (map->instance_size (), slot->GetChildrenCount () * kTaggedSize );
37283768
37293769 Handle<ByteArray> object_storage = AllocateStorageFor (slot);
0 commit comments