| Index: content/renderer/history_entry.cc
|
| diff --git a/content/renderer/history_entry.cc b/content/renderer/history_entry.cc
|
| index 63c1ea0f1d3d588bde9a13ecb150b71065a2f955..67806342bed91d4f25e709f0783735a5200f571b 100644
|
| --- a/content/renderer/history_entry.cc
|
| +++ b/content/renderer/history_entry.cc
|
| @@ -44,6 +44,16 @@ using blink::WebHistoryItem;
|
|
|
| namespace content {
|
|
|
| +// Frame routing ids are not safe to serialize, so instead create a mapping
|
| +// from routing ids to frame sequence numbers. The sequence numbers can be
|
| +// benignly serialized with limited risk of collision in a different process.
|
| +// FrameMap is a singleton per-process.
|
| +typedef base::hash_map<uint64_t, uint64_t> FrameMap;
|
| +static FrameMap& GetFrameMap() {
|
| + CR_DEFINE_STATIC_LOCAL(FrameMap, routing_ids_to_internal_frame_ids, ());
|
| + return routing_ids_to_internal_frame_ids;
|
| +}
|
| +
|
| HistoryEntry::HistoryNode* HistoryEntry::HistoryNode::AddChild(
|
| const WebHistoryItem& item,
|
| int64_t frame_id) {
|
| @@ -96,6 +106,7 @@ void HistoryEntry::HistoryNode::set_item(const WebHistoryItem& item) {
|
| // The previous HistoryItem might not have had a target set, or it might be
|
| // different than the current one.
|
| entry_->unique_names_to_items_[item.target().utf8()] = this;
|
| + entry_->frames_to_items_[item.frameSequenceNumber()] = this;
|
| item_ = item;
|
| }
|
|
|
| @@ -103,10 +114,20 @@ HistoryEntry::HistoryNode::HistoryNode(HistoryEntry* entry,
|
| const WebHistoryItem& item,
|
| int64_t frame_id)
|
| : entry_(entry), item_(item) {
|
| - if (frame_id != kInvalidFrameRoutingID)
|
| - entry_->frames_to_items_[frame_id] = this;
|
| - if (!item.isNull())
|
| - entry_->unique_names_to_items_[item.target().utf8()] = this;
|
| + if (frame_id != kInvalidFrameRoutingID) {
|
| + // Each history item is given a frame sequence number on creation.
|
| + // If we've already mapped this frame id to a sequence number, standardize
|
| + // this item to that sequence number. Otherwise, map the frame id to this
|
| + // item's existing sequence number.
|
| + if (GetFrameMap()[frame_id] == 0)
|
| + GetFrameMap()[frame_id] = item_.frameSequenceNumber();
|
| + else if (!item_.isNull())
|
| + item_.setFrameSequenceNumber(GetFrameMap()[frame_id]);
|
| + entry_->frames_to_items_[GetFrameMap()[frame_id]] = this;
|
| + }
|
| +
|
| + if (!item_.isNull())
|
| + entry_->unique_names_to_items_[item_.target().utf8()] = this;
|
| children_.reset(new ScopedVector<HistoryNode>);
|
| }
|
|
|
| @@ -130,7 +151,7 @@ void HistoryEntry::HistoryNode::RemoveChildren() {
|
| it != frames_end;
|
| ++it) {
|
| if (it->second == children().at(i))
|
| - frames_to_remove.push_back(it->first);
|
| + frames_to_remove.push_back(GetFrameMap()[it->first]);
|
| }
|
| for (HistoryEntry::UniqueNamesToItems::iterator it =
|
| entry_->unique_names_to_items_.begin();
|
| @@ -174,7 +195,8 @@ HistoryEntry* HistoryEntry::CloneAndReplace(const WebHistoryItem& new_item,
|
|
|
| HistoryEntry::HistoryNode* HistoryEntry::GetHistoryNodeForFrame(
|
| RenderFrameImpl* frame) {
|
| - if (HistoryNode* history_node = frames_to_items_[frame->GetRoutingID()])
|
| + if (HistoryNode* history_node =
|
| + frames_to_items_[GetFrameMap()[frame->GetRoutingID()]])
|
| return history_node;
|
| return unique_names_to_items_[frame->GetWebFrame()->uniqueName().utf8()];
|
| }
|
|
|