diff options
author | Simon Wülker <simon.wuelker@arcor.de> | 2025-01-22 15:50:37 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-01-22 14:50:37 +0000 |
commit | aed7e8cefd054995da4a448be7b734d956e9e11a (patch) | |
tree | cacc83356f157710d79a1522f01cc7072bd2dd18 /components/script/dom | |
parent | e74539404467cc31c03f52a419371258235a1d69 (diff) | |
download | servo-aed7e8cefd054995da4a448be7b734d956e9e11a.tar.gz servo-aed7e8cefd054995da4a448be7b734d956e9e11a.zip |
Remove BlobState abstraction (#35114)
The BlobState enum was used to track whether a GlobalScope
was managing any blobs (effectively like an `Option<HashMap>`,
being `None` if no blobs are being managed)
This is a pointless abstraction, as a HashMap is already allowed
to be empty. Removing `BlobState` and just using a
HashMap directly reduces noise and panic! invocations when
working with the blob store.
Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
Diffstat (limited to 'components/script/dom')
-rw-r--r-- | components/script/dom/globalscope.rs | 310 |
1 files changed, 128 insertions, 182 deletions
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 22edc0bbcdf..fc42131fc37 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -203,7 +203,7 @@ pub(crate) struct GlobalScope { broadcast_channel_state: DomRefCell<BroadcastChannelState>, /// The blobs managed by this global, if any. - blob_state: DomRefCell<BlobState>, + blob_state: DomRefCell<HashMapTracedValues<BlobId, BlobInfo>>, /// <https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-registration-object-map> registration_map: DomRefCell< @@ -428,15 +428,6 @@ pub(crate) struct BlobInfo { has_url: bool, } -/// State representing whether this global is currently managing blobs. -#[derive(JSTraceable, MallocSizeOf)] -pub(crate) enum BlobState { - /// A map of managed blobs. - Managed(HashMapTracedValues<BlobId, BlobInfo>), - /// This global is not managing any blobs at this time. - UnManaged, -} - /// The result of looking-up the data for a Blob, /// containing either the in-memory bytes, /// or the file-id. @@ -721,7 +712,7 @@ impl GlobalScope { task_manager: Default::default(), message_port_state: DomRefCell::new(MessagePortState::UnManaged), broadcast_channel_state: DomRefCell::new(BroadcastChannelState::UnManaged), - blob_state: DomRefCell::new(BlobState::UnManaged), + blob_state: Default::default(), eventtarget: EventTarget::new_inherited(), crypto: Default::default(), registration_map: DomRefCell::new(HashMapTracedValues::new()), @@ -1499,18 +1490,7 @@ impl GlobalScope { } fn track_blob_info(&self, blob_info: BlobInfo, blob_id: BlobId) { - let mut blob_state = self.blob_state.borrow_mut(); - - match &mut *blob_state { - BlobState::UnManaged => { - let mut blobs_map = HashMapTracedValues::new(); - blobs_map.insert(blob_id, blob_info); - *blob_state = BlobState::Managed(blobs_map); - }, - BlobState::Managed(blobs_map) => { - blobs_map.insert(blob_id, blob_info); - }, - } + self.blob_state.borrow_mut().insert(blob_id, blob_info); } /// Start tracking a blob @@ -1544,39 +1524,33 @@ impl GlobalScope { /// <https://w3c.github.io/FileAPI/#lifeTime> fn perform_a_blob_garbage_collection_checkpoint(&self) { let mut blob_state = self.blob_state.borrow_mut(); - if let BlobState::Managed(blobs_map) = &mut *blob_state { - blobs_map.0.retain(|_id, blob_info| { - let garbage_collected = match &blob_info.tracker { - BlobTracker::File(weak) => weak.root().is_none(), - BlobTracker::Blob(weak) => weak.root().is_none(), - }; - if garbage_collected && !blob_info.has_url { - if let BlobData::File(ref f) = blob_info.blob_impl.blob_data() { - self.decrement_file_ref(f.get_id()); - } - false - } else { - true + blob_state.0.retain(|_id, blob_info| { + let garbage_collected = match &blob_info.tracker { + BlobTracker::File(weak) => weak.root().is_none(), + BlobTracker::Blob(weak) => weak.root().is_none(), + }; + if garbage_collected && !blob_info.has_url { + if let BlobData::File(ref f) = blob_info.blob_impl.blob_data() { + self.decrement_file_ref(f.get_id()); } - }); - if blobs_map.is_empty() { - *blob_state = BlobState::UnManaged; + false + } else { + true } - } + }); } /// Clean-up all file related resources on document unload. /// <https://w3c.github.io/FileAPI/#lifeTime> pub(crate) fn clean_up_all_file_resources(&self) { - let mut blob_state = self.blob_state.borrow_mut(); - if let BlobState::Managed(blobs_map) = &mut *blob_state { - blobs_map.drain().for_each(|(_id, blob_info)| { + self.blob_state + .borrow_mut() + .drain() + .for_each(|(_id, blob_info)| { if let BlobData::File(ref f) = blob_info.blob_impl.blob_data() { self.decrement_file_ref(f.get_id()); } }); - } - *blob_state = BlobState::UnManaged; } fn decrement_file_ref(&self, id: Uuid) { @@ -1594,16 +1568,12 @@ impl GlobalScope { pub(crate) fn get_blob_bytes(&self, blob_id: &BlobId) -> Result<Vec<u8>, ()> { let parent = { let blob_state = self.blob_state.borrow(); - if let BlobState::Managed(blobs_map) = &*blob_state { - let blob_info = blobs_map - .get(blob_id) - .expect("get_blob_bytes for an unknown blob."); - match blob_info.blob_impl.blob_data() { - BlobData::Sliced(ref parent, ref rel_pos) => Some((*parent, rel_pos.clone())), - _ => None, - } - } else { - panic!("get_blob_bytes called on a global not managing any blobs."); + let blob_info = blob_state + .get(blob_id) + .expect("get_blob_bytes for an unknown blob."); + match blob_info.blob_impl.blob_data() { + BlobData::Sliced(ref parent, ref rel_pos) => Some((*parent, rel_pos.clone())), + _ => None, } }; @@ -1619,32 +1589,28 @@ impl GlobalScope { /// Get bytes from a non-sliced blob fn get_blob_bytes_non_sliced(&self, blob_id: &BlobId) -> Result<Vec<u8>, ()> { let blob_state = self.blob_state.borrow(); - if let BlobState::Managed(blobs_map) = &*blob_state { - let blob_info = blobs_map - .get(blob_id) - .expect("get_blob_bytes_non_sliced called for a unknown blob."); - match blob_info.blob_impl.blob_data() { - BlobData::File(ref f) => { - let (buffer, is_new_buffer) = match f.get_cache() { - Some(bytes) => (bytes, false), - None => { - let bytes = self.read_file(f.get_id())?; - (bytes, true) - }, - }; + let blob_info = blob_state + .get(blob_id) + .expect("get_blob_bytes_non_sliced called for a unknown blob."); + match blob_info.blob_impl.blob_data() { + BlobData::File(ref f) => { + let (buffer, is_new_buffer) = match f.get_cache() { + Some(bytes) => (bytes, false), + None => { + let bytes = self.read_file(f.get_id())?; + (bytes, true) + }, + }; - // Cache - if is_new_buffer { - f.cache_bytes(buffer.clone()); - } + // Cache + if is_new_buffer { + f.cache_bytes(buffer.clone()); + } - Ok(buffer) - }, - BlobData::Memory(ref s) => Ok(s.clone()), - BlobData::Sliced(_, _) => panic!("This blob doesn't have a parent."), - } - } else { - panic!("get_blob_bytes_non_sliced called on a global not managing any blobs."); + Ok(buffer) + }, + BlobData::Memory(ref s) => Ok(s.clone()), + BlobData::Sliced(_, _) => panic!("This blob doesn't have a parent."), } } @@ -1657,16 +1623,12 @@ impl GlobalScope { fn get_blob_bytes_or_file_id(&self, blob_id: &BlobId) -> BlobResult { let parent = { let blob_state = self.blob_state.borrow(); - if let BlobState::Managed(blobs_map) = &*blob_state { - let blob_info = blobs_map - .get(blob_id) - .expect("get_blob_bytes_or_file_id for an unknown blob."); - match blob_info.blob_impl.blob_data() { - BlobData::Sliced(ref parent, ref rel_pos) => Some((*parent, rel_pos.clone())), - _ => None, - } - } else { - panic!("get_blob_bytes_or_file_id called on a global not managing any blobs."); + let blob_info = blob_state + .get(blob_id) + .expect("get_blob_bytes_or_file_id for an unknown blob."); + match blob_info.blob_impl.blob_data() { + BlobData::Sliced(ref parent, ref rel_pos) => Some((*parent, rel_pos.clone())), + _ => None, } }; @@ -1691,121 +1653,105 @@ impl GlobalScope { /// TODO: merge with `get_blob_bytes` by way of broader integration with blob streams. fn get_blob_bytes_non_sliced_or_file_id(&self, blob_id: &BlobId) -> BlobResult { let blob_state = self.blob_state.borrow(); - if let BlobState::Managed(blobs_map) = &*blob_state { - let blob_info = blobs_map - .get(blob_id) - .expect("get_blob_bytes_non_sliced_or_file_id called for a unknown blob."); - match blob_info.blob_impl.blob_data() { - BlobData::File(ref f) => match f.get_cache() { - Some(bytes) => BlobResult::Bytes(bytes.clone()), - None => BlobResult::File(f.get_id(), f.get_size() as usize), - }, - BlobData::Memory(ref s) => BlobResult::Bytes(s.clone()), - BlobData::Sliced(_, _) => panic!("This blob doesn't have a parent."), - } - } else { - panic!( - "get_blob_bytes_non_sliced_or_file_id called on a global not managing any blobs." - ); + let blob_info = blob_state + .get(blob_id) + .expect("get_blob_bytes_non_sliced_or_file_id called for a unknown blob."); + match blob_info.blob_impl.blob_data() { + BlobData::File(ref f) => match f.get_cache() { + Some(bytes) => BlobResult::Bytes(bytes.clone()), + None => BlobResult::File(f.get_id(), f.get_size() as usize), + }, + BlobData::Memory(ref s) => BlobResult::Bytes(s.clone()), + BlobData::Sliced(_, _) => panic!("This blob doesn't have a parent."), } } /// Get a copy of the type_string of a blob. pub(crate) fn get_blob_type_string(&self, blob_id: &BlobId) -> String { let blob_state = self.blob_state.borrow(); - if let BlobState::Managed(blobs_map) = &*blob_state { - let blob_info = blobs_map - .get(blob_id) - .expect("get_blob_type_string called for a unknown blob."); - blob_info.blob_impl.type_string() - } else { - panic!("get_blob_type_string called on a global not managing any blobs."); - } + let blob_info = blob_state + .get(blob_id) + .expect("get_blob_type_string called for a unknown blob."); + blob_info.blob_impl.type_string() } /// <https://w3c.github.io/FileAPI/#dfn-size> pub(crate) fn get_blob_size(&self, blob_id: &BlobId) -> u64 { let blob_state = self.blob_state.borrow(); - if let BlobState::Managed(blobs_map) = &*blob_state { - let parent = { - let blob_info = blobs_map + let parent = { + let blob_info = blob_state + .get(blob_id) + .expect("get_blob_size called for a unknown blob."); + match blob_info.blob_impl.blob_data() { + BlobData::Sliced(ref parent, ref rel_pos) => Some((*parent, rel_pos.clone())), + _ => None, + } + }; + match parent { + Some((parent_id, rel_pos)) => { + let parent_info = blob_state + .get(&parent_id) + .expect("Parent of blob whose size is unknown."); + let parent_size = match parent_info.blob_impl.blob_data() { + BlobData::File(ref f) => f.get_size(), + BlobData::Memory(ref v) => v.len() as u64, + BlobData::Sliced(_, _) => panic!("Blob ancestry should be only one level."), + }; + rel_pos.to_abs_range(parent_size as usize).len() as u64 + }, + None => { + let blob_info = blob_state .get(blob_id) - .expect("get_blob_size called for a unknown blob."); + .expect("Blob whose size is unknown."); match blob_info.blob_impl.blob_data() { - BlobData::Sliced(ref parent, ref rel_pos) => Some((*parent, rel_pos.clone())), - _ => None, + BlobData::File(ref f) => f.get_size(), + BlobData::Memory(ref v) => v.len() as u64, + BlobData::Sliced(_, _) => { + panic!("It was previously checked that this blob does not have a parent.") + }, } - }; - match parent { - Some((parent_id, rel_pos)) => { - let parent_info = blobs_map - .get(&parent_id) - .expect("Parent of blob whose size is unknown."); - let parent_size = match parent_info.blob_impl.blob_data() { - BlobData::File(ref f) => f.get_size(), - BlobData::Memory(ref v) => v.len() as u64, - BlobData::Sliced(_, _) => panic!("Blob ancestry should be only one level."), - }; - rel_pos.to_abs_range(parent_size as usize).len() as u64 - }, - None => { - let blob_info = blobs_map.get(blob_id).expect("Blob whose size is unknown."); - match blob_info.blob_impl.blob_data() { - BlobData::File(ref f) => f.get_size(), - BlobData::Memory(ref v) => v.len() as u64, - BlobData::Sliced(_, _) => panic!( - "It was previously checked that this blob does not have a parent." - ), - } - }, - } - } else { - panic!("get_blob_size called on a global not managing any blobs."); + }, } } pub(crate) fn get_blob_url_id(&self, blob_id: &BlobId) -> Uuid { let mut blob_state = self.blob_state.borrow_mut(); - if let BlobState::Managed(blobs_map) = &mut *blob_state { - let parent = { - let blob_info = blobs_map - .get_mut(blob_id) - .expect("get_blob_url_id called for a unknown blob."); + let parent = { + let blob_info = blob_state + .get_mut(blob_id) + .expect("get_blob_url_id called for a unknown blob."); - // Keep track of blobs with outstanding URLs. - blob_info.has_url = true; + // Keep track of blobs with outstanding URLs. + blob_info.has_url = true; - match blob_info.blob_impl.blob_data() { - BlobData::Sliced(ref parent, ref rel_pos) => Some((*parent, rel_pos.clone())), - _ => None, - } - }; - match parent { - Some((parent_id, rel_pos)) => { - let parent_info = blobs_map - .get_mut(&parent_id) - .expect("Parent of blob whose url is requested is unknown."); - let parent_file_id = self.promote(parent_info, /* set_valid is */ false); - let parent_size = match parent_info.blob_impl.blob_data() { - BlobData::File(ref f) => f.get_size(), - BlobData::Memory(ref v) => v.len() as u64, - BlobData::Sliced(_, _) => panic!("Blob ancestry should be only one level."), - }; - let parent_size = rel_pos.to_abs_range(parent_size as usize).len() as u64; - let blob_info = blobs_map - .get_mut(blob_id) - .expect("Blob whose url is requested is unknown."); - self.create_sliced_url_id(blob_info, &parent_file_id, &rel_pos, parent_size) - }, - None => { - let blob_info = blobs_map - .get_mut(blob_id) - .expect("Blob whose url is requested is unknown."); - self.promote(blob_info, /* set_valid is */ true) - }, + match blob_info.blob_impl.blob_data() { + BlobData::Sliced(ref parent, ref rel_pos) => Some((*parent, rel_pos.clone())), + _ => None, } - } else { - panic!("get_blob_url_id called on a global not managing any blobs."); + }; + match parent { + Some((parent_id, rel_pos)) => { + let parent_info = blob_state + .get_mut(&parent_id) + .expect("Parent of blob whose url is requested is unknown."); + let parent_file_id = self.promote(parent_info, /* set_valid is */ false); + let parent_size = match parent_info.blob_impl.blob_data() { + BlobData::File(ref f) => f.get_size(), + BlobData::Memory(ref v) => v.len() as u64, + BlobData::Sliced(_, _) => panic!("Blob ancestry should be only one level."), + }; + let parent_size = rel_pos.to_abs_range(parent_size as usize).len() as u64; + let blob_info = blob_state + .get_mut(blob_id) + .expect("Blob whose url is requested is unknown."); + self.create_sliced_url_id(blob_info, &parent_file_id, &rel_pos, parent_size) + }, + None => { + let blob_info = blob_state + .get_mut(blob_id) + .expect("Blob whose url is requested is unknown."); + self.promote(blob_info, /* set_valid is */ true) + }, } } |