@@ -3222,7 +3222,8 @@ int TranslatedState::CreateNextTranslatedValue(
32223222 FATAL (" We should never get here - unexpected deopt info." );
32233223}
32243224
3225- TranslatedState::TranslatedState (const JavaScriptFrame* frame) {
3225+ TranslatedState::TranslatedState (const JavaScriptFrame* frame)
3226+ : purpose_(kFrameInspection ) {
32263227 int deopt_index = Safepoint::kNoDeoptimizationIndex ;
32273228 DeoptimizationData* data =
32283229 static_cast <const OptimizedFrame*>(frame)->GetDeoptimizationData (
@@ -3596,25 +3597,63 @@ void TranslatedState::EnsureCapturedObjectAllocatedAt(
35963597 }
35973598
35983599 default :
3599- CHECK (map->IsJSObjectMap ());
36003600 EnsureJSObjectAllocated (slot, map);
3601- TranslatedValue* properties_slot = &(frame->values_ [value_index]);
3602- value_index++;
3601+ int remaining_children_count = slot->GetChildrenCount () - 1 ;
3602+
3603+ TranslatedValue* properties_slot = frame->ValueAt (value_index);
3604+ value_index++, remaining_children_count--;
36033605 if (properties_slot->kind () == TranslatedValue::kCapturedObject ) {
3604- // If we are materializing the property array, make sure we put
3605- // the mutable heap numbers at the right places.
3606+ // We are materializing the property array, so make sure we put the
3607+ // mutable heap numbers at the right places.
36063608 EnsurePropertiesAllocatedAndMarked (properties_slot, map);
36073609 EnsureChildrenAllocated (properties_slot->GetChildrenCount (), frame,
36083610 &value_index, worklist);
3611+ } else {
3612+ CHECK_EQ (properties_slot->kind (), TranslatedValue::kTagged );
36093613 }
3610- // Make sure all the remaining children (after the map and properties) are
3611- // allocated.
3612- return EnsureChildrenAllocated (slot->GetChildrenCount () - 2 , frame,
3614+
3615+ TranslatedValue* elements_slot = frame->ValueAt (value_index);
3616+ value_index++, remaining_children_count--;
3617+ if (elements_slot->kind () == TranslatedValue::kCapturedObject ||
3618+ !map->IsJSArrayMap ()) {
3619+ // Handle this case with the other remaining children below.
3620+ value_index--, remaining_children_count++;
3621+ } else {
3622+ CHECK_EQ (elements_slot->kind (), TranslatedValue::kTagged );
3623+ elements_slot->GetValue ();
3624+ if (purpose_ == kFrameInspection ) {
3625+ // We are materializing a JSArray for the purpose of frame inspection.
3626+ // If we were to construct it with the above elements value then an
3627+ // actual deopt later on might create another JSArray instance with
3628+ // the same elements store. That would violate the key assumption
3629+ // behind left-trimming.
3630+ elements_slot->ReplaceElementsArrayWithCopy ();
3631+ }
3632+ }
3633+
3634+ // Make sure all the remaining children (after the map, properties store,
3635+ // and possibly elements store) are allocated.
3636+ return EnsureChildrenAllocated (remaining_children_count, frame,
36133637 &value_index, worklist);
36143638 }
36153639 UNREACHABLE ();
36163640}
36173641
3642+ void TranslatedValue::ReplaceElementsArrayWithCopy () {
3643+ DCHECK_EQ (kind (), TranslatedValue::kTagged );
3644+ DCHECK_EQ (materialization_state (), TranslatedValue::kFinished );
3645+ auto elements = Handle<FixedArrayBase>::cast (GetValue ());
3646+ DCHECK (elements->IsFixedArray () || elements->IsFixedDoubleArray ());
3647+ if (elements->IsFixedDoubleArray ()) {
3648+ DCHECK (!elements->IsCowArray ());
3649+ set_storage (isolate ()->factory ()->CopyFixedDoubleArray (
3650+ Handle<FixedDoubleArray>::cast (elements)));
3651+ } else if (!elements->IsCowArray ()) {
3652+ set_storage (isolate ()->factory ()->CopyFixedArray (
3653+ Handle<FixedArray>::cast (elements)));
3654+ }
3655+ }
3656+
36183657void TranslatedState::EnsureChildrenAllocated (int count, TranslatedFrame* frame,
36193658 int * value_index,
36203659 std::stack<int >* worklist) {
@@ -3680,6 +3719,7 @@ Handle<ByteArray> TranslatedState::AllocateStorageFor(TranslatedValue* slot) {
36803719
36813720void TranslatedState::EnsureJSObjectAllocated (TranslatedValue* slot,
36823721 Handle<Map> map) {
3722+ CHECK (map->IsJSObjectMap ());
36833723 CHECK_EQ (map->instance_size (), slot->GetChildrenCount () * kPointerSize );
36843724
36853725 Handle<ByteArray> object_storage = AllocateStorageFor (slot);
0 commit comments