Bug 1474793 - Part 11: Add FFI API to use SharedMemoryBuilder. r=emilio
authorCameron McCormack <cam@mcc.id.au>
Sat, 30 Mar 2019 00:16:27 +0000
changeset 466907 e450b952d748478689a83dd2dd1914ad80fdc6fe
parent 466906 7c9ebe38c5a98ed59d1df0d2b769d6e8d5fd4083
child 466908 7d7b50ad974a1a9d2a77e5f6187d782233fbcc22
push id112603
push usernerli@mozilla.com
push dateSat, 30 Mar 2019 09:35:57 +0000
treeherdermozilla-inbound@7c3183c56eb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemilio
bugs1474793
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1474793 - Part 11: Add FFI API to use SharedMemoryBuilder. r=emilio Depends on D17197 Differential Revision: https://phabricator.services.mozilla.com/D17198
Cargo.lock
layout/style/ServoBindingTypes.h
layout/style/ServoBindings.h
servo/components/style/gecko/boxed_types.rs
servo/components/style/gecko/mod.rs
servo/ports/geckolib/Cargo.toml
servo/ports/geckolib/glue.rs
servo/ports/geckolib/lib.rs
servo/ports/geckolib/tests/Cargo.toml
servo/ports/geckolib/tests/lib.rs
servo/tests/unit/style/Cargo.toml
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1182,16 +1182,17 @@ dependencies = [
  "nsstring 0.1.0",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.21.0",
  "servo_arc 0.1.1",
  "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
+ "to_shmem 0.0.1",
 ]
 
 [[package]]
 name = "generic-array"
 version = "0.9.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2787,16 +2788,17 @@ dependencies = [
  "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "selectors 0.21.0",
  "size_of_test 0.0.1",
  "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
+ "to_shmem 0.0.1",
 ]
 
 [[package]]
 name = "syn"
 version = "0.13.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
--- a/layout/style/ServoBindingTypes.h
+++ b/layout/style/ServoBindingTypes.h
@@ -175,16 +175,17 @@ SERVO_ARC_TYPE(ComputedStyle, mozilla::C
     void operator()(type_* aPtr) const {                            \
       Servo_##name_##_Drop(mozilla::StyleOwned<type_>{aPtr});       \
     }                                                               \
   };                                                                \
   }
 SERVO_BOXED_TYPE(StyleSet, RawServoStyleSet)
 SERVO_BOXED_TYPE(AuthorStyles, RawServoAuthorStyles)
 SERVO_BOXED_TYPE(SelectorList, RawServoSelectorList)
+SERVO_BOXED_TYPE(SharedMemoryBuilder, RawServoSharedMemoryBuilder)
 SERVO_BOXED_TYPE(SourceSizeList, RawServoSourceSizeList)
 SERVO_BOXED_TYPE(UseCounters, StyleUseCounters)
 #undef SERVO_BOXED_TYPE
 
 #pragma GCC diagnostic pop
 
 // Other special cases.
 
--- a/layout/style/ServoBindings.h
+++ b/layout/style/ServoBindings.h
@@ -997,13 +997,23 @@ bool Servo_IsCssPropertyRecordedInUseCou
 
 mozilla::StyleStrong<RawServoQuotes> Servo_Quotes_GetInitialValue();
 bool Servo_Quotes_Equal(const RawServoQuotes* a, RawServoQuotes* b);
 
 void Servo_Quotes_GetQuote(const RawServoQuotes* quotes, int32_t depth,
                            mozilla::StyleContentType quote_type,
                            nsAString* result);
 
+RawServoSharedMemoryBuilder* Servo_SharedMemoryBuilder_Create(uint8_t* buffer,
+                                                              size_t len);
+
+const ServoCssRules* Servo_SharedMemoryBuilder_AddStylesheet(
+    RawServoSharedMemoryBuilder* builder,
+    const RawServoStyleSheetContents* sheet);
+
+size_t Servo_SharedMemoryBuilder_GetLength(
+    RawServoSharedMemoryBuilder* builder);
+
 }  // extern "C"
 
 #pragma GCC diagnostic pop
 
 #endif  // mozilla_ServoBindings_h
new file mode 100644
--- /dev/null
+++ b/servo/components/style/gecko/boxed_types.rs
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+//! FFI implementations for types listed in ServoBoxedTypeList.h.
+
+use crate::gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI};
+use to_shmem::SharedMemoryBuilder;
+
+// TODO(heycam): The FFI impls for most of the types in ServoBoxedTypeList.h are spread across
+// various files at the moment, but should probably all move here, and use macros to define
+// them more succinctly, like we do in arc_types.rs.
+
+#[cfg(feature = "gecko")]
+unsafe impl HasFFI for SharedMemoryBuilder {
+    type FFIType = crate::gecko_bindings::bindings::RawServoSharedMemoryBuilder;
+}
+#[cfg(feature = "gecko")]
+unsafe impl HasSimpleFFI for SharedMemoryBuilder {}
+#[cfg(feature = "gecko")]
+unsafe impl HasBoxFFI for SharedMemoryBuilder {}
--- a/servo/components/style/gecko/mod.rs
+++ b/servo/components/style/gecko/mod.rs
@@ -3,16 +3,17 @@
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
 
 //! Gecko-specific style-system bits.
 
 #[macro_use]
 mod non_ts_pseudo_class_list;
 
 pub mod arc_types;
+pub mod boxed_types;
 pub mod conversions;
 pub mod data;
 pub mod media_features;
 pub mod media_queries;
 pub mod pseudo_element;
 pub mod restyle_damage;
 pub mod rules;
 pub mod selector_parser;
--- a/servo/ports/geckolib/Cargo.toml
+++ b/servo/ports/geckolib/Cargo.toml
@@ -22,8 +22,9 @@ malloc_size_of = {path = "../../componen
 nsstring = {path = "../../../xpcom/rust/nsstring/"}
 num-traits = "0.2"
 parking_lot = "0.6"
 selectors = {path = "../../components/selectors"}
 servo_arc = {path = "../../components/servo_arc"}
 smallvec = "0.6"
 style = {path = "../../components/style", features = ["gecko"]}
 style_traits = {path = "../../components/style_traits"}
+to_shmem = {path = "../../components/to_shmem"}
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -50,17 +50,18 @@ use style::gecko_bindings::structs;
 use style::gecko_bindings::structs::{Element as RawGeckoElement, nsINode as RawGeckoNode};
 use style::gecko_bindings::structs::{
     RawServoQuotes, RawServoStyleSet, RawServoAuthorStyles,
     RawServoCssUrlData, RawServoDeclarationBlock, RawServoMediaList,
     RawServoCounterStyleRule, RawServoAnimationValue, RawServoSupportsRule,
     RawServoKeyframesRule, ServoCssRules, RawServoStyleSheetContents,
     RawServoPageRule, RawServoNamespaceRule, RawServoMozDocumentRule,
     RawServoKeyframe, RawServoMediaRule, RawServoImportRule,
-    RawServoFontFaceRule, RawServoFontFeatureValuesRule
+    RawServoFontFaceRule, RawServoFontFeatureValuesRule,
+    RawServoSharedMemoryBuilder
 };
 use style::gecko_bindings::structs::gfxFontFeatureValueSet;
 use style::gecko_bindings::structs::nsAtom;
 use style::gecko_bindings::structs::nsCSSCounterDesc;
 use style::gecko_bindings::structs::nsCSSFontDesc;
 use style::gecko_bindings::structs::nsCSSPropertyID;
 use style::gecko_bindings::structs::nsCSSValueSharedList;
 use style::gecko_bindings::structs::nsChangeHint;
@@ -102,17 +103,17 @@ use style::global_style_data::{GlobalSty
 use style::invalidation::element::restyle_hints::RestyleHint;
 use style::media_queries::MediaList;
 use style::parser::{self, Parse, ParserContext};
 use style::properties::animated_properties::AnimationValue;
 use style::properties::{parse_one_declaration_into, parse_style_attribute};
 use style::properties::{ComputedValues, Importance, NonCustomPropertyId};
 use style::properties::{LonghandId, LonghandIdSet, PropertyDeclarationBlock, PropertyId};
 use style::properties::{PropertyDeclarationId, ShorthandId};
-use style::properties::{SourcePropertyDeclaration, StyleBuilder};
+use style::properties::{SourcePropertyDeclaration, StyleBuilder, UnparsedValue};
 use style::rule_cache::RuleCacheConditions;
 use style::rule_tree::{CascadeLevel, StrongRuleNode};
 use style::selector_parser::{PseudoElementCascadeType, SelectorImpl};
 use style::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard};
 use style::string_cache::{Atom, WeakAtom};
 use style::style_adjuster::StyleAdjuster;
 use style::stylesheets::import_rule::ImportSheet;
 use style::stylesheets::keyframes_rule::{Keyframe, KeyframeSelector, KeyframesStepValue};
@@ -132,16 +133,17 @@ use style::use_counters::UseCounters;
 use style::values::animated::{Animate, Procedure, ToAnimatedZero};
 use style::values::computed::{self, Context, QuotePair, ToComputedValue};
 use style::values::distance::ComputeSquaredDistance;
 use style::values::specified;
 use style::values::specified::gecko::IntersectionObserverRootMargin;
 use style::values::specified::source_size_list::SourceSizeList;
 use style::values::{CustomIdent, KeyframesName};
 use style_traits::{CssWriter, ParsingMode, StyleParseErrorKind, ToCss};
+use to_shmem::SharedMemoryBuilder;
 
 trait ClosureHelper {
     fn invoke(&self);
 }
 
 impl ClosureHelper for DeclarationBlockMutationClosure {
     #[inline]
     fn invoke(&self) {
@@ -6332,8 +6334,60 @@ pub unsafe extern "C" fn Servo_Quotes_Ge
     let quote = if quote_type == StyleContentType::OpenQuote {
         &quote_pair.opening
     } else {
         debug_assert!(quote_type == StyleContentType::CloseQuote);
         &quote_pair.closing
     };
     (*result).write_str(quote).unwrap();
 }
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_SharedMemoryBuilder_Create(
+    buffer: *mut u8,
+    len: usize,
+) -> *mut RawServoSharedMemoryBuilder {
+    let mut builder = Box::new(SharedMemoryBuilder::new(buffer, len));
+
+    // We have Arc<UnparsedValue>s in style sheets due to CSS variables being
+    // used in shorthand property declarations.  There aren't many, though,
+    // and they aren't big, so we just allow their duplication for now.
+    builder.add_allowed_duplication_type::<UnparsedValue>();
+
+    Box::into_raw(builder) as *mut _
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_SharedMemoryBuilder_AddStylesheet(
+    builder: &mut RawServoSharedMemoryBuilder,
+    raw_contents: &RawServoStyleSheetContents,
+) -> *const ServoCssRules {
+    let builder = SharedMemoryBuilder::from_ffi_mut(builder);
+    let contents = StylesheetContents::as_arc(&raw_contents);
+
+    // Assert some things we assume when we create a style sheet from shared
+    // memory.
+    debug_assert_eq!(contents.origin, Origin::UserAgent);
+    debug_assert_eq!(contents.quirks_mode, QuirksMode::NoQuirks);
+    debug_assert!(contents.source_map_url.read().is_none());
+    debug_assert!(contents.source_url.read().is_none());
+
+    let rules = &contents.rules;
+    let shared_rules: &Arc<Locked<CssRules>> = &*builder.write(rules);
+    (&*shared_rules).with_raw_offset_arc(|arc| {
+        *Locked::<CssRules>::arc_as_borrowed(arc) as *const _
+    })
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_SharedMemoryBuilder_GetLength(
+    builder: &mut RawServoSharedMemoryBuilder,
+) -> usize {
+    let builder = SharedMemoryBuilder::from_ffi_mut(builder);
+    builder.len()
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn Servo_SharedMemoryBuilder_Drop(
+    builder: Owned<RawServoSharedMemoryBuilder>
+) {
+    let _ = builder.into_box::<SharedMemoryBuilder>();
+}
--- a/servo/ports/geckolib/lib.rs
+++ b/servo/ports/geckolib/lib.rs
@@ -12,16 +12,17 @@ extern crate malloc_size_of;
 extern crate nsstring;
 extern crate num_traits;
 extern crate selectors;
 extern crate servo_arc;
 extern crate smallvec;
 #[macro_use]
 extern crate style;
 extern crate style_traits;
+extern crate to_shmem;
 
 mod error_reporter;
 #[allow(non_snake_case)]
 pub mod glue;
 mod stylesheet_loader;
 
 // FIXME(bholley): This should probably go away once we harmonize the allocators.
 #[no_mangle]
--- a/servo/ports/geckolib/tests/Cargo.toml
+++ b/servo/ports/geckolib/tests/Cargo.toml
@@ -19,8 +19,9 @@ libc = "0.2"
 log = {version = "0.4", features = ["release_max_level_info"]}
 malloc_size_of = {path = "../../../components/malloc_size_of"}
 num-traits = "0.2"
 selectors = {path = "../../../components/selectors"}
 size_of_test = {path = "../../../components/size_of_test"}
 smallvec = "0.6"
 style_traits = {path = "../../../components/style_traits"}
 style = {path = "../../../components/style", features = ["gecko"]}
+to_shmem = {path = "../../../components/to_shmem"}
--- a/servo/ports/geckolib/tests/lib.rs
+++ b/servo/ports/geckolib/tests/lib.rs
@@ -21,12 +21,13 @@ extern crate num_traits;
 extern crate selectors;
 extern crate smallvec;
 #[cfg(target_pointer_width = "64")]
 #[macro_use]
 extern crate size_of_test;
 #[cfg_attr(target_pointer_width = "64", macro_use)]
 extern crate style;
 extern crate style_traits;
+extern crate to_shmem;
 
 #[cfg(target_pointer_width = "64")]
 mod size_of;
 mod specified_values;
--- a/servo/tests/unit/style/Cargo.toml
+++ b/servo/tests/unit/style/Cargo.toml
@@ -22,8 +22,9 @@ selectors = {path = "../../../components
 servo_arc = {path = "../../../components/servo_arc"}
 servo_atoms = {path = "../../../components/atoms"}
 servo_config = {path = "../../../components/config"}
 servo_url = {path = "../../../components/url"}
 size_of_test = {path = "../../../components/size_of_test"}
 style = {path = "../../../components/style"}
 style_traits = {path = "../../../components/style_traits"}
 std_test_override = { path = "../../../components/std_test_override" }
+to_shmem = { path = "../../../components/to_shmem" }