From 6629d22907a17fd571e5b1efb8f334ba35a68389 Mon Sep 17 00:00:00 2001 From: roytam1 Date: Mon, 9 Nov 2020 23:37:50 +0800 Subject: [PATCH] import changes from `dev' branch of rmottola/Arctic-Fox: - Bug 1170717 - Move heapState check up to readBarrier; r=jonco (b9c4df5ea) - Bug 1163908 - Export GL draw data to layerscope for drawing heat-map view. r=:djg (cf078d4fd) - Bug 1161372 - Add EventRegions on LayerScope. r=dglastonbury (49fc29e8a) - Files as of Bug 1138721 - Application reputation should check mac file extensions. r=mmc (4b76de8d8) - Bug 1024774 - Part 0: Upgrade the protobuf library. r=mmc,glandium (c98c08fbd) - Bug 1149397 - JS::ubi::Node::edges should return a mozilla::UniquePtr; r=jimb (32f755867) - Bug 1110039 - Part 1 - Add nsLayoutUtils::ClampRectToScrollFrames. r=roc (a8812c287) - Bug 1110039 - Part 2.1 - Add logger facility. r=roc (1a400bb1f) - Bug 1110039 - Part 2.2 - Add AccessibleCaret. r=roc (d8c2c759f) - Bug 1110039 - Part 2.3 - Add AccessibleCaretManager. r=roc (ba8ad6424) - Bug 1110039 - Part 2.4 - Add AccessibleCaretEventHub. r=roc (db4ef1fe6) - Bug 1110039 - Part 2.5 - Add all files to build system. r=roc (bee54dc43) - fix nsRefPtr includes - but build still broken (423d9f32d) - Bug 1110039 - Part 3 - Add gtest for AccessibleCaretEventHub. r=roc (cdf0df240) - Bug 1110039 - Part 4 - Hook new classes into the system. r=roc (438a4df68) - Bug 1109183 - Fix imports of the marionette client and remove spurious entry from sys.path provided by mach. r=ahal (86b814562) - Bug 1110039 - Part 5 - Reuse marionette tests for AccessibleCaret. r=roc (d5cd35016) - Bug 1110039 followup: Add 'override' keyword to Name() decl in Access# (cd0d9b0f6) - Bug 1140994 - Notify gaia to hide selection bubble when scrolling without APZ. r=roc (ca15626fa) - Bug 1143665 - Remove the ambiguous scroll position being passed around in scroll started/stop notifications. r=roc,ehsan (ce8f1d2a9) - Bug 1140238 - Part 1: Add a test to drag first caret over non-selectable. r=automatedtester (4080723fe) - Bug 1140238 - Part 2: Adjust ranges after changing selection direction. r=mats (add1f155d) - Bug 1140238 - Part 3: Clear maintain selection when dragging caret. r=mats (0aba36f24) - Bug 1024774 - Part 2: Implement a google::protobuf::ZeroCopyOutputStream wrapper around nsIOutputStream; r=jimb (30c6272d2) - Bug 1024774 - Part 3: Serialize heap snapshots. r=jimb (9d0c8f6ec) - Bug 1024774 - Part 1: Add the ChromeUtils WebIDL interface. r=bholley (8e81e8344) - Bug 1024774 - Part 4: Add an xpcshell test for saving heap snapshots. r=jimb (6e0a07069) - Bug 1024774 - Part 5: Add GTests for core dump serialization. r=jimb (79315c540) - clean up spurious char (9a1f9bc18) - Bug 1121528 - Avoid the inspector going blank when quickly navigating; r=bgrins (f4cff269f) - Bug 1155168 - Always use the same actor pool. r=ochameau (3e6cc5504) - Bug 1137527 - Part 1: Make the memory actor emit events for garbage collection. r=jryans (6dcdb18f8) - Bug 1137527 - Part 2: Add a test for GC MemoryActor events. r=jryans (df2bcf120) - Bug 1024774 - Part 6: Add a mochitest-chrome sanity check test. r=bholley (4b5bffe79) - Bug 1024774 - Part 7: Add HeapSnapshot WebIDL interface; r=bholley (7b5ae703a) - Bug 1024774 - Part 8: Add JS::ubi::Node::isLive; r=jimb (42a965f56) - Bug 1024774 - Part 9: Deserialize heap snapshots; r=jimb (fb3edfbc0) - Bug 1024774 - Part 10: Add an xpcshell test for reading heap snapshots. r=jimb (09c3390a1) - Bug 1024774 - Part 11: Implement a JS::ubi::Node specialization for DeserializedNode; r=jimb (d73362efe) - Bug 1024774 - Part 12: Add a GTest for the JS::ubi::Node specialization for DeserializedNode; r=jimb (4415acb73) - Bug 1024774 - Part 13: Change to new SpiderMonkey style from bug 1144366; r=me (15c4bcf87) - Bug 1024774 - Part 14: Ignore protobuf indirect calls in the GC hazard analysis; r=sfink (c5b141c59) - Bug 1024774 - Followup: Don't redefine the Debugger property in xpcshell tests; r=jorendorff (dc4f1f109) - Bug 1169791 - Strongly type NoteJSRoot; r=mccr8 (ba722a44f) - Bug 1169791 - Strongly type MergeZone; r=mccr8 (a118cf612) - Bug 1169791 - Strongly type GetTenuredGCThingZone; r=jonco, r=mccr8 (a4da82aea) - Bug 1171780 - We no longer need to cast out of barrieried types in GC; r=jonco (be83218fa) - Bug 1144361: Re-enable JIT code randomization on Win64. r=jandem (6c88b4312) - pointer style (458344bcd) - Bug 1156914 - Fix the MacroAssembler::pushValue(const Address&) footgun on 32 bit platforms. (r=jandem) (52d5c351d) - Bug 1156030 - Remove some obsolete static assertion macros from the tree; r=Waldo (84d8f3fea) - pointer style (ac3c92ce1) - Bug 1151323 - Handle loading unboxed int32 properties into floating point registers, r=jandem. (790920f3d) - Bug 1023297 - Use explicit constructors for ARM-specific classes. r=jandem (f7f12cd76) - Bug 1164229 - Rename ARM SetCond_ to SBit. r=efaust (c55e1d535) - Bug 977805 - Add an option to mark JIT pages as non-writable. r=luke bug 977805 - add missing #include. r=jandem (384abd6ad) - Bug 1173992 - Add ARM64 build support. r=glandium (540a7c784) - Bug 1170750 - Replace %f by %.16g in js/src. r=jandem (48f808c73) - Bug 1170750 - Use mfbt snprintf_literal instead of sprintf. r=jandem (3b2016484) - Bug 1170750 - jsprf.cpp: Sort headers properly. r=me (0956cd3a5) - Bug 923717 - Use structured control flow when testing for the forceInlineCaches option, r=nbp. (fc1dcef6e) - Bug 1158044 - Remove unused TypeWrapper class and untemplatize/cleanup some code. r=bhackett (a4d5de646) - Bug 1169355 - Remove unnecessary assertion, r=jandem. (f55c99552) - Bug 1162986 - Allow objects to be turned into singletons dynamically, r=jandem. (9c683e420) - Bug 1169731 - [[Call]] on a class constructor should throw. (r=jandem) (470895e3f) and fix for shared-js in UbiNode.h --- build/mach_bootstrap.py | 1 - configure.in | 1 + docshell/base/nsDocShell.cpp | 12 +- docshell/base/nsDocShell.h | 4 +- docshell/base/nsIScrollObserver.h | 8 +- dom/base/nsFocusManager.cpp | 6 + dom/bindings/BindingUtils.h | 2 +- dom/bindings/Bindings.conf | 12 + .../BrowserElementChildPreload.js | 2 - dom/plugins/test/testplugin/nptest.cpp | 7 +- dom/webidl/ChromeUtils.webidl | 63 + dom/webidl/HeapSnapshot.webidl | 12 + dom/webidl/ScrollViewChangeEvent.webidl | 4 - dom/webidl/moz.build | 2 + gfx/layers/LayerScope.cpp | 216 +- gfx/layers/LayerScope.h | 13 +- gfx/layers/Layers.cpp | 19 + gfx/layers/apz/util/APZEventState.cpp | 4 +- gfx/layers/opengl/CompositorOGL.cpp | 11 +- gfx/layers/protobuf/LayerScopePacket.pb.cc | 2576 +++- gfx/layers/protobuf/LayerScopePacket.pb.h | 2137 ++- gfx/layers/protobuf/LayerScopePacket.proto | 23 + js/public/Debug.h | 15 +- js/public/HeapAPI.h | 16 +- js/public/TrackedOptimizationInfo.h | 1 + js/public/UbiNode.h | 113 +- js/public/UbiNodeTraverse.h | 4 +- js/public/Utility.h | 14 - js/src/asmjs/AsmJSLink.cpp | 3 + js/src/asmjs/AsmJSModule.cpp | 49 +- js/src/asmjs/AsmJSSignalHandlers.cpp | 2 +- js/src/builtin/TestingFunctions.cpp | 2 +- js/src/configure.in | 55 +- js/src/devtools/automation/variants/arm-sim | 2 +- .../devtools/automation/variants/arm-sim-osx | 2 +- js/src/devtools/rootAnalysis/annotations.js | 45 +- js/src/gc/Barrier.cpp | 6 + js/src/gc/Barrier.h | 17 +- js/src/gc/Heap.h | 5 +- js/src/gc/Marking.cpp | 20 +- js/src/gc/Nursery.cpp | 11 +- js/src/gc/StoreBuffer.cpp | 1 + js/src/gc/StoreBuffer.h | 11 +- .../irregexp/NativeRegExpMacroAssembler.cpp | 2 + .../baseline/classConstructor-AnyScripted.js | 30 + js/src/jit-test/tests/ion/bug1151323.js | 8 + js/src/jit/BaselineBailouts.cpp | 2 +- js/src/jit/BaselineCompiler.cpp | 20 +- js/src/jit/BaselineIC.cpp | 17 +- js/src/jit/BaselineIC.h | 4 +- js/src/jit/BaselineJIT.cpp | 9 + js/src/jit/CodeGenerator.cpp | 122 +- js/src/jit/CodeGenerator.h | 5 +- js/src/jit/CompileWrappers.cpp | 7 + js/src/jit/CompileWrappers.h | 1 + js/src/jit/ExecutableAllocator.cpp | 9 + js/src/jit/ExecutableAllocator.h | 38 +- js/src/jit/ExecutableAllocatorPosix.cpp | 37 +- js/src/jit/ExecutableAllocatorWin.cpp | 59 +- js/src/jit/Ion.cpp | 110 +- js/src/jit/IonBuilder.cpp | 358 +- js/src/jit/IonBuilder.h | 7 +- js/src/jit/IonCaches.cpp | 35 +- js/src/jit/IonCaches.h | 2 +- js/src/jit/IonCode.h | 6 +- js/src/jit/JitCommon.h | 6 +- js/src/jit/JitCompartment.h | 54 +- js/src/jit/LIR-Common.h | 10 - js/src/jit/LOpcodes.h | 1 - js/src/jit/Linker.h | 1 + js/src/jit/Lowering.cpp | 19 +- js/src/jit/Lowering.h | 1 - js/src/jit/MCallOptimize.cpp | 21 +- js/src/jit/MIR.cpp | 92 +- js/src/jit/MIR.h | 45 +- js/src/jit/MIRGenerator.h | 20 +- js/src/jit/MIRGraph.cpp | 2 +- js/src/jit/MOpcodes.h | 1 - js/src/jit/MacroAssembler.cpp | 125 +- js/src/jit/MacroAssembler.h | 20 +- js/src/jit/VMFunctions.cpp | 6 +- js/src/jit/arm/Architecture-arm.cpp | 14 +- js/src/jit/arm/Architecture-arm.h | 2 +- js/src/jit/arm/Assembler-arm.cpp | 273 +- js/src/jit/arm/Assembler-arm.h | 484 +- js/src/jit/arm/BaselineIC-arm.cpp | 10 +- js/src/jit/arm/CodeGenerator-arm.cpp | 60 +- js/src/jit/arm/MacroAssembler-arm.cpp | 531 +- js/src/jit/arm/MacroAssembler-arm.h | 211 +- js/src/jit/arm/MoveEmitter-arm.cpp | 82 +- js/src/jit/arm/MoveEmitter-arm.h | 6 +- js/src/jit/arm/Simulator-arm.cpp | 6 +- js/src/jit/arm/Simulator-arm.h | 4 +- js/src/jit/arm/Trampoline-arm.cpp | 8 +- js/src/jit/arm64/BaselineIC-arm64.cpp | 2 +- js/src/jit/arm64/MacroAssembler-arm64.cpp | 8 +- js/src/jit/arm64/MacroAssembler-arm64.h | 4 +- js/src/jit/arm64/vixl/Cpu-vixl.cpp | 6 +- js/src/jit/arm64/vixl/Debugger-vixl.cpp | 4 +- js/src/jit/arm64/vixl/MacroAssembler-vixl.cpp | 6 +- js/src/jit/arm64/vixl/MacroAssembler-vixl.h | 2 +- js/src/jit/arm64/vixl/Simulator-vixl.cpp | 4 +- js/src/jit/mips/Architecture-mips.cpp | 4 +- js/src/jit/mips/Assembler-mips.cpp | 43 - js/src/jit/mips/Assembler-mips.h | 10 +- js/src/jit/mips/MacroAssembler-mips.cpp | 9 +- js/src/jit/mips/MacroAssembler-mips.h | 4 - js/src/jit/mips/Simulator-mips.h | 4 +- js/src/jit/none/MacroAssembler-none.h | 14 +- js/src/jit/shared/Assembler-shared.h | 65 +- js/src/jit/x64/Assembler-x64.cpp | 3 +- js/src/jit/x64/Assembler-x64.h | 13 +- js/src/jit/x64/MacroAssembler-x64.h | 6 - .../jit/x86-shared/Assembler-x86-shared.cpp | 48 +- js/src/jit/x86-shared/Assembler-x86-shared.h | 8 +- .../jit/x86-shared/BaseAssembler-x86-shared.h | 6 +- .../x86-shared/MacroAssembler-x86-shared.h | 3 + js/src/jit/x86/Assembler-x86.h | 9 +- js/src/jit/x86/MacroAssembler-x86.h | 20 +- js/src/js.msg | 1 + .../testJitMoveEmitterCycles-mips.cpp | 2 +- .../jsapi-tests/testJitMoveEmitterCycles.cpp | 2 +- js/src/jscntxt.cpp | 2 +- js/src/jsfriendapi.cpp | 6 + js/src/jsfriendapi.h | 3 + js/src/jsobj.cpp | 16 + js/src/jsobj.h | 10 +- js/src/jsprf.cpp | 12 +- js/src/jspubtd.h | 4 +- js/src/jsweakmap.cpp | 2 +- js/src/jsweakmap.h | 31 +- js/src/moz.build | 32 +- js/src/shell/js.cpp | 22 +- .../ecma_6/Class/classConstructorNoCall.js | 28 + .../tests/ecma_6/Class/methodInstallation.js | 2 +- js/src/tests/lib/tests.py | 4 +- js/src/vm/Debugger-inl.h | 2 +- js/src/vm/Debugger.cpp | 25 +- js/src/vm/Debugger.h | 5 +- js/src/vm/DebuggerMemory.cpp | 11 +- js/src/vm/Interpreter.cpp | 9 +- js/src/vm/ObjectGroup.cpp | 16 +- js/src/vm/ObjectGroup.h | 9 +- js/src/vm/Runtime.cpp | 10 +- js/src/vm/Runtime.h | 26 +- js/src/vm/TypeInference.cpp | 121 +- js/src/vm/TypeInference.h | 5 + js/src/vm/UbiNode.cpp | 48 +- js/src/vm/UnboxedObject.cpp | 3 + js/src/vm/Xdr.h | 4 +- js/xpconnect/src/xpcpublic.h | 2 +- layout/base/AccessibleCaret.cpp | 269 + layout/base/AccessibleCaret.h | 209 + layout/base/AccessibleCaretEventHub.cpp | 814 + layout/base/AccessibleCaretEventHub.h | 227 + layout/base/AccessibleCaretLogger.cpp | 27 + layout/base/AccessibleCaretLogger.h | 40 + layout/base/AccessibleCaretManager.cpp | 873 ++ layout/base/AccessibleCaretManager.h | 174 + layout/base/SelectionCarets.cpp | 35 +- layout/base/SelectionCarets.h | 7 +- .../doc/AccessibleCaretEventHubStates.dot | 37 + .../doc/AccessibleCaretEventHubStates.png | Bin 0 -> 92942 bytes .../gtest/TestAccessibleCaretEventHub.cpp | 761 + layout/base/gtest/moz.build | 24 + layout/base/moz.build | 7 + layout/base/nsIPresShell.h | 6 + layout/base/nsLayoutUtils.cpp | 22 +- layout/base/nsLayoutUtils.h | 7 + layout/base/nsPresShell.cpp | 59 +- layout/base/nsPresShell.h | 6 + layout/base/tests/marionette/manifest.ini | 2 +- .../tests/marionette/test_selectioncarets.py | 155 +- .../tests/marionette/test_selectioncarets2.py | 253 + .../test_selectioncarets_multiplerange.py | 8 +- .../base/tests/marionette/test_touchcaret.py | 157 +- layout/generic/Selection.h | 1 + layout/generic/nsSelection.cpp | 43 + layout/style/ua.css | 94 + modules/libpref/init/all.js | 7 + .../tests/unit/test_accessibility.py | 2 +- .../tests/unit/test_anonymous_content.py | 2 +- .../marionette/tests/unit/test_appcache.py | 2 +- .../tests/unit/test_capabilities.py | 4 +- .../marionette/tests/unit/test_clearing.py | 2 +- .../marionette/tests/unit/test_click.py | 2 +- .../tests/unit/test_click_chrome.py | 2 +- .../tests/unit/test_click_scrolling.py | 2 +- .../marionette/tests/unit/test_cookies.py | 2 +- .../marionette/tests/unit/test_data_driven.py | 12 +- .../tests/unit/test_date_time_value.py | 2 +- .../tests/unit/test_elementState.py | 2 +- .../tests/unit/test_elementState_chrome.py | 2 +- .../tests/unit/test_element_touch.py | 2 +- .../marionette/tests/unit/test_elementsize.py | 2 +- .../marionette/tests/unit/test_emulator.py | 5 +- .../marionette/tests/unit/test_errors.py | 2 +- .../tests/unit/test_execute_async_script.py | 3 +- .../tests/unit/test_execute_isolate.py | 5 +- .../tests/unit/test_execute_script.py | 4 +- .../marionette/tests/unit/test_expected.py | 2 +- .../tests/unit/test_expectedfail.py | 2 +- .../marionette/tests/unit/test_findelement.py | 2 +- .../tests/unit/test_findelement_chrome.py | 2 +- .../marionette/tests/unit/test_gesture.py | 4 +- .../tests/unit/test_getactiveframe_oop.py | 2 +- .../marionette/tests/unit/test_getattr.py | 2 +- .../tests/unit/test_getattr_chrome.py | 2 +- .../tests/unit/test_implicit_waits.py | 2 +- .../tests/unit/test_import_script.py | 2 +- .../unit/test_import_script_reuse_window.py | 2 +- .../marionette/tests/unit/test_key_actions.py | 6 +- .../client/marionette/tests/unit/test_log.py | 4 +- .../marionette/tests/unit/test_marionette.py | 2 +- .../tests/unit/test_modal_dialogs.py | 2 +- .../tests/unit/test_multi_finger.py | 4 +- .../marionette/tests/unit/test_navigation.py | 6 +- .../marionette/tests/unit/test_pagesource.py | 2 +- .../marionette/tests/unit/test_position.py | 2 +- .../tests/unit/test_profile_management.py | 2 +- .../tests/unit/test_rendered_element.py | 2 +- .../marionette/tests/unit/test_report.py | 3 +- .../marionette/tests/unit/test_run_js_test.py | 3 +- .../tests/unit/test_screen_orientation.py | 2 +- .../marionette/tests/unit/test_screenshot.py | 2 +- .../marionette/tests/unit/test_selected.py | 2 +- .../tests/unit/test_selected_chrome.py | 2 +- .../marionette/tests/unit/test_session.py | 6 +- .../tests/unit/test_set_window_size.py | 2 +- .../tests/unit/test_simpletest_sanity.py | 5 +- .../tests/unit/test_single_finger.py | 2 +- .../tests/unit/test_single_finger_desktop.py | 3 +- .../marionette/tests/unit/test_skip_setup.py | 2 +- .../tests/unit/test_specialpowers.py | 4 +- .../marionette/tests/unit/test_submit.py | 2 +- .../tests/unit/test_switch_frame.py | 2 +- .../tests/unit/test_switch_frame_chrome.py | 4 +- .../tests/unit/test_switch_remote_frame.py | 2 +- .../client/marionette/tests/unit/test_text.py | 2 +- .../marionette/tests/unit/test_text_chrome.py | 2 +- .../marionette/tests/unit/test_timeouts.py | 4 +- .../marionette/tests/unit/test_typing.py | 2 +- .../marionette/tests/unit/test_visibility.py | 2 +- .../client/marionette/tests/unit/test_wait.py | 2 +- .../tests/unit/test_window_handles.py | 2 +- .../tests/unit/test_window_management.py | 2 +- .../tests/unit/test_window_position.py | 2 +- .../tests/unit/test_window_switching.py | 2 +- .../tests/unit/test_window_title.py | 2 +- .../marionette/tests/unit/test_window_type.py | 2 +- .../tests/unit/test_with_using_context.py | 2 +- testing/marionette/mach_commands.py | 15 +- .../downloads/ApplicationReputation.cpp | 1160 ++ toolkit/components/downloads/csd.pb.cc | 12069 +++++++++++++++ toolkit/components/downloads/csd.pb.h | 12606 ++++++++++++++++ toolkit/components/downloads/csd.proto | 487 + toolkit/components/downloads/generate_csd.sh | 34 + toolkit/components/downloads/moz.build | 1 + .../test/unit/test_app_rep_maclinux.js | 303 + .../test/unit/test_app_rep_windows.js | 11 +- toolkit/components/protobuf/README.txt | 30 +- .../protobuf/google/protobuf/stubs/map-util.h | 119 - toolkit/components/protobuf/m-c-changes.patch | 365 + toolkit/components/protobuf/moz.build | 131 +- toolkit/components/protobuf/r512.patch | 13 - .../src/google/protobuf/descriptor.cc | 5420 +++++++ .../protobuf/src/google/protobuf/descriptor.h | 1691 +++ .../src/google/protobuf/descriptor.pb.cc | 9135 +++++++++++ .../src/google/protobuf/descriptor.pb.h | 6761 +++++++++ .../src/google/protobuf/descriptor.proto | 687 + .../google/protobuf/descriptor_database.cc | 543 + .../src/google/protobuf/descriptor_database.h | 369 + .../src/google/protobuf/dynamic_message.cc | 764 + .../src/google/protobuf/dynamic_message.h | 148 + .../google/protobuf/extension_set.cc | 637 +- .../{ => src}/google/protobuf/extension_set.h | 484 +- .../google/protobuf/extension_set_heavy.cc | 734 + .../protobuf/generated_enum_reflection.h | 91 + .../protobuf/generated_message_reflection.cc | 1683 +++ .../protobuf/generated_message_reflection.h | 504 + .../google/protobuf/generated_message_util.cc | 14 +- .../google/protobuf/generated_message_util.h | 65 +- .../google/protobuf/io/coded_stream.cc | 153 +- .../google/protobuf/io/coded_stream.h | 156 +- .../google/protobuf/io/coded_stream_inl.h | 13 +- .../src/google/protobuf/io/gzip_stream.cc | 325 + .../src/google/protobuf/io/gzip_stream.h | 209 + .../google/protobuf/io/package_info.h | 2 +- .../src/google/protobuf/io/printer.cc | 198 + .../protobuf/src/google/protobuf/io/printer.h | 136 + .../protobuf/src/google/protobuf/io/strtod.cc | 113 + .../protobuf/src/google/protobuf/io/strtod.h | 50 + .../src/google/protobuf/io/tokenizer.cc | 1127 ++ .../src/google/protobuf/io/tokenizer.h | 402 + .../google/protobuf/io/zero_copy_stream.cc | 57 + .../google/protobuf/io/zero_copy_stream.h | 12 +- .../protobuf/io/zero_copy_stream_impl.cc | 473 + .../protobuf/io/zero_copy_stream_impl.h | 3 +- .../protobuf/io/zero_copy_stream_impl_lite.cc | 24 +- .../protobuf/io/zero_copy_stream_impl_lite.h | 16 +- .../protobuf/src/google/protobuf/message.cc | 358 + .../protobuf/src/google/protobuf/message.h | 866 ++ .../{ => src}/google/protobuf/message_lite.cc | 7 +- .../{ => src}/google/protobuf/message_lite.h | 14 +- .../{ => src}/google/protobuf/package_info.h | 2 +- .../src/google/protobuf/reflection_ops.cc | 269 + .../src/google/protobuf/reflection_ops.h | 81 + .../google/protobuf/repeated_field.cc | 23 +- .../google/protobuf/repeated_field.h | 474 +- .../google/protobuf/service.cc} | 14 +- .../protobuf/src/google/protobuf/service.h | 291 + .../src/google/protobuf/stubs/atomicops.h | 227 + .../stubs/atomicops_internals_arm64_gcc.h | 325 + .../stubs/atomicops_internals_arm_gcc.h | 151 + .../stubs/atomicops_internals_arm_qnx.h | 146 + .../atomicops_internals_atomicword_compat.h | 122 + .../stubs/atomicops_internals_generic_gcc.h | 137 + .../stubs/atomicops_internals_macosx.h | 225 + .../stubs/atomicops_internals_mips_gcc.h | 313 + .../stubs/atomicops_internals_pnacl.h | 73 + .../stubs/atomicops_internals_solaris.h | 188 + .../protobuf/stubs/atomicops_internals_tsan.h | 219 + .../stubs/atomicops_internals_x86_gcc.cc | 137 + .../stubs/atomicops_internals_x86_gcc.h | 293 + .../stubs/atomicops_internals_x86_msvc.cc | 112 + .../stubs/atomicops_internals_x86_msvc.h | 150 + .../{ => src}/google/protobuf/stubs/common.cc | 47 +- .../{ => src}/google/protobuf/stubs/common.h | 121 +- .../{ => src}/google/protobuf/stubs/hash.h | 14 +- .../src/google/protobuf/stubs/map_util.h | 771 + .../{ => src}/google/protobuf/stubs/once.cc | 89 +- .../{ => src}/google/protobuf/stubs/once.h | 103 +- .../google/protobuf/stubs/platform_macros.h | 103 + .../src/google/protobuf/stubs/shared_ptr.h | 470 + .../google/protobuf/stubs/stl_util.h} | 10 +- .../src/google/protobuf/stubs/stringprintf.cc | 174 + .../src/google/protobuf/stubs/stringprintf.h | 76 + .../protobuf/stubs/structurally_valid.cc | 536 + .../src/google/protobuf/stubs/strutil.cc | 1280 ++ .../src/google/protobuf/stubs/strutil.h | 563 + .../src/google/protobuf/stubs/substitute.cc | 134 + .../src/google/protobuf/stubs/substitute.h | 170 + .../src/google/protobuf/stubs/template_util.h | 138 + .../src/google/protobuf/stubs/type_traits.h | 334 + .../src/google/protobuf/text_format.cc | 1746 +++ .../src/google/protobuf/text_format.h | 473 + .../src/google/protobuf/unknown_field_set.cc | 265 + .../src/google/protobuf/unknown_field_set.h | 318 + .../src/google/protobuf/wire_format.cc | 1106 ++ .../src/google/protobuf/wire_format.h | 336 + .../google/protobuf/wire_format_lite.cc | 126 +- .../google/protobuf/wire_format_lite.h | 58 +- .../google/protobuf/wire_format_lite_inl.h | 131 +- toolkit/components/protobuf/update.sh | 2 - .../components/protobuf/upgrade_protobuf.sh | 71 + toolkit/components/protobuf/vs2013.patch | 21 - toolkit/devtools/inspector/inspector-panel.js | 6 +- toolkit/devtools/markupview/markup-view.js | 7 +- toolkit/devtools/server/ChromeUtils.cpp | 432 + toolkit/devtools/server/ChromeUtils.h | 81 + toolkit/devtools/server/CoreDump.pb.cc | 1005 ++ toolkit/devtools/server/CoreDump.pb.h | 643 + toolkit/devtools/server/CoreDump.proto | 69 + toolkit/devtools/server/DeserializedNode.cpp | 202 + toolkit/devtools/server/DeserializedNode.h | 131 + toolkit/devtools/server/HeapSnapshot.cpp | 194 + toolkit/devtools/server/HeapSnapshot.h | 133 + .../server/ZeroCopyNSIOutputStream.cpp | 99 + .../devtools/server/ZeroCopyNSIOutputStream.h | 70 + toolkit/devtools/server/actors/highlighter.js | 11 +- toolkit/devtools/server/actors/inspector.js | 121 +- toolkit/devtools/server/actors/memory.js | 23 + toolkit/devtools/server/actors/styles.js | 4 + toolkit/devtools/server/actors/webbrowser.js | 15 +- .../server/generate-core-dump-sources.sh | 26 + toolkit/devtools/server/moz.build | 23 +- .../tests/gtest/DeserializedNodeUbiNodes.cpp | 95 + .../devtools/server/tests/gtest/DevTools.h | 288 + .../tests/gtest/DoesCrossZoneBoundaries.cpp | 70 + .../tests/gtest/DoesntCrossZoneBoundaries.cpp | 62 + .../tests/gtest/SerializesEdgeNames.cpp | 53 + .../SerializesEverythingInHeapGraphOnce.cpp | 37 + .../tests/gtest/SerializesTypeNames.cpp | 30 + toolkit/devtools/server/tests/gtest/moz.build | 22 + .../server/tests/mochitest/chrome.ini | 55 +- .../server/tests/mochitest/hello-actor.js | 20 + .../mochitest/test_SaveHeapSnapshot.html | 31 + .../mochitest/test_inspector-dead-nodes.html | 367 + .../mochitest/test_memory_gc_events.html | 42 + .../tests/mochitest/test_registerActor.html | 102 + .../devtools/server/tests/unit/head_dbg.js | 12 +- .../tests/unit/test_ReadHeapSnapshot.js | 23 + .../tests/unit/test_SaveHeapSnapshot.js | 99 + .../devtools/server/tests/unit/xpcshell.ini | 2 + toolkit/devtools/styleinspector/rule-view.js | 2 +- xpcom/base/nsCycleCollector.cpp | 12 +- xpcom/glue/nsCRTGlue.cpp | 18 + xpcom/glue/nsCRTGlue.h | 5 + .../glue/nsCycleCollectionNoteRootCallback.h | 2 +- xpcom/glue/nsDebug.h | 7 - 400 files changed, 89958 insertions(+), 4168 deletions(-) create mode 100644 dom/webidl/ChromeUtils.webidl create mode 100644 dom/webidl/HeapSnapshot.webidl create mode 100644 js/src/jit-test/tests/baseline/classConstructor-AnyScripted.js create mode 100644 js/src/jit-test/tests/ion/bug1151323.js create mode 100644 js/src/tests/ecma_6/Class/classConstructorNoCall.js create mode 100644 layout/base/AccessibleCaret.cpp create mode 100644 layout/base/AccessibleCaret.h create mode 100644 layout/base/AccessibleCaretEventHub.cpp create mode 100644 layout/base/AccessibleCaretEventHub.h create mode 100644 layout/base/AccessibleCaretLogger.cpp create mode 100644 layout/base/AccessibleCaretLogger.h create mode 100644 layout/base/AccessibleCaretManager.cpp create mode 100644 layout/base/AccessibleCaretManager.h create mode 100644 layout/base/doc/AccessibleCaretEventHubStates.dot create mode 100644 layout/base/doc/AccessibleCaretEventHubStates.png create mode 100644 layout/base/gtest/TestAccessibleCaretEventHub.cpp create mode 100644 layout/base/gtest/moz.build create mode 100644 layout/base/tests/marionette/test_selectioncarets2.py create mode 100644 toolkit/components/downloads/ApplicationReputation.cpp create mode 100644 toolkit/components/downloads/csd.pb.cc create mode 100644 toolkit/components/downloads/csd.pb.h create mode 100644 toolkit/components/downloads/csd.proto create mode 100644 toolkit/components/downloads/generate_csd.sh create mode 100644 toolkit/components/downloads/test/unit/test_app_rep_maclinux.js delete mode 100644 toolkit/components/protobuf/google/protobuf/stubs/map-util.h create mode 100644 toolkit/components/protobuf/m-c-changes.patch delete mode 100644 toolkit/components/protobuf/r512.patch create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.pb.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.pb.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor.proto create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor_database.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/descriptor_database.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/dynamic_message.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/dynamic_message.h rename toolkit/components/protobuf/{ => src}/google/protobuf/extension_set.cc (76%) rename toolkit/components/protobuf/{ => src}/google/protobuf/extension_set.h (63%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/extension_set_heavy.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/generated_enum_reflection.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/generated_message_reflection.h rename toolkit/components/protobuf/{ => src}/google/protobuf/generated_message_util.cc (87%) rename toolkit/components/protobuf/{ => src}/google/protobuf/generated_message_util.h (57%) rename toolkit/components/protobuf/{ => src}/google/protobuf/io/coded_stream.cc (85%) rename toolkit/components/protobuf/{ => src}/google/protobuf/io/coded_stream.h (87%) rename toolkit/components/protobuf/{ => src}/google/protobuf/io/coded_stream_inl.h (85%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/gzip_stream.h rename toolkit/components/protobuf/{ => src}/google/protobuf/io/package_info.h (97%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/printer.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/printer.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/strtod.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/strtod.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/tokenizer.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/tokenizer.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream.cc rename toolkit/components/protobuf/{ => src}/google/protobuf/io/zero_copy_stream.h (93%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/io/zero_copy_stream_impl.cc rename toolkit/components/protobuf/{ => src}/google/protobuf/io/zero_copy_stream_impl.h (99%) rename toolkit/components/protobuf/{ => src}/google/protobuf/io/zero_copy_stream_impl_lite.cc (93%) rename toolkit/components/protobuf/{ => src}/google/protobuf/io/zero_copy_stream_impl_lite.h (95%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/message.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/message.h rename toolkit/components/protobuf/{ => src}/google/protobuf/message_lite.cc (98%) rename toolkit/components/protobuf/{ => src}/google/protobuf/message_lite.h (97%) rename toolkit/components/protobuf/{ => src}/google/protobuf/package_info.h (98%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/reflection_ops.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/reflection_ops.h rename toolkit/components/protobuf/{ => src}/google/protobuf/repeated_field.cc (79%) rename toolkit/components/protobuf/{ => src}/google/protobuf/repeated_field.h (74%) rename toolkit/components/protobuf/{google/protobuf/io/zero_copy_stream.cc => src/google/protobuf/service.cc} (89%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/service.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm64_gcc.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_gcc.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_arm_qnx.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_atomicword_compat.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_macosx.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_mips_gcc.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_pnacl.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_solaris.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_tsan.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_gcc.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/atomicops_internals_x86_msvc.h rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/common.cc (90%) rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/common.h (93%) rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/hash.h (96%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/map_util.h rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/once.cc (56%) rename toolkit/components/protobuf/{ => src}/google/protobuf/stubs/once.h (61%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/platform_macros.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/shared_ptr.h rename toolkit/components/protobuf/{google/protobuf/stubs/stl_util-inl.h => src/google/protobuf/stubs/stl_util.h} (95%) create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/stringprintf.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/structurally_valid.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/strutil.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/strutil.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/substitute.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/substitute.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/template_util.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/stubs/type_traits.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/text_format.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/text_format.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/unknown_field_set.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/unknown_field_set.h create mode 100644 toolkit/components/protobuf/src/google/protobuf/wire_format.cc create mode 100644 toolkit/components/protobuf/src/google/protobuf/wire_format.h rename toolkit/components/protobuf/{ => src}/google/protobuf/wire_format_lite.cc (76%) rename toolkit/components/protobuf/{ => src}/google/protobuf/wire_format_lite.h (92%) rename toolkit/components/protobuf/{ => src}/google/protobuf/wire_format_lite_inl.h (86%) delete mode 100755 toolkit/components/protobuf/update.sh create mode 100644 toolkit/components/protobuf/upgrade_protobuf.sh delete mode 100644 toolkit/components/protobuf/vs2013.patch create mode 100644 toolkit/devtools/server/ChromeUtils.cpp create mode 100644 toolkit/devtools/server/ChromeUtils.h create mode 100644 toolkit/devtools/server/CoreDump.pb.cc create mode 100644 toolkit/devtools/server/CoreDump.pb.h create mode 100644 toolkit/devtools/server/CoreDump.proto create mode 100644 toolkit/devtools/server/DeserializedNode.cpp create mode 100644 toolkit/devtools/server/DeserializedNode.h create mode 100644 toolkit/devtools/server/HeapSnapshot.cpp create mode 100644 toolkit/devtools/server/HeapSnapshot.h create mode 100644 toolkit/devtools/server/ZeroCopyNSIOutputStream.cpp create mode 100644 toolkit/devtools/server/ZeroCopyNSIOutputStream.h create mode 100644 toolkit/devtools/server/generate-core-dump-sources.sh create mode 100644 toolkit/devtools/server/tests/gtest/DeserializedNodeUbiNodes.cpp create mode 100644 toolkit/devtools/server/tests/gtest/DevTools.h create mode 100644 toolkit/devtools/server/tests/gtest/DoesCrossZoneBoundaries.cpp create mode 100644 toolkit/devtools/server/tests/gtest/DoesntCrossZoneBoundaries.cpp create mode 100644 toolkit/devtools/server/tests/gtest/SerializesEdgeNames.cpp create mode 100644 toolkit/devtools/server/tests/gtest/SerializesEverythingInHeapGraphOnce.cpp create mode 100644 toolkit/devtools/server/tests/gtest/SerializesTypeNames.cpp create mode 100644 toolkit/devtools/server/tests/gtest/moz.build create mode 100644 toolkit/devtools/server/tests/mochitest/hello-actor.js create mode 100644 toolkit/devtools/server/tests/mochitest/test_SaveHeapSnapshot.html create mode 100644 toolkit/devtools/server/tests/mochitest/test_inspector-dead-nodes.html create mode 100644 toolkit/devtools/server/tests/mochitest/test_memory_gc_events.html create mode 100644 toolkit/devtools/server/tests/mochitest/test_registerActor.html create mode 100644 toolkit/devtools/server/tests/unit/test_ReadHeapSnapshot.js create mode 100644 toolkit/devtools/server/tests/unit/test_SaveHeapSnapshot.js diff --git a/build/mach_bootstrap.py b/build/mach_bootstrap.py index 6873290565..741582db48 100644 --- a/build/mach_bootstrap.py +++ b/build/mach_bootstrap.py @@ -50,7 +50,6 @@ SEARCH_PATHS = [ 'testing/web-platform', 'testing/web-platform/harness', 'testing/marionette/client', - 'testing/marionette/client/marionette', 'testing/marionette/transport', 'testing/marionette/driver', 'testing/mozbase/mozcrash', diff --git a/configure.in b/configure.in index b8222e79b3..8a75110de9 100644 --- a/configure.in +++ b/configure.in @@ -2977,6 +2977,7 @@ then esac LDFLAGS="${_PTHREAD_LDFLAGS} ${LDFLAGS}" AC_SUBST(MOZ_USE_PTHREADS) + MOZ_CHECK_HEADERS(pthread.h) fi diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index a5e6fda3d8..03a73e2046 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -3269,14 +3269,14 @@ nsDocShell::RemoveWeakScrollObserver(nsIScrollObserver* aObserver) } void -nsDocShell::NotifyAsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos) +nsDocShell::NotifyAsyncPanZoomStarted() { nsTObserverArray::ForwardIterator iter(mScrollObservers); while (iter.HasMore()) { nsWeakPtr ref = iter.GetNext(); nsCOMPtr obs = do_QueryReferent(ref); if (obs) { - obs->AsyncPanZoomStarted(aScrollPos); + obs->AsyncPanZoomStarted(); } else { mScrollObservers.RemoveElement(ref); } @@ -3287,20 +3287,20 @@ nsDocShell::NotifyAsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos) nsCOMPtr kid = do_QueryInterface(ChildAt(i)); if (kid) { nsDocShell* docShell = static_cast(kid.get()); - docShell->NotifyAsyncPanZoomStarted(aScrollPos); + docShell->NotifyAsyncPanZoomStarted(); } } } void -nsDocShell::NotifyAsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos) +nsDocShell::NotifyAsyncPanZoomStopped() { nsTObserverArray::ForwardIterator iter(mScrollObservers); while (iter.HasMore()) { nsWeakPtr ref = iter.GetNext(); nsCOMPtr obs = do_QueryReferent(ref); if (obs) { - obs->AsyncPanZoomStopped(aScrollPos); + obs->AsyncPanZoomStopped(); } else { mScrollObservers.RemoveElement(ref); } @@ -3311,7 +3311,7 @@ nsDocShell::NotifyAsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos) nsCOMPtr kid = do_QueryInterface(ChildAt(i)); if (kid) { nsDocShell* docShell = static_cast(kid.get()); - docShell->NotifyAsyncPanZoomStopped(aScrollPos); + docShell->NotifyAsyncPanZoomStopped(); } } } diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index 935f61d86a..ef79677cfd 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -255,10 +255,10 @@ public: // Notify Scroll observers when an async panning/zooming transform // has started being applied - void NotifyAsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos); + void NotifyAsyncPanZoomStarted(); // Notify Scroll observers when an async panning/zooming transform // is no longer applied - void NotifyAsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos); + void NotifyAsyncPanZoomStopped(); // Add new profile timeline markers to this docShell. This will only add // markers if the docShell is currently recording profile timeline markers. diff --git a/docshell/base/nsIScrollObserver.h b/docshell/base/nsIScrollObserver.h index cbf21405f6..82c7cabe91 100644 --- a/docshell/base/nsIScrollObserver.h +++ b/docshell/base/nsIScrollObserver.h @@ -11,8 +11,8 @@ #include "Units.h" #define NS_ISCROLLOBSERVER_IID \ - { 0x00bc10e3, 0xaa59, 0x4aa3, \ - { 0x88, 0xe9, 0x43, 0x0a, 0x01, 0xa3, 0x88, 0x04 } } + { 0xaa5026eb, 0x2f88, 0x4026, \ + { 0xa4, 0x6b, 0xf4, 0x59, 0x6b, 0x4e, 0xdf, 0x00 } } class nsIScrollObserver : public nsISupports { @@ -28,13 +28,13 @@ public: * Called when an async panning/zooming transform has started being applied * and passed the scroll offset */ - virtual void AsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos) {}; + virtual void AsyncPanZoomStarted() {}; /** * Called when an async panning/zooming transform is no longer applied * and passed the scroll offset */ - virtual void AsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos) {}; + virtual void AsyncPanZoomStopped() {}; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIScrollObserver, NS_ISCROLLOBSERVER_IID) diff --git a/dom/base/nsFocusManager.cpp b/dom/base/nsFocusManager.cpp index 78a420712c..40310892ef 100644 --- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -8,6 +8,7 @@ #include "nsFocusManager.h" +#include "AccessibleCaretEventHub.h" #include "nsIInterfaceRequestorUtils.h" #include "nsGkAtoms.h" #include "nsContentUtils.h" @@ -1671,6 +1672,11 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear, selectionCarets->NotifyBlur(aIsLeavingDocument || !mActiveWindow); } + nsRefPtr eventHub = presShell->GetAccessibleCaretEventHub(); + if (eventHub) { + eventHub->NotifyBlur(aIsLeavingDocument || !mActiveWindow); + } + // at this point, it is expected that this window will be still be // focused, but the focused content will be null, as it was cleared before // the event. If this isn't the case, then something else was focused during diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 4ddcc6439a..66f99961ac 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -806,7 +806,7 @@ MaybeWrapStringValue(JSContext* cx, JS::MutableHandle rval) { MOZ_ASSERT(rval.isString()); JSString* str = rval.toString(); - if (JS::GetTenuredGCThingZone(str) != js::GetContextZone(cx)) { + if (JS::GetStringZone(str) != js::GetContextZone(cx)) { return JS_WrapValue(cx, rval); } return true; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 346fb72f29..273be83ced 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -261,6 +261,14 @@ DOMInterfaces = { 'concrete': False }, +'ChromeUtils': { + # The codegen is dumb, and doesn't understand that this interface is only a + # collection of static methods, so we have this `concrete: False` hack. + 'concrete': False, + 'nativeType': 'mozilla::devtools::ChromeUtils', + 'implicitJSContext': ['readHeapSnapshot', 'saveHeapSnapshot'] +}, + 'ChromeWindow': { 'concrete': False, }, @@ -488,6 +496,10 @@ DOMInterfaces = { 'headerFile': 'nsGeolocation.h' }, +'HeapSnapshot': { + 'nativeType': 'mozilla::devtools::HeapSnapshot' +}, + 'History': { 'headerFile': 'nsHistory.h', 'nativeType': 'nsHistory' diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index c377fe9bbe..9b3084138e 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -576,8 +576,6 @@ BrowserElementChild.prototype = { e.stopPropagation(); let detail = { state: e.state, - scrollX: e.scrollX, - scrollY: e.scrollY, }; sendAsyncMsg('scrollviewchange', detail); }, diff --git a/dom/plugins/test/testplugin/nptest.cpp b/dom/plugins/test/testplugin/nptest.cpp index 6271f33ba9..9378b6f946 100644 --- a/dom/plugins/test/testplugin/nptest.cpp +++ b/dom/plugins/test/testplugin/nptest.cpp @@ -62,8 +62,6 @@ using namespace std; #define PLUGIN_VERSION "1.0.0.0" #define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0])) -#define STATIC_ASSERT(condition) \ - extern void np_static_assert(int arg[(condition) ? 1 : -1]) extern const char *sPluginName; extern const char *sPluginDescription; @@ -305,8 +303,9 @@ static const ScriptableFunction sPluginMethodFunctions[] = { echoString, }; -STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) == - ARRAY_LENGTH(sPluginMethodFunctions)); +static_assert(ARRAY_LENGTH(sPluginMethodIdentifierNames) == + ARRAY_LENGTH(sPluginMethodFunctions), + "Arrays should have the same size"); static const NPUTF8* sPluginPropertyIdentifierNames[] = { "propertyAndMethod" diff --git a/dom/webidl/ChromeUtils.webidl b/dom/webidl/ChromeUtils.webidl new file mode 100644 index 0000000000..db373fea98 --- /dev/null +++ b/dom/webidl/ChromeUtils.webidl @@ -0,0 +1,63 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. + */ + +/** + * A collection of static utility methods that are only exposed to Chrome. + */ +[ChromeOnly, Exposed=(Window,System)] +interface ChromeUtils { + /** + * Serialize a snapshot of the heap graph, as seen by |JS::ubi::Node| and + * restricted by |boundaries|, and write it to the provided file path. + * + * @param filePath The file path to write the heap snapshot to. + * + * @param boundaries The portion of the heap graph to write. + */ + [Throws] + static void saveHeapSnapshot(DOMString filePath, + optional HeapSnapshotBoundaries boundaries); + + /** + * Deserialize a core dump into a HeapSnapshot. + * + * @param filePath The file path to read the core dump from. + */ + [Throws, NewObject] + static HeapSnapshot readHeapSnapshot(DOMString filePath); +}; + +/** + * A JS object whose properties specify what portion of the heap graph to + * write. The recognized properties are: + * + * * globals: [ global, ... ] + * Dump only nodes that either: + * - belong in the compartment of one of the given globals; + * - belong to no compartment, but do belong to a Zone that contains one of + * the given globals; + * - are referred to directly by one of the last two kinds of nodes; or + * - is the fictional root node, described below. + * + * * debugger: Debugger object + * Like "globals", but use the Debugger's debuggees as the globals. + * + * * runtime: true + * Dump the entire heap graph, starting with the JSRuntime's roots. + * + * One, and only one, of these properties must exist on the boundaries object. + * + * The root of the dumped graph is a fictional node whose ubi::Node type name is + * "CoreDumpRoot". If we are dumping the entire ubi::Node graph, this root node + * has an edge for each of the JSRuntime's roots. If we are dumping a selected + * set of globals, the root has an edge to each global, and an edge for each + * incoming JS reference to the selected Zones. + */ +dictionary HeapSnapshotBoundaries { + sequence globals; + object debugger; + boolean runtime; +}; diff --git a/dom/webidl/HeapSnapshot.webidl b/dom/webidl/HeapSnapshot.webidl new file mode 100644 index 0000000000..4b4068318c --- /dev/null +++ b/dom/webidl/HeapSnapshot.webidl @@ -0,0 +1,12 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. + */ + +/** + * A HeapSnapshot represents a snapshot of the heap graph + */ +[ChromeOnly, Exposed=(Window,System)] +interface HeapSnapshot { +}; diff --git a/dom/webidl/ScrollViewChangeEvent.webidl b/dom/webidl/ScrollViewChangeEvent.webidl index e94e9b5d33..a3e92139a2 100644 --- a/dom/webidl/ScrollViewChangeEvent.webidl +++ b/dom/webidl/ScrollViewChangeEvent.webidl @@ -8,14 +8,10 @@ enum ScrollState {"started", "stopped"}; dictionary ScrollViewChangeEventInit : EventInit { ScrollState state = "started"; - float scrollX = 0; - float scrollY = 0; }; [Constructor(DOMString type, optional ScrollViewChangeEventInit eventInit), ChromeOnly] interface ScrollViewChangeEvent : Event { readonly attribute ScrollState state; - readonly attribute float scrollX; - readonly attribute float scrollY; }; diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index 12d80319eb..c69f611625 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -73,6 +73,7 @@ WEBIDL_FILES = [ 'CharacterData.webidl', 'ChildNode.webidl', 'ChromeNotifications.webidl', + 'ChromeUtils.webidl', 'Client.webidl', 'Clients.webidl', 'ClipboardEvent.webidl', @@ -158,6 +159,7 @@ WEBIDL_FILES = [ 'GetUserMediaRequest.webidl', 'HDMIInputPort.webidl', 'Headers.webidl', + 'HeapSnapshot.webidl', 'History.webidl', 'HTMLAllCollection.webidl', 'HTMLAnchorElement.webidl', diff --git a/gfx/layers/LayerScope.cpp b/gfx/layers/LayerScope.cpp index f3a794cada..6d2f2fb963 100644 --- a/gfx/layers/LayerScope.cpp +++ b/gfx/layers/LayerScope.cpp @@ -225,10 +225,9 @@ public: virtual ~DebugGLData() { } - Packet::DataType GetDataType() const { return mDataType; } - virtual bool Write() = 0; +protected: static bool WriteToStream(Packet& aPacket) { if (!WebSocketHelper::GetSocketManager()) return true; @@ -239,11 +238,10 @@ public: return WebSocketHelper::GetSocketManager()->WriteAll(data.get(), size); } -protected: Packet::DataType mDataType; }; -class DebugGLFrameStatusData : public DebugGLData +class DebugGLFrameStatusData final: public DebugGLData { public: DebugGLFrameStatusData(Packet::DataType aDataType, @@ -257,8 +255,6 @@ public: mFrameStamp(0) { } - int64_t GetFrameStamp() const { return mFrameStamp; } - virtual bool Write() override { Packet packet; packet.set_type(mDataType); @@ -266,16 +262,14 @@ public: FramePacket* fp = packet.mutable_frame(); fp->set_value(static_cast(mFrameStamp)); - if (!WriteToStream(packet)) - return false; - return true; + return WriteToStream(packet); } protected: int64_t mFrameStamp; }; -class DebugGLTextureData : public DebugGLData { +class DebugGLTextureData final: public DebugGLData { public: DebugGLTextureData(GLContext* cx, void* layerRef, @@ -283,7 +277,7 @@ public: GLuint name, DataSourceSurface* img) : DebugGLData(Packet::TEXTURE), - mLayerRef(layerRef), + mLayerRef(reinterpret_cast(layerRef)), mTarget(target), mName(name), mContextAddress(reinterpret_cast(cx)), @@ -296,16 +290,8 @@ public: pack(img); } - const void* GetLayerRef() const { return mLayerRef; } - GLuint GetName() const { return mName; } - GLenum GetTextureTarget() const { return mTarget; } - intptr_t GetContextAddress() const { return mContextAddress; } - uint32_t GetDataSize() const { return mDatasize; } - virtual bool Write() override { - if (!WriteToStream(mPacket)) - return false; - return true; + return WriteToStream(mPacket); } private: @@ -313,7 +299,7 @@ private: mPacket.set_type(mDataType); TexturePacket* tp = mPacket.mutable_texture(); - tp->set_layerref(reinterpret_cast(mLayerRef)); + tp->set_layerref(mLayerRef); tp->set_name(mName); tp->set_target(mTarget); tp->set_dataformat(LOCAL_GL_RGBA); @@ -351,7 +337,7 @@ private: } protected: - void* mLayerRef; + uint64_t mLayerRef; GLenum mTarget; GLuint mName; intptr_t mContextAddress; @@ -361,44 +347,38 @@ protected: Packet mPacket; }; -class DebugGLColorData : public DebugGLData { +class DebugGLColorData final: public DebugGLData { public: DebugGLColorData(void* layerRef, const gfxRGBA& color, int width, int height) : DebugGLData(Packet::COLOR), - mLayerRef(layerRef), + mLayerRef(reinterpret_cast(layerRef)), mColor(color.Packed()), mSize(width, height) { } - const void* GetLayerRef() const { return mLayerRef; } - uint32_t GetColor() const { return mColor; } - const nsIntSize& GetSize() const { return mSize; } - virtual bool Write() override { Packet packet; packet.set_type(mDataType); ColorPacket* cp = packet.mutable_color(); - cp->set_layerref(reinterpret_cast(mLayerRef)); + cp->set_layerref(mLayerRef); cp->set_color(mColor); cp->set_width(mSize.width); cp->set_height(mSize.height); - if (!WriteToStream(packet)) - return false; - return true; + return WriteToStream(packet); } protected: - void* mLayerRef; + uint64_t mLayerRef; uint32_t mColor; nsIntSize mSize; }; -class DebugGLLayersData : public DebugGLData { +class DebugGLLayersData final: public DebugGLData { public: explicit DebugGLLayersData(UniquePtr aPacket) : DebugGLData(Packet::LAYERS), @@ -407,17 +387,14 @@ public: virtual bool Write() override { mPacket->set_type(mDataType); - - if (!WriteToStream(*mPacket)) - return false; - return true; + return WriteToStream(*mPacket); } protected: UniquePtr mPacket; }; -class DebugGLMetaData : public DebugGLData +class DebugGLMetaData final: public DebugGLData { public: DebugGLMetaData(Packet::DataType aDataType, @@ -438,15 +415,69 @@ public: MetaPacket* mp = packet.mutable_meta(); mp->set_composedbyhwc(mComposedByHwc); - if (!WriteToStream(packet)) - return false; - return true; + return WriteToStream(packet); } protected: bool mComposedByHwc; }; +class DebugGLDrawData final: public DebugGLData { +public: + DebugGLDrawData(float aOffsetX, + float aOffsetY, + const gfx::Matrix4x4& aMVMatrix, + size_t aRects, + const gfx::Rect* aLayerRects, + void* aLayerRef) + : DebugGLData(Packet::DRAW), + mOffsetX(aOffsetX), + mOffsetY(aOffsetY), + mMVMatrix(aMVMatrix), + mRects(aRects), + mLayerRef(reinterpret_cast(aLayerRef)) + { + for (size_t i = 0; i < mRects; i++){ + mLayerRects[i] = aLayerRects[i]; + } + } + + virtual bool Write() override { + Packet packet; + packet.set_type(mDataType); + + DrawPacket* dp = packet.mutable_draw(); + dp->set_layerref(mLayerRef); + + dp->set_offsetx(mOffsetX); + dp->set_offsety(mOffsetY); + + auto element = reinterpret_cast(&mMVMatrix); + for (int i = 0; i < 16; i++) { + dp->add_mvmatrix(*element++); + } + dp->set_totalrects(mRects); + + MOZ_ASSERT(mRects > 0 && mRects < 4); + for (size_t i = 0; i < mRects; i++) { + layerscope::DrawPacket::Rect* pRect = dp->add_layerrect(); + pRect->set_x(mLayerRects[i].x); + pRect->set_y(mLayerRects[i].y); + pRect->set_w(mLayerRects[i].width); + pRect->set_h(mLayerRects[i].height); + } + + return WriteToStream(packet); + } + +protected: + float mOffsetX; + float mOffsetY; + gfx::Matrix4x4 mMVMatrix; + size_t mRects; + gfx::Rect mLayerRects[4]; + uint64_t mLayerRef; +}; class DebugListener : public nsIServerSocketListener { @@ -772,7 +803,6 @@ SenderHelper::SendEffectChain(GLContext* aGLContext, // TODO: } - // ---------------------------------------------- // LayerScopeWebSocketHandler implementation // ---------------------------------------------- @@ -1265,16 +1295,107 @@ LayerScope::Init() } } +class DrawSession { +public: + NS_INLINE_DECL_REFCOUNTING(DrawSession) + + DrawSession() + : mOffsetX(0.0), + mOffsetY(0.0), + mRects(0) + { } + + float mOffsetX; + float mOffsetY; + gfx::Matrix4x4 mMVMatrix; + size_t mRects; + gfx::Rect mLayerRects[4]; +private: + ~DrawSession() {} +}; + +class DrawSessionHolder { +public: + static void setSession(DrawSession *aSession) { + mSession = aSession; + } + + static DrawSession& current() { + return *mSession; + } + +private: + static nsRefPtr mSession; +}; + +nsRefPtr DrawSessionHolder::mSession; + void -LayerScope::SendEffectChain(gl::GLContext* aGLContext, - const EffectChain& aEffectChain, - int aWidth, - int aHeight) +LayerScope::DrawBegin() +{ + if (!CheckSendable()) { + return; + } + + DrawSessionHolder::setSession(new DrawSession()); +} + +void LayerScope::SetRenderOffset(float aX, float aY) +{ + if (!CheckSendable()) { + return; + } + + DrawSessionHolder::current().mOffsetX = aX; + DrawSessionHolder::current().mOffsetY = aY; +} + +void LayerScope::SetLayerTransform(const gfx::Matrix4x4& aMatrix) +{ + if (!CheckSendable()) { + return; + } + + DrawSessionHolder::current().mMVMatrix = aMatrix; +} + +void LayerScope::SetLayerRects(size_t aRects, const gfx::Rect* aLayerRects) +{ + if (!CheckSendable()) { + return; + } + + MOZ_ASSERT(aRects > 0 && aRects <= 4); + MOZ_ASSERT(aLayerRects); + + DrawSessionHolder::current().mRects = aRects; + + for (size_t i = 0; i < aRects; i++){ + DrawSessionHolder::current().mLayerRects[i] = aLayerRects[i]; + } +} + +void +LayerScope::DrawEnd(gl::GLContext* aGLContext, + const EffectChain& aEffectChain, + int aWidth, + int aHeight) { // Protect this public function if (!CheckSendable()) { return; } + + // 1. Send parameters of draw call, such as uniforms and attributes of + // vertex adnd fragment shader. + DrawSession& draws = DrawSessionHolder::current(); + WebSocketHelper::GetSocketManager()->AppendDebugData( + new DebugGLDrawData(draws.mOffsetX, draws.mOffsetY, + draws.mMVMatrix, draws.mRects, + draws.mLayerRects, + aEffectChain.mLayerRef)); + + // 2. Send textures. SenderHelper::SendEffectChain(aGLContext, aEffectChain, aWidth, aHeight); } @@ -1328,7 +1449,6 @@ LayerScope::CleanLayer() } } - void LayerScope::SetHWComposed() { diff --git a/gfx/layers/LayerScope.h b/gfx/layers/LayerScope.h index 18aa89fdd5..7c8d8e8e68 100644 --- a/gfx/layers/LayerScope.h +++ b/gfx/layers/LayerScope.h @@ -23,10 +23,15 @@ class LayerComposite; class LayerScope { public: - static void SendEffectChain(gl::GLContext* aGLContext, - const EffectChain& aEffectChain, - int aWidth, - int aHeight); + static void DrawBegin(); + static void SetRenderOffset(float aX, float aY); + static void SetLayerTransform(const gfx::Matrix4x4& aMatrix); + static void SetLayerRects(size_t aRects, const gfx::Rect* aLayerRects); + static void DrawEnd(gl::GLContext* aGLContext, + const EffectChain& aEffectChain, + int aWidth, + int aHeight); + static void SendLayer(LayerComposite* aLayer, int aWidth, int aHeight); diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 76eb5af87c..35afc05638 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -1712,6 +1712,25 @@ Layer::DumpPacket(layerscope::LayersPacket* aPacket, const void* aParent) if (!mVisibleRegion.IsEmpty()) { DumpRegion(layer->mutable_vregion(), mVisibleRegion); } + // EventRegions + if (!mEventRegions.IsEmpty()) { + const EventRegions &e = mEventRegions; + if (!e.mHitRegion.IsEmpty()) { + DumpRegion(layer->mutable_hitregion(), e.mHitRegion); + } + if (!e.mDispatchToContentHitRegion.IsEmpty()) { + DumpRegion(layer->mutable_dispatchregion(), e.mDispatchToContentHitRegion); + } + if (!e.mNoActionRegion.IsEmpty()) { + DumpRegion(layer->mutable_noactionregion(), e.mNoActionRegion); + } + if (!e.mHorizontalPanRegion.IsEmpty()) { + DumpRegion(layer->mutable_hpanregion(), e.mHorizontalPanRegion); + } + if (!e.mVerticalPanRegion.IsEmpty()) { + DumpRegion(layer->mutable_vpanregion(), e.mVerticalPanRegion); + } + } // Opacity layer->set_opacity(mOpacity); // Content opaque diff --git a/gfx/layers/apz/util/APZEventState.cpp b/gfx/layers/apz/util/APZEventState.cpp index bba10e1e73..763faeb511 100644 --- a/gfx/layers/apz/util/APZEventState.cpp +++ b/gfx/layers/apz/util/APZEventState.cpp @@ -344,7 +344,7 @@ APZEventState::ProcessAPZStateChange(const nsCOMPtr& aDocument, nsCOMPtr docshell(aDocument->GetDocShell()); if (docshell && sf) { nsDocShell* nsdocshell = static_cast(docshell.get()); - nsdocshell->NotifyAsyncPanZoomStarted(sf->GetScrollPositionCSSPixels()); + nsdocshell->NotifyAsyncPanZoomStarted(); } } mActiveAPZTransforms++; @@ -366,7 +366,7 @@ APZEventState::ProcessAPZStateChange(const nsCOMPtr& aDocument, nsCOMPtr docshell(aDocument->GetDocShell()); if (docshell && sf) { nsDocShell* nsdocshell = static_cast(docshell.get()); - nsdocshell->NotifyAsyncPanZoomStopped(sf->GetScrollPositionCSSPixels()); + nsdocshell->NotifyAsyncPanZoomStopped(); } } break; diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index dca5379ba5..0513011e05 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -425,6 +425,7 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg, aTexCoordRect, &layerRects, &textureRects); + BindAndDrawQuads(aProg, rects, layerRects, textureRects); } @@ -912,6 +913,7 @@ CompositorOGL::DrawQuad(const Rect& aRect, DrawVRDistortion(aRect, aClipRect, aEffectChain, aOpacity, aTransform); return; } + LayerScope::DrawBegin(); Rect clipRect = aClipRect; // aClipRect is in destination coordinate space (after all @@ -927,9 +929,6 @@ CompositorOGL::DrawQuad(const Rect& aRect, gl()->fScissor(intClipRect.x, FlipY(intClipRect.y + intClipRect.height), intClipRect.width, intClipRect.height); - LayerScope::SendEffectChain(mGLContext, aEffectChain, - aRect.width, aRect.height); - MaskType maskType; EffectMask* effectMask; TextureSourceOGL* sourceMask = nullptr; @@ -1002,7 +1001,7 @@ CompositorOGL::DrawQuad(const Rect& aRect, ActivateProgram(program); program->SetProjectionMatrix(mProjMatrix); program->SetLayerTransform(aTransform); - + LayerScope::SetLayerTransform(aTransform); if (colorMatrix) { EffectColorMatrix* effectColorMatrix = static_cast(aEffectChain.mSecondaryEffects[EffectTypes::COLOR_MATRIX].get()); @@ -1011,6 +1010,8 @@ CompositorOGL::DrawQuad(const Rect& aRect, IntPoint offset = mCurrentRenderTarget->GetOrigin(); program->SetRenderOffset(offset.x, offset.y); + LayerScope::SetRenderOffset(offset.x, offset.y); + if (aOpacity != 1.f) program->SetLayerOpacity(aOpacity); if (config.mFeatures & ENABLE_TEXTURE_RECT) { @@ -1209,6 +1210,7 @@ CompositorOGL::DrawQuad(const Rect& aRect, // in case rendering has used some other GL context MakeCurrent(); + LayerScope::DrawEnd(mGLContext, aEffectChain, aRect.width, aRect.height); } void @@ -1471,6 +1473,7 @@ CompositorOGL::BindAndDrawQuads(ShaderProgramOGL *aProg, // We are using GL_TRIANGLES here because the Mac Intel drivers fail to properly // process uniform arrays with GL_TRIANGLE_STRIP. Go figure. mGLContext->fDrawArrays(LOCAL_GL_TRIANGLES, 0, 6 * aQuads); + LayerScope::SetLayerRects(aQuads, aLayerRects); } GLBlitTextureImageHelper* diff --git a/gfx/layers/protobuf/LayerScopePacket.pb.cc b/gfx/layers/protobuf/LayerScopePacket.pb.cc index 3c07257b29..0bc11b1c9e 100644 --- a/gfx/layers/protobuf/LayerScopePacket.pb.cc +++ b/gfx/layers/protobuf/LayerScopePacket.pb.cc @@ -1,13 +1,16 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! +// source: LayerScopePacket.proto #define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION #include "LayerScopePacket.pb.h" #include +#include #include #include #include +#include // @@protoc_insertion_point(includes) namespace mozilla { @@ -26,16 +29,24 @@ void protobuf_ShutdownFile_LayerScopePacket_2eproto() { delete LayersPacket_Layer_Matrix::default_instance_; delete LayersPacket_Layer_Shadow::default_instance_; delete MetaPacket::default_instance_; + delete DrawPacket::default_instance_; + delete DrawPacket_Rect::default_instance_; delete Packet::default_instance_; delete CommandPacket::default_instance_; } +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER +void protobuf_AddDesc_LayerScopePacket_2eproto_impl() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + +#else void protobuf_AddDesc_LayerScopePacket_2eproto() { static bool already_here = false; if (already_here) return; already_here = true; GOOGLE_PROTOBUF_VERIFY_VERSION; +#endif FramePacket::default_instance_ = new FramePacket(); ColorPacket::default_instance_ = new ColorPacket(); TexturePacket::default_instance_ = new TexturePacket(); @@ -47,6 +58,8 @@ void protobuf_AddDesc_LayerScopePacket_2eproto() { LayersPacket_Layer_Matrix::default_instance_ = new LayersPacket_Layer_Matrix(); LayersPacket_Layer_Shadow::default_instance_ = new LayersPacket_Layer_Shadow(); MetaPacket::default_instance_ = new MetaPacket(); + DrawPacket::default_instance_ = new DrawPacket(); + DrawPacket_Rect::default_instance_ = new DrawPacket_Rect(); Packet::default_instance_ = new Packet(); CommandPacket::default_instance_ = new CommandPacket(); FramePacket::default_instance_->InitAsDefaultInstance(); @@ -60,18 +73,27 @@ void protobuf_AddDesc_LayerScopePacket_2eproto() { LayersPacket_Layer_Matrix::default_instance_->InitAsDefaultInstance(); LayersPacket_Layer_Shadow::default_instance_->InitAsDefaultInstance(); MetaPacket::default_instance_->InitAsDefaultInstance(); + DrawPacket::default_instance_->InitAsDefaultInstance(); + DrawPacket_Rect::default_instance_->InitAsDefaultInstance(); Packet::default_instance_->InitAsDefaultInstance(); CommandPacket::default_instance_->InitAsDefaultInstance(); ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_LayerScopePacket_2eproto); } +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER +GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AddDesc_LayerScopePacket_2eproto_once_); +void protobuf_AddDesc_LayerScopePacket_2eproto() { + ::google::protobuf::GoogleOnceInit(&protobuf_AddDesc_LayerScopePacket_2eproto_once_, + &protobuf_AddDesc_LayerScopePacket_2eproto_impl); +} +#else // Force AddDescriptors() to be called at static initialization time. struct StaticDescriptorInitializer_LayerScopePacket_2eproto { StaticDescriptorInitializer_LayerScopePacket_2eproto() { protobuf_AddDesc_LayerScopePacket_2eproto(); } } static_descriptor_initializer_LayerScopePacket_2eproto_; - +#endif // =================================================================== @@ -82,6 +104,7 @@ const int FramePacket::kValueFieldNumber; FramePacket::FramePacket() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.FramePacket) } void FramePacket::InitAsDefaultInstance() { @@ -91,6 +114,7 @@ FramePacket::FramePacket(const FramePacket& from) : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.FramePacket) } void FramePacket::SharedCtor() { @@ -100,11 +124,16 @@ void FramePacket::SharedCtor() { } FramePacket::~FramePacket() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.FramePacket) SharedDtor(); } void FramePacket::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -114,7 +143,12 @@ void FramePacket::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const FramePacket& FramePacket::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } FramePacket* FramePacket::default_instance_ = NULL; @@ -124,60 +158,77 @@ FramePacket* FramePacket::New() const { } void FramePacket::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - value_ = GOOGLE_ULONGLONG(0); - } + value_ = GOOGLE_ULONGLONG(0); ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool FramePacket::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.FramePacket) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional uint64 value = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &value_))); set_has_value(); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.FramePacket) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.FramePacket) + return false; #undef DO_ } void FramePacket::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.FramePacket) // optional uint64 value = 1; if (has_value()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->value(), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.FramePacket) } int FramePacket::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // optional uint64 value = 1; if (has_value()) { @@ -185,8 +236,10 @@ int FramePacket::ByteSize() const { ::google::protobuf::internal::WireFormatLite::UInt64Size( this->value()); } - + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -205,6 +258,7 @@ void FramePacket::MergeFrom(const FramePacket& from) { set_value(from.value()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void FramePacket::CopyFrom(const FramePacket& from) { @@ -214,7 +268,7 @@ void FramePacket::CopyFrom(const FramePacket& from) { } bool FramePacket::IsInitialized() const { - + return true; } @@ -222,6 +276,7 @@ void FramePacket::Swap(FramePacket* other) { if (other != this) { std::swap(value_, other->value_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -243,6 +298,7 @@ const int ColorPacket::kColorFieldNumber; ColorPacket::ColorPacket() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.ColorPacket) } void ColorPacket::InitAsDefaultInstance() { @@ -252,6 +308,7 @@ ColorPacket::ColorPacket(const ColorPacket& from) : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.ColorPacket) } void ColorPacket::SharedCtor() { @@ -264,11 +321,16 @@ void ColorPacket::SharedCtor() { } ColorPacket::~ColorPacket() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.ColorPacket) SharedDtor(); } void ColorPacket::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -278,7 +340,12 @@ void ColorPacket::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const ColorPacket& ColorPacket::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } ColorPacket* ColorPacket::default_instance_ = NULL; @@ -288,126 +355,151 @@ ColorPacket* ColorPacket::New() const { } void ColorPacket::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - layerref_ = GOOGLE_ULONGLONG(0); - width_ = 0u; - height_ = 0u; - color_ = 0u; - } +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(layerref_, color_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool ColorPacket::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.ColorPacket) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // required uint64 layerref = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &layerref_))); set_has_layerref(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(16)) goto parse_width; break; } - + // optional uint32 width = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 16) { parse_width: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &width_))); set_has_width(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(24)) goto parse_height; break; } - + // optional uint32 height = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 24) { parse_height: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &height_))); set_has_height(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(32)) goto parse_color; break; } - + // optional uint32 color = 4; case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 32) { parse_color: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &color_))); set_has_color(); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.ColorPacket) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.ColorPacket) + return false; #undef DO_ } void ColorPacket::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.ColorPacket) // required uint64 layerref = 1; if (has_layerref()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->layerref(), output); } - + // optional uint32 width = 2; if (has_width()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->width(), output); } - + // optional uint32 height = 3; if (has_height()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->height(), output); } - + // optional uint32 color = 4; if (has_color()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->color(), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.ColorPacket) } int ColorPacket::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // required uint64 layerref = 1; if (has_layerref()) { @@ -415,29 +507,31 @@ int ColorPacket::ByteSize() const { ::google::protobuf::internal::WireFormatLite::UInt64Size( this->layerref()); } - + // optional uint32 width = 2; if (has_width()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->width()); } - + // optional uint32 height = 3; if (has_height()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->height()); } - + // optional uint32 color = 4; if (has_color()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->color()); } - + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -465,6 +559,7 @@ void ColorPacket::MergeFrom(const ColorPacket& from) { set_color(from.color()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void ColorPacket::CopyFrom(const ColorPacket& from) { @@ -475,7 +570,7 @@ void ColorPacket::CopyFrom(const ColorPacket& from) { bool ColorPacket::IsInitialized() const { if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; - + return true; } @@ -486,6 +581,7 @@ void ColorPacket::Swap(ColorPacket* other) { std::swap(height_, other->height_); std::swap(color_, other->color_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -512,6 +608,7 @@ const int TexturePacket::kDataFieldNumber; TexturePacket::TexturePacket() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.TexturePacket) } void TexturePacket::InitAsDefaultInstance() { @@ -521,9 +618,11 @@ TexturePacket::TexturePacket(const TexturePacket& from) : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.TexturePacket) } void TexturePacket::SharedCtor() { + ::google::protobuf::internal::GetEmptyString(); _cached_size_ = 0; layerref_ = GOOGLE_ULONGLONG(0); width_ = 0u; @@ -533,19 +632,24 @@ void TexturePacket::SharedCtor() { target_ = 0u; dataformat_ = 0u; glcontext_ = GOOGLE_ULONGLONG(0); - data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); ::memset(_has_bits_, 0, sizeof(_has_bits_)); } TexturePacket::~TexturePacket() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.TexturePacket) SharedDtor(); } void TexturePacket::SharedDtor() { - if (data_ != &::google::protobuf::internal::kEmptyString) { + if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { delete data_; } + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -555,7 +659,12 @@ void TexturePacket::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const TexturePacket& TexturePacket::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } TexturePacket* TexturePacket::default_instance_ = NULL; @@ -565,241 +674,257 @@ TexturePacket* TexturePacket::New() const { } void TexturePacket::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - layerref_ = GOOGLE_ULONGLONG(0); - width_ = 0u; - height_ = 0u; - stride_ = 0u; - name_ = 0u; - target_ = 0u; - dataformat_ = 0u; - glcontext_ = GOOGLE_ULONGLONG(0); +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 255) { + ZR_(layerref_, glcontext_); } - if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { - if (has_data()) { - if (data_ != &::google::protobuf::internal::kEmptyString) { - data_->clear(); - } + if (has_data()) { + if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + data_->clear(); } } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool TexturePacket::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.TexturePacket) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // required uint64 layerref = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &layerref_))); set_has_layerref(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(16)) goto parse_width; break; } - + // optional uint32 width = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 16) { parse_width: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &width_))); set_has_width(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(24)) goto parse_height; break; } - + // optional uint32 height = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 24) { parse_height: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &height_))); set_has_height(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(32)) goto parse_stride; break; } - + // optional uint32 stride = 4; case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 32) { parse_stride: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &stride_))); set_has_stride(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(40)) goto parse_name; break; } - + // optional uint32 name = 5; case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 40) { parse_name: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &name_))); set_has_name(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(48)) goto parse_target; break; } - + // optional uint32 target = 6; case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 48) { parse_target: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &target_))); set_has_target(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(56)) goto parse_dataformat; break; } - + // optional uint32 dataformat = 7; case 7: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 56) { parse_dataformat: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &dataformat_))); set_has_dataformat(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(64)) goto parse_glcontext; break; } - + // optional uint64 glcontext = 8; case 8: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 64) { parse_glcontext: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &glcontext_))); set_has_glcontext(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(74)) goto parse_data; break; } - + // optional bytes data = 9; case 9: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 74) { parse_data: DO_(::google::protobuf::internal::WireFormatLite::ReadBytes( input, this->mutable_data())); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.TexturePacket) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.TexturePacket) + return false; #undef DO_ } void TexturePacket::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.TexturePacket) // required uint64 layerref = 1; if (has_layerref()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->layerref(), output); } - + // optional uint32 width = 2; if (has_width()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(2, this->width(), output); } - + // optional uint32 height = 3; if (has_height()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(3, this->height(), output); } - + // optional uint32 stride = 4; if (has_stride()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->stride(), output); } - + // optional uint32 name = 5; if (has_name()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(5, this->name(), output); } - + // optional uint32 target = 6; if (has_target()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(6, this->target(), output); } - + // optional uint32 dataformat = 7; if (has_dataformat()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(7, this->dataformat(), output); } - + // optional uint64 glcontext = 8; if (has_glcontext()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(8, this->glcontext(), output); } - + // optional bytes data = 9; if (has_data()) { - ::google::protobuf::internal::WireFormatLite::WriteBytes( + ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( 9, this->data(), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.TexturePacket) } int TexturePacket::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // required uint64 layerref = 1; if (has_layerref()) { @@ -807,56 +932,56 @@ int TexturePacket::ByteSize() const { ::google::protobuf::internal::WireFormatLite::UInt64Size( this->layerref()); } - + // optional uint32 width = 2; if (has_width()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->width()); } - + // optional uint32 height = 3; if (has_height()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->height()); } - + // optional uint32 stride = 4; if (has_stride()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->stride()); } - + // optional uint32 name = 5; if (has_name()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->name()); } - + // optional uint32 target = 6; if (has_target()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->target()); } - + // optional uint32 dataformat = 7; if (has_dataformat()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->dataformat()); } - + // optional uint64 glcontext = 8; if (has_glcontext()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->glcontext()); } - + } if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { // optional bytes data = 9; @@ -865,8 +990,10 @@ int TexturePacket::ByteSize() const { ::google::protobuf::internal::WireFormatLite::BytesSize( this->data()); } - + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -911,6 +1038,7 @@ void TexturePacket::MergeFrom(const TexturePacket& from) { set_data(from.data()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void TexturePacket::CopyFrom(const TexturePacket& from) { @@ -921,7 +1049,7 @@ void TexturePacket::CopyFrom(const TexturePacket& from) { bool TexturePacket::IsInitialized() const { if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; - + return true; } @@ -937,6 +1065,7 @@ void TexturePacket::Swap(TexturePacket* other) { std::swap(glcontext_, other->glcontext_); std::swap(data_, other->data_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -1031,6 +1160,7 @@ const int LayersPacket_Layer_Size::kHFieldNumber; LayersPacket_Layer_Size::LayersPacket_Layer_Size() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Size) } void LayersPacket_Layer_Size::InitAsDefaultInstance() { @@ -1040,6 +1170,7 @@ LayersPacket_Layer_Size::LayersPacket_Layer_Size(const LayersPacket_Layer_Size& : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Size) } void LayersPacket_Layer_Size::SharedCtor() { @@ -1050,11 +1181,16 @@ void LayersPacket_Layer_Size::SharedCtor() { } LayersPacket_Layer_Size::~LayersPacket_Layer_Size() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Size) SharedDtor(); } void LayersPacket_Layer_Size::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -1064,7 +1200,12 @@ void LayersPacket_Layer_Size::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const LayersPacket_Layer_Size& LayersPacket_Layer_Size::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } LayersPacket_Layer_Size* LayersPacket_Layer_Size::default_instance_ = NULL; @@ -1074,82 +1215,111 @@ LayersPacket_Layer_Size* LayersPacket_Layer_Size::New() const { } void LayersPacket_Layer_Size::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - w_ = 0; - h_ = 0; - } +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(w_, h_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool LayersPacket_Layer_Size::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Size) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional int32 w = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &w_))); set_has_w(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(16)) goto parse_h; break; } - + // optional int32 h = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 16) { parse_h: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &h_))); set_has_h(); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Size) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Size) + return false; #undef DO_ } void LayersPacket_Layer_Size::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Size) // optional int32 w = 1; if (has_w()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->w(), output); } - + // optional int32 h = 2; if (has_h()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->h(), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Size) } int LayersPacket_Layer_Size::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // optional int32 w = 1; if (has_w()) { @@ -1157,15 +1327,17 @@ int LayersPacket_Layer_Size::ByteSize() const { ::google::protobuf::internal::WireFormatLite::Int32Size( this->w()); } - + // optional int32 h = 2; if (has_h()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::Int32Size( this->h()); } - + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -1187,6 +1359,7 @@ void LayersPacket_Layer_Size::MergeFrom(const LayersPacket_Layer_Size& from) { set_h(from.h()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void LayersPacket_Layer_Size::CopyFrom(const LayersPacket_Layer_Size& from) { @@ -1196,7 +1369,7 @@ void LayersPacket_Layer_Size::CopyFrom(const LayersPacket_Layer_Size& from) { } bool LayersPacket_Layer_Size::IsInitialized() const { - + return true; } @@ -1205,6 +1378,7 @@ void LayersPacket_Layer_Size::Swap(LayersPacket_Layer_Size* other) { std::swap(w_, other->w_); std::swap(h_, other->h_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -1226,6 +1400,7 @@ const int LayersPacket_Layer_Rect::kHFieldNumber; LayersPacket_Layer_Rect::LayersPacket_Layer_Rect() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Rect) } void LayersPacket_Layer_Rect::InitAsDefaultInstance() { @@ -1235,6 +1410,7 @@ LayersPacket_Layer_Rect::LayersPacket_Layer_Rect(const LayersPacket_Layer_Rect& : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Rect) } void LayersPacket_Layer_Rect::SharedCtor() { @@ -1247,11 +1423,16 @@ void LayersPacket_Layer_Rect::SharedCtor() { } LayersPacket_Layer_Rect::~LayersPacket_Layer_Rect() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Rect) SharedDtor(); } void LayersPacket_Layer_Rect::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -1261,7 +1442,12 @@ void LayersPacket_Layer_Rect::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const LayersPacket_Layer_Rect& LayersPacket_Layer_Rect::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } LayersPacket_Layer_Rect* LayersPacket_Layer_Rect::default_instance_ = NULL; @@ -1271,126 +1457,151 @@ LayersPacket_Layer_Rect* LayersPacket_Layer_Rect::New() const { } void LayersPacket_Layer_Rect::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - x_ = 0; - y_ = 0; - w_ = 0; - h_ = 0; - } +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(x_, h_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool LayersPacket_Layer_Rect::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Rect) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional int32 x = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &x_))); set_has_x(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(16)) goto parse_y; break; } - + // optional int32 y = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 16) { parse_y: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &y_))); set_has_y(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(24)) goto parse_w; break; } - + // optional int32 w = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 24) { parse_w: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &w_))); set_has_w(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(32)) goto parse_h; break; } - + // optional int32 h = 4; case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 32) { parse_h: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>( input, &h_))); set_has_h(); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Rect) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Rect) + return false; #undef DO_ } void LayersPacket_Layer_Rect::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Rect) // optional int32 x = 1; if (has_x()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->x(), output); } - + // optional int32 y = 2; if (has_y()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->y(), output); } - + // optional int32 w = 3; if (has_w()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->w(), output); } - + // optional int32 h = 4; if (has_h()) { ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->h(), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Rect) } int LayersPacket_Layer_Rect::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // optional int32 x = 1; if (has_x()) { @@ -1398,29 +1609,31 @@ int LayersPacket_Layer_Rect::ByteSize() const { ::google::protobuf::internal::WireFormatLite::Int32Size( this->x()); } - + // optional int32 y = 2; if (has_y()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::Int32Size( this->y()); } - + // optional int32 w = 3; if (has_w()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::Int32Size( this->w()); } - + // optional int32 h = 4; if (has_h()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::Int32Size( this->h()); } - + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -1448,6 +1661,7 @@ void LayersPacket_Layer_Rect::MergeFrom(const LayersPacket_Layer_Rect& from) { set_h(from.h()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void LayersPacket_Layer_Rect::CopyFrom(const LayersPacket_Layer_Rect& from) { @@ -1457,7 +1671,7 @@ void LayersPacket_Layer_Rect::CopyFrom(const LayersPacket_Layer_Rect& from) { } bool LayersPacket_Layer_Rect::IsInitialized() const { - + return true; } @@ -1468,6 +1682,7 @@ void LayersPacket_Layer_Rect::Swap(LayersPacket_Layer_Rect* other) { std::swap(w_, other->w_); std::swap(h_, other->h_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -1486,6 +1701,7 @@ const int LayersPacket_Layer_Region::kRFieldNumber; LayersPacket_Layer_Region::LayersPacket_Layer_Region() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Region) } void LayersPacket_Layer_Region::InitAsDefaultInstance() { @@ -1495,6 +1711,7 @@ LayersPacket_Layer_Region::LayersPacket_Layer_Region(const LayersPacket_Layer_Re : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Region) } void LayersPacket_Layer_Region::SharedCtor() { @@ -1503,11 +1720,16 @@ void LayersPacket_Layer_Region::SharedCtor() { } LayersPacket_Layer_Region::~LayersPacket_Layer_Region() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Region) SharedDtor(); } void LayersPacket_Layer_Region::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -1517,7 +1739,12 @@ void LayersPacket_Layer_Region::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const LayersPacket_Layer_Region& LayersPacket_Layer_Region::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } LayersPacket_Layer_Region* LayersPacket_Layer_Region::default_instance_ = NULL; @@ -1529,57 +1756,76 @@ LayersPacket_Layer_Region* LayersPacket_Layer_Region::New() const { void LayersPacket_Layer_Region::Clear() { r_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool LayersPacket_Layer_Region::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Region) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .mozilla.layers.layerscope.LayersPacket.Layer.Rect r = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 10) { parse_r: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_r())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(10)) goto parse_r; - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Region) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Region) + return false; #undef DO_ } void LayersPacket_Layer_Region::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Region) // repeated .mozilla.layers.layerscope.LayersPacket.Layer.Rect r = 1; for (int i = 0; i < this->r_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 1, this->r(i), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Region) } int LayersPacket_Layer_Region::ByteSize() const { int total_size = 0; - + // repeated .mozilla.layers.layerscope.LayersPacket.Layer.Rect r = 1; total_size += 1 * this->r_size(); for (int i = 0; i < this->r_size(); i++) { @@ -1587,7 +1833,9 @@ int LayersPacket_Layer_Region::ByteSize() const { ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->r(i)); } - + + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -1602,6 +1850,7 @@ void LayersPacket_Layer_Region::CheckTypeAndMergeFrom( void LayersPacket_Layer_Region::MergeFrom(const LayersPacket_Layer_Region& from) { GOOGLE_CHECK_NE(&from, this); r_.MergeFrom(from.r_); + mutable_unknown_fields()->append(from.unknown_fields()); } void LayersPacket_Layer_Region::CopyFrom(const LayersPacket_Layer_Region& from) { @@ -1611,7 +1860,7 @@ void LayersPacket_Layer_Region::CopyFrom(const LayersPacket_Layer_Region& from) } bool LayersPacket_Layer_Region::IsInitialized() const { - + return true; } @@ -1619,6 +1868,7 @@ void LayersPacket_Layer_Region::Swap(LayersPacket_Layer_Region* other) { if (other != this) { r_.Swap(&other->r_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -1639,6 +1889,7 @@ const int LayersPacket_Layer_Matrix::kMFieldNumber; LayersPacket_Layer_Matrix::LayersPacket_Layer_Matrix() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Matrix) } void LayersPacket_Layer_Matrix::InitAsDefaultInstance() { @@ -1648,6 +1899,7 @@ LayersPacket_Layer_Matrix::LayersPacket_Layer_Matrix(const LayersPacket_Layer_Ma : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Matrix) } void LayersPacket_Layer_Matrix::SharedCtor() { @@ -1658,11 +1910,16 @@ void LayersPacket_Layer_Matrix::SharedCtor() { } LayersPacket_Layer_Matrix::~LayersPacket_Layer_Matrix() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Matrix) SharedDtor(); } void LayersPacket_Layer_Matrix::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -1672,7 +1929,12 @@ void LayersPacket_Layer_Matrix::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const LayersPacket_Layer_Matrix& LayersPacket_Layer_Matrix::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } LayersPacket_Layer_Matrix* LayersPacket_Layer_Matrix::default_instance_ = NULL; @@ -1682,122 +1944,148 @@ LayersPacket_Layer_Matrix* LayersPacket_Layer_Matrix::New() const { } void LayersPacket_Layer_Matrix::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - is2d_ = false; - isid_ = false; - } +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(is2d_, isid_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + m_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool LayersPacket_Layer_Matrix::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Matrix) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional bool is2D = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &is2d_))); set_has_is2d(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(16)) goto parse_isId; break; } - + // optional bool isId = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 16) { parse_isId: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &isid_))); set_has_isid(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(29)) goto parse_m; break; } - + // repeated float m = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + if (tag == 29) { parse_m: DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( 1, 29, input, this->mutable_m()))); - } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) - == ::google::protobuf::internal::WireFormatLite:: - WIRETYPE_LENGTH_DELIMITED) { + } else if (tag == 26) { DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( input, this->mutable_m()))); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(29)) goto parse_m; - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Matrix) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Matrix) + return false; #undef DO_ } void LayersPacket_Layer_Matrix::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Matrix) // optional bool is2D = 1; if (has_is2d()) { ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->is2d(), output); } - + // optional bool isId = 2; if (has_isid()) { ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->isid(), output); } - + // repeated float m = 3; for (int i = 0; i < this->m_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteFloat( 3, this->m(i), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Matrix) } int LayersPacket_Layer_Matrix::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // optional bool is2D = 1; if (has_is2d()) { total_size += 1 + 1; } - + // optional bool isId = 2; if (has_isid()) { total_size += 1 + 1; } - + } // repeated float m = 3; { @@ -1805,7 +2093,9 @@ int LayersPacket_Layer_Matrix::ByteSize() const { data_size = 4 * this->m_size(); total_size += 1 * this->m_size() + data_size; } - + + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -1828,6 +2118,7 @@ void LayersPacket_Layer_Matrix::MergeFrom(const LayersPacket_Layer_Matrix& from) set_isid(from.isid()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void LayersPacket_Layer_Matrix::CopyFrom(const LayersPacket_Layer_Matrix& from) { @@ -1837,7 +2128,7 @@ void LayersPacket_Layer_Matrix::CopyFrom(const LayersPacket_Layer_Matrix& from) } bool LayersPacket_Layer_Matrix::IsInitialized() const { - + return true; } @@ -1847,6 +2138,7 @@ void LayersPacket_Layer_Matrix::Swap(LayersPacket_Layer_Matrix* other) { std::swap(isid_, other->isid_); m_.Swap(&other->m_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -1867,18 +2159,35 @@ const int LayersPacket_Layer_Shadow::kVRegionFieldNumber; LayersPacket_Layer_Shadow::LayersPacket_Layer_Shadow() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer.Shadow) } void LayersPacket_Layer_Shadow::InitAsDefaultInstance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + clip_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Rect::internal_default_instance()); +#else clip_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Rect::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + transform_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix::internal_default_instance()); +#else transform_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Matrix::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + vregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance()); +#else vregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance()); +#endif } LayersPacket_Layer_Shadow::LayersPacket_Layer_Shadow(const LayersPacket_Layer_Shadow& from) : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer.Shadow) } void LayersPacket_Layer_Shadow::SharedCtor() { @@ -1890,11 +2199,16 @@ void LayersPacket_Layer_Shadow::SharedCtor() { } LayersPacket_Layer_Shadow::~LayersPacket_Layer_Shadow() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer.Shadow) SharedDtor(); } void LayersPacket_Layer_Shadow::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif delete clip_; delete transform_; delete vregion_; @@ -1907,7 +2221,12 @@ void LayersPacket_Layer_Shadow::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const LayersPacket_Layer_Shadow& LayersPacket_Layer_Shadow::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } LayersPacket_Layer_Shadow* LayersPacket_Layer_Shadow::default_instance_ = NULL; @@ -1917,7 +2236,7 @@ LayersPacket_Layer_Shadow* LayersPacket_Layer_Shadow::New() const { } void LayersPacket_Layer_Shadow::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (_has_bits_[0 / 32] & 7) { if (has_clip()) { if (clip_ != NULL) clip_->::mozilla::layers::layerscope::LayersPacket_Layer_Rect::Clear(); } @@ -1929,95 +2248,112 @@ void LayersPacket_Layer_Shadow::Clear() { } } ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool LayersPacket_Layer_Shadow::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer.Shadow) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 10) { DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_clip())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(18)) goto parse_transform; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 18) { parse_transform: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_transform())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(26)) goto parse_vRegion; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 26) { parse_vRegion: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_vregion())); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer.Shadow) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer.Shadow) + return false; #undef DO_ } void LayersPacket_Layer_Shadow::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer.Shadow) // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 1; if (has_clip()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 1, this->clip(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2; if (has_transform()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 2, this->transform(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3; if (has_vregion()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 3, this->vregion(), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer.Shadow) } int LayersPacket_Layer_Shadow::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 1; if (has_clip()) { @@ -2025,22 +2361,24 @@ int LayersPacket_Layer_Shadow::ByteSize() const { ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->clip()); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2; if (has_transform()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->transform()); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3; if (has_vregion()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->vregion()); } - + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -2065,6 +2403,7 @@ void LayersPacket_Layer_Shadow::MergeFrom(const LayersPacket_Layer_Shadow& from) mutable_vregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.vregion()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void LayersPacket_Layer_Shadow::CopyFrom(const LayersPacket_Layer_Shadow& from) { @@ -2074,7 +2413,7 @@ void LayersPacket_Layer_Shadow::CopyFrom(const LayersPacket_Layer_Shadow& from) } bool LayersPacket_Layer_Shadow::IsInitialized() const { - + return true; } @@ -2084,6 +2423,7 @@ void LayersPacket_Layer_Shadow::Swap(LayersPacket_Layer_Shadow* other) { std::swap(transform_, other->transform_); std::swap(vregion_, other->vregion_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -2109,6 +2449,11 @@ const int LayersPacket_Layer::kCAlphaFieldNumber; const int LayersPacket_Layer::kDirectFieldNumber; const int LayersPacket_Layer::kBarIDFieldNumber; const int LayersPacket_Layer::kMaskFieldNumber; +const int LayersPacket_Layer::kHitRegionFieldNumber; +const int LayersPacket_Layer::kDispatchRegionFieldNumber; +const int LayersPacket_Layer::kNoActionRegionFieldNumber; +const int LayersPacket_Layer::kHPanRegionFieldNumber; +const int LayersPacket_Layer::kVPanRegionFieldNumber; const int LayersPacket_Layer::kValidFieldNumber; const int LayersPacket_Layer::kColorFieldNumber; const int LayersPacket_Layer::kFilterFieldNumber; @@ -2119,21 +2464,83 @@ const int LayersPacket_Layer::kSizeFieldNumber; LayersPacket_Layer::LayersPacket_Layer() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket.Layer) } void LayersPacket_Layer::InitAsDefaultInstance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + clip_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Rect::internal_default_instance()); +#else clip_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Rect::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + transform_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix::internal_default_instance()); +#else transform_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Matrix::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + vregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance()); +#else vregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + shadow_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow::internal_default_instance()); +#else shadow_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Shadow::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + hitregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance()); +#else + hitregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + dispatchregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance()); +#else + dispatchregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + noactionregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance()); +#else + noactionregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + hpanregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance()); +#else + hpanregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + vpanregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance()); +#else + vpanregion_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + valid_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Region::internal_default_instance()); +#else valid_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Region*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Region::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + size_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Size*>( + ::mozilla::layers::layerscope::LayersPacket_Layer_Size::internal_default_instance()); +#else size_ = const_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Size*>(&::mozilla::layers::layerscope::LayersPacket_Layer_Size::default_instance()); +#endif } LayersPacket_Layer::LayersPacket_Layer(const LayersPacket_Layer& from) : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket.Layer) } void LayersPacket_Layer::SharedCtor() { @@ -2151,6 +2558,11 @@ void LayersPacket_Layer::SharedCtor() { direct_ = 1; barid_ = GOOGLE_ULONGLONG(0); mask_ = GOOGLE_ULONGLONG(0); + hitregion_ = NULL; + dispatchregion_ = NULL; + noactionregion_ = NULL; + hpanregion_ = NULL; + vpanregion_ = NULL; valid_ = NULL; color_ = 0u; filter_ = 0; @@ -2160,15 +2572,25 @@ void LayersPacket_Layer::SharedCtor() { } LayersPacket_Layer::~LayersPacket_Layer() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket.Layer) SharedDtor(); } void LayersPacket_Layer::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif delete clip_; delete transform_; delete vregion_; delete shadow_; + delete hitregion_; + delete dispatchregion_; + delete noactionregion_; + delete hpanregion_; + delete vpanregion_; delete valid_; delete size_; } @@ -2180,7 +2602,12 @@ void LayersPacket_Layer::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const LayersPacket_Layer& LayersPacket_Layer::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } LayersPacket_Layer* LayersPacket_Layer::default_instance_ = NULL; @@ -2190,10 +2617,19 @@ LayersPacket_Layer* LayersPacket_Layer::New() const { } void LayersPacket_Layer::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - type_ = 0; - ptr_ = GOOGLE_ULONGLONG(0); - parentptr_ = GOOGLE_ULONGLONG(0); +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + if (_has_bits_[0 / 32] & 255) { + ZR_(ptr_, parentptr_); + ZR_(type_, opacity_); if (has_clip()) { if (clip_ != NULL) clip_->::mozilla::layers::layerscope::LayersPacket_Layer_Rect::Clear(); } @@ -2206,193 +2642,208 @@ void LayersPacket_Layer::Clear() { if (has_shadow()) { if (shadow_ != NULL) shadow_->::mozilla::layers::layerscope::LayersPacket_Layer_Shadow::Clear(); } - opacity_ = 0; } - if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { - copaque_ = false; - calpha_ = false; + if (_has_bits_[8 / 32] & 65280) { + ZR_(copaque_, calpha_); + ZR_(barid_, mask_); direct_ = 1; - barid_ = GOOGLE_ULONGLONG(0); - mask_ = GOOGLE_ULONGLONG(0); + if (has_hitregion()) { + if (hitregion_ != NULL) hitregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + } + if (has_dispatchregion()) { + if (dispatchregion_ != NULL) dispatchregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + } + if (has_noactionregion()) { + if (noactionregion_ != NULL) noactionregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + } + } + if (_has_bits_[16 / 32] & 8323072) { + ZR_(color_, refid_); + if (has_hpanregion()) { + if (hpanregion_ != NULL) hpanregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + } + if (has_vpanregion()) { + if (vpanregion_ != NULL) vpanregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + } if (has_valid()) { if (valid_ != NULL) valid_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); } - color_ = 0u; - filter_ = 0; - } - if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) { - refid_ = GOOGLE_ULONGLONG(0); if (has_size()) { if (size_ != NULL) size_->::mozilla::layers::layerscope::LayersPacket_Layer_Size::Clear(); } } + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool LayersPacket_Layer::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket.Layer) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(16383); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // required .mozilla.layers.layerscope.LayersPacket.Layer.LayerType type = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); if (::mozilla::layers::layerscope::LayersPacket_Layer_LayerType_IsValid(value)) { set_type(static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_LayerType >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); } } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(16)) goto parse_ptr; break; } - + // required uint64 ptr = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 16) { parse_ptr: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &ptr_))); set_has_ptr(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(24)) goto parse_parentPtr; break; } - + // required uint64 parentPtr = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 24) { parse_parentPtr: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &parentptr_))); set_has_parentptr(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(82)) goto parse_clip; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10; case 10: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 82) { parse_clip: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_clip())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(90)) goto parse_transform; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11; case 11: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 90) { parse_transform: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_transform())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(98)) goto parse_vRegion; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12; case 12: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 98) { parse_vRegion: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_vregion())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(106)) goto parse_shadow; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13; case 13: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 106) { parse_shadow: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_shadow())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(117)) goto parse_opacity; break; } - + // optional float opacity = 14; case 14: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED32) { + if (tag == 117) { parse_opacity: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( input, &opacity_))); set_has_opacity(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(120)) goto parse_cOpaque; break; } - + // optional bool cOpaque = 15; case 15: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 120) { parse_cOpaque: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &copaque_))); set_has_copaque(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(128)) goto parse_cAlpha; break; } - + // optional bool cAlpha = 16; case 16: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 128) { parse_cAlpha: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &calpha_))); set_has_calpha(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(136)) goto parse_direct; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17; case 17: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 136) { parse_direct: int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< @@ -2400,80 +2851,143 @@ bool LayersPacket_Layer::MergePartialFromCodedStream( input, &value))); if (::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect_IsValid(value)) { set_direct(static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); } } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(144)) goto parse_barID; break; } - + // optional uint64 barID = 18; case 18: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 144) { parse_barID: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &barid_))); set_has_barid(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(152)) goto parse_mask; break; } - + // optional uint64 mask = 19; case 19: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 152) { parse_mask: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &mask_))); set_has_mask(); } else { - goto handle_uninterpreted; + goto handle_unusual; + } + if (input->ExpectTag(162)) goto parse_hitRegion; + break; + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20; + case 20: { + if (tag == 162) { + parse_hitRegion: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_hitregion())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(170)) goto parse_dispatchRegion; + break; + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21; + case 21: { + if (tag == 170) { + parse_dispatchRegion: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_dispatchregion())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(178)) goto parse_noActionRegion; + break; + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22; + case 22: { + if (tag == 178) { + parse_noActionRegion: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_noactionregion())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(186)) goto parse_hPanRegion; + break; + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23; + case 23: { + if (tag == 186) { + parse_hPanRegion: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_hpanregion())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(194)) goto parse_vPanRegion; + break; + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24; + case 24: { + if (tag == 194) { + parse_vPanRegion: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_vpanregion())); + } else { + goto handle_unusual; } if (input->ExpectTag(802)) goto parse_valid; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100; case 100: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 802) { parse_valid: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_valid())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(808)) goto parse_color; break; } - + // optional uint32 color = 101; case 101: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 808) { parse_color: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( input, &color_))); set_has_color(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(816)) goto parse_filter; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102; case 102: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 816) { parse_filter: int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< @@ -2481,288 +2995,367 @@ bool LayersPacket_Layer::MergePartialFromCodedStream( input, &value))); if (::mozilla::layers::layerscope::LayersPacket_Layer_Filter_IsValid(value)) { set_filter(static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Filter >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); } } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(824)) goto parse_refID; break; } - + // optional uint64 refID = 103; case 103: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 824) { parse_refID: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( input, &refid_))); set_has_refid(); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(834)) goto parse_size; break; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104; case 104: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 834) { parse_size: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_size())); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket.Layer) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket.Layer) + return false; #undef DO_ } void LayersPacket_Layer::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket.Layer) // required .mozilla.layers.layerscope.LayersPacket.Layer.LayerType type = 1; if (has_type()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 1, this->type(), output); } - + // required uint64 ptr = 2; if (has_ptr()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->ptr(), output); } - + // required uint64 parentPtr = 3; if (has_parentptr()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->parentptr(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10; if (has_clip()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 10, this->clip(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11; if (has_transform()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 11, this->transform(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12; if (has_vregion()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 12, this->vregion(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13; if (has_shadow()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 13, this->shadow(), output); } - + // optional float opacity = 14; if (has_opacity()) { ::google::protobuf::internal::WireFormatLite::WriteFloat(14, this->opacity(), output); } - + // optional bool cOpaque = 15; if (has_copaque()) { ::google::protobuf::internal::WireFormatLite::WriteBool(15, this->copaque(), output); } - + // optional bool cAlpha = 16; if (has_calpha()) { ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->calpha(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17; if (has_direct()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 17, this->direct(), output); } - + // optional uint64 barID = 18; if (has_barid()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(18, this->barid(), output); } - + // optional uint64 mask = 19; if (has_mask()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(19, this->mask(), output); } - + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20; + if (has_hitregion()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 20, this->hitregion(), output); + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21; + if (has_dispatchregion()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 21, this->dispatchregion(), output); + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22; + if (has_noactionregion()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 22, this->noactionregion(), output); + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23; + if (has_hpanregion()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 23, this->hpanregion(), output); + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24; + if (has_vpanregion()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 24, this->vpanregion(), output); + } + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100; if (has_valid()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 100, this->valid(), output); } - + // optional uint32 color = 101; if (has_color()) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(101, this->color(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102; if (has_filter()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 102, this->filter(), output); } - + // optional uint64 refID = 103; if (has_refid()) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(103, this->refid(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104; if (has_size()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 104, this->size(), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket.Layer) } int LayersPacket_Layer::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // required .mozilla.layers.layerscope.LayersPacket.Layer.LayerType type = 1; if (has_type()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); } - + // required uint64 ptr = 2; if (has_ptr()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->ptr()); } - + // required uint64 parentPtr = 3; if (has_parentptr()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->parentptr()); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10; if (has_clip()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->clip()); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11; if (has_transform()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->transform()); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12; if (has_vregion()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->vregion()); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13; if (has_shadow()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->shadow()); } - + // optional float opacity = 14; if (has_opacity()) { total_size += 1 + 4; } - + } if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) { // optional bool cOpaque = 15; if (has_copaque()) { total_size += 1 + 1; } - + // optional bool cAlpha = 16; if (has_calpha()) { total_size += 2 + 1; } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17; if (has_direct()) { total_size += 2 + ::google::protobuf::internal::WireFormatLite::EnumSize(this->direct()); } - + // optional uint64 barID = 18; if (has_barid()) { total_size += 2 + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->barid()); } - + // optional uint64 mask = 19; if (has_mask()) { total_size += 2 + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->mask()); } - + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20; + if (has_hitregion()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->hitregion()); + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21; + if (has_dispatchregion()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->dispatchregion()); + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22; + if (has_noactionregion()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->noactionregion()); + } + + } + if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) { + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23; + if (has_hpanregion()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->hpanregion()); + } + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24; + if (has_vpanregion()) { + total_size += 2 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->vpanregion()); + } + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100; if (has_valid()) { total_size += 2 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->valid()); } - + // optional uint32 color = 101; if (has_color()) { total_size += 2 + ::google::protobuf::internal::WireFormatLite::UInt32Size( this->color()); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102; if (has_filter()) { total_size += 2 + ::google::protobuf::internal::WireFormatLite::EnumSize(this->filter()); } - - } - if (_has_bits_[16 / 32] & (0xffu << (16 % 32))) { + // optional uint64 refID = 103; if (has_refid()) { total_size += 2 + ::google::protobuf::internal::WireFormatLite::UInt64Size( this->refid()); } - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104; if (has_size()) { total_size += 2 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->size()); } - + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -2818,6 +3411,23 @@ void LayersPacket_Layer::MergeFrom(const LayersPacket_Layer& from) { if (from.has_mask()) { set_mask(from.mask()); } + if (from.has_hitregion()) { + mutable_hitregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.hitregion()); + } + if (from.has_dispatchregion()) { + mutable_dispatchregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.dispatchregion()); + } + if (from.has_noactionregion()) { + mutable_noactionregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.noactionregion()); + } + } + if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) { + if (from.has_hpanregion()) { + mutable_hpanregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.hpanregion()); + } + if (from.has_vpanregion()) { + mutable_vpanregion()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.vpanregion()); + } if (from.has_valid()) { mutable_valid()->::mozilla::layers::layerscope::LayersPacket_Layer_Region::MergeFrom(from.valid()); } @@ -2827,8 +3437,6 @@ void LayersPacket_Layer::MergeFrom(const LayersPacket_Layer& from) { if (from.has_filter()) { set_filter(from.filter()); } - } - if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) { if (from.has_refid()) { set_refid(from.refid()); } @@ -2836,6 +3444,7 @@ void LayersPacket_Layer::MergeFrom(const LayersPacket_Layer& from) { mutable_size()->::mozilla::layers::layerscope::LayersPacket_Layer_Size::MergeFrom(from.size()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void LayersPacket_Layer::CopyFrom(const LayersPacket_Layer& from) { @@ -2846,7 +3455,7 @@ void LayersPacket_Layer::CopyFrom(const LayersPacket_Layer& from) { bool LayersPacket_Layer::IsInitialized() const { if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false; - + return true; } @@ -2865,12 +3474,18 @@ void LayersPacket_Layer::Swap(LayersPacket_Layer* other) { std::swap(direct_, other->direct_); std::swap(barid_, other->barid_); std::swap(mask_, other->mask_); + std::swap(hitregion_, other->hitregion_); + std::swap(dispatchregion_, other->dispatchregion_); + std::swap(noactionregion_, other->noactionregion_); + std::swap(hpanregion_, other->hpanregion_); + std::swap(vpanregion_, other->vpanregion_); std::swap(valid_, other->valid_); std::swap(color_, other->color_); std::swap(filter_, other->filter_); std::swap(refid_, other->refid_); std::swap(size_, other->size_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -2889,6 +3504,7 @@ const int LayersPacket::kLayerFieldNumber; LayersPacket::LayersPacket() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.LayersPacket) } void LayersPacket::InitAsDefaultInstance() { @@ -2898,6 +3514,7 @@ LayersPacket::LayersPacket(const LayersPacket& from) : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.LayersPacket) } void LayersPacket::SharedCtor() { @@ -2906,11 +3523,16 @@ void LayersPacket::SharedCtor() { } LayersPacket::~LayersPacket() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.LayersPacket) SharedDtor(); } void LayersPacket::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -2920,7 +3542,12 @@ void LayersPacket::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const LayersPacket& LayersPacket::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } LayersPacket* LayersPacket::default_instance_ = NULL; @@ -2932,57 +3559,76 @@ LayersPacket* LayersPacket::New() const { void LayersPacket::Clear() { layer_.Clear(); ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool LayersPacket::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.LayersPacket) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // repeated .mozilla.layers.layerscope.LayersPacket.Layer layer = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 10) { parse_layer: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_layer())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(10)) goto parse_layer; - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.LayersPacket) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.LayersPacket) + return false; #undef DO_ } void LayersPacket::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.LayersPacket) // repeated .mozilla.layers.layerscope.LayersPacket.Layer layer = 1; for (int i = 0; i < this->layer_size(); i++) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 1, this->layer(i), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.LayersPacket) } int LayersPacket::ByteSize() const { int total_size = 0; - + // repeated .mozilla.layers.layerscope.LayersPacket.Layer layer = 1; total_size += 1 * this->layer_size(); for (int i = 0; i < this->layer_size(); i++) { @@ -2990,7 +3636,9 @@ int LayersPacket::ByteSize() const { ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->layer(i)); } - + + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -3005,6 +3653,7 @@ void LayersPacket::CheckTypeAndMergeFrom( void LayersPacket::MergeFrom(const LayersPacket& from) { GOOGLE_CHECK_NE(&from, this); layer_.MergeFrom(from.layer_); + mutable_unknown_fields()->append(from.unknown_fields()); } void LayersPacket::CopyFrom(const LayersPacket& from) { @@ -3014,10 +3663,8 @@ void LayersPacket::CopyFrom(const LayersPacket& from) { } bool LayersPacket::IsInitialized() const { - - for (int i = 0; i < layer_size(); i++) { - if (!this->layer(i).IsInitialized()) return false; - } + + if (!::google::protobuf::internal::AllAreInitialized(this->layer())) return false; return true; } @@ -3025,6 +3672,7 @@ void LayersPacket::Swap(LayersPacket* other) { if (other != this) { layer_.Swap(&other->layer_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -3043,6 +3691,7 @@ const int MetaPacket::kComposedByHwcFieldNumber; MetaPacket::MetaPacket() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.MetaPacket) } void MetaPacket::InitAsDefaultInstance() { @@ -3052,6 +3701,7 @@ MetaPacket::MetaPacket(const MetaPacket& from) : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.MetaPacket) } void MetaPacket::SharedCtor() { @@ -3061,11 +3711,16 @@ void MetaPacket::SharedCtor() { } MetaPacket::~MetaPacket() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.MetaPacket) SharedDtor(); } void MetaPacket::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -3075,7 +3730,12 @@ void MetaPacket::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const MetaPacket& MetaPacket::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } MetaPacket* MetaPacket::default_instance_ = NULL; @@ -3085,67 +3745,86 @@ MetaPacket* MetaPacket::New() const { } void MetaPacket::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - composedbyhwc_ = false; - } + composedbyhwc_ = false; ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool MetaPacket::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.MetaPacket) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // optional bool composedByHwc = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &composedbyhwc_))); set_has_composedbyhwc(); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.MetaPacket) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.MetaPacket) + return false; #undef DO_ } void MetaPacket::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.MetaPacket) // optional bool composedByHwc = 1; if (has_composedbyhwc()) { ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->composedbyhwc(), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.MetaPacket) } int MetaPacket::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // optional bool composedByHwc = 1; if (has_composedbyhwc()) { total_size += 1 + 1; } - + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -3164,6 +3843,7 @@ void MetaPacket::MergeFrom(const MetaPacket& from) { set_composedbyhwc(from.composedbyhwc()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void MetaPacket::CopyFrom(const MetaPacket& from) { @@ -3173,7 +3853,7 @@ void MetaPacket::CopyFrom(const MetaPacket& from) { } bool MetaPacket::IsInitialized() const { - + return true; } @@ -3181,6 +3861,7 @@ void MetaPacket::Swap(MetaPacket* other) { if (other != this) { std::swap(composedbyhwc_, other->composedbyhwc_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -3190,6 +3871,674 @@ void MetaPacket::Swap(MetaPacket* other) { } +// =================================================================== + +#ifndef _MSC_VER +const int DrawPacket_Rect::kXFieldNumber; +const int DrawPacket_Rect::kYFieldNumber; +const int DrawPacket_Rect::kWFieldNumber; +const int DrawPacket_Rect::kHFieldNumber; +#endif // !_MSC_VER + +DrawPacket_Rect::DrawPacket_Rect() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.DrawPacket.Rect) +} + +void DrawPacket_Rect::InitAsDefaultInstance() { +} + +DrawPacket_Rect::DrawPacket_Rect(const DrawPacket_Rect& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.DrawPacket.Rect) +} + +void DrawPacket_Rect::SharedCtor() { + _cached_size_ = 0; + x_ = 0; + y_ = 0; + w_ = 0; + h_ = 0; + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +DrawPacket_Rect::~DrawPacket_Rect() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.DrawPacket.Rect) + SharedDtor(); +} + +void DrawPacket_Rect::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void DrawPacket_Rect::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const DrawPacket_Rect& DrawPacket_Rect::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; +} + +DrawPacket_Rect* DrawPacket_Rect::default_instance_ = NULL; + +DrawPacket_Rect* DrawPacket_Rect::New() const { + return new DrawPacket_Rect; +} + +void DrawPacket_Rect::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(x_, h_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool DrawPacket_Rect::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.DrawPacket.Rect) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required float x = 1; + case 1: { + if (tag == 13) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &x_))); + set_has_x(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(21)) goto parse_y; + break; + } + + // required float y = 2; + case 2: { + if (tag == 21) { + parse_y: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &y_))); + set_has_y(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(29)) goto parse_w; + break; + } + + // required float w = 3; + case 3: { + if (tag == 29) { + parse_w: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &w_))); + set_has_w(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(37)) goto parse_h; + break; + } + + // required float h = 4; + case 4: { + if (tag == 37) { + parse_h: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &h_))); + set_has_h(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.DrawPacket.Rect) + return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.DrawPacket.Rect) + return false; +#undef DO_ +} + +void DrawPacket_Rect::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.DrawPacket.Rect) + // required float x = 1; + if (has_x()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->x(), output); + } + + // required float y = 2; + if (has_y()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->y(), output); + } + + // required float w = 3; + if (has_w()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(3, this->w(), output); + } + + // required float h = 4; + if (has_h()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(4, this->h(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.DrawPacket.Rect) +} + +int DrawPacket_Rect::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required float x = 1; + if (has_x()) { + total_size += 1 + 4; + } + + // required float y = 2; + if (has_y()) { + total_size += 1 + 4; + } + + // required float w = 3; + if (has_w()) { + total_size += 1 + 4; + } + + // required float h = 4; + if (has_h()) { + total_size += 1 + 4; + } + + } + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void DrawPacket_Rect::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void DrawPacket_Rect::MergeFrom(const DrawPacket_Rect& from) { + GOOGLE_CHECK_NE(&from, this); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_x()) { + set_x(from.x()); + } + if (from.has_y()) { + set_y(from.y()); + } + if (from.has_w()) { + set_w(from.w()); + } + if (from.has_h()) { + set_h(from.h()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void DrawPacket_Rect::CopyFrom(const DrawPacket_Rect& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DrawPacket_Rect::IsInitialized() const { + if ((_has_bits_[0] & 0x0000000f) != 0x0000000f) return false; + + return true; +} + +void DrawPacket_Rect::Swap(DrawPacket_Rect* other) { + if (other != this) { + std::swap(x_, other->x_); + std::swap(y_, other->y_); + std::swap(w_, other->w_); + std::swap(h_, other->h_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string DrawPacket_Rect::GetTypeName() const { + return "mozilla.layers.layerscope.DrawPacket.Rect"; +} + + +// ------------------------------------------------------------------- + +#ifndef _MSC_VER +const int DrawPacket::kOffsetXFieldNumber; +const int DrawPacket::kOffsetYFieldNumber; +const int DrawPacket::kMvMatrixFieldNumber; +const int DrawPacket::kTotalRectsFieldNumber; +const int DrawPacket::kLayerRectFieldNumber; +const int DrawPacket::kLayerrefFieldNumber; +#endif // !_MSC_VER + +DrawPacket::DrawPacket() + : ::google::protobuf::MessageLite() { + SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.DrawPacket) +} + +void DrawPacket::InitAsDefaultInstance() { +} + +DrawPacket::DrawPacket(const DrawPacket& from) + : ::google::protobuf::MessageLite() { + SharedCtor(); + MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.DrawPacket) +} + +void DrawPacket::SharedCtor() { + _cached_size_ = 0; + offsetx_ = 0; + offsety_ = 0; + totalrects_ = 0u; + layerref_ = GOOGLE_ULONGLONG(0); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); +} + +DrawPacket::~DrawPacket() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.DrawPacket) + SharedDtor(); +} + +void DrawPacket::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else + if (this != default_instance_) { + #endif + } +} + +void DrawPacket::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const DrawPacket& DrawPacket::default_instance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; +} + +DrawPacket* DrawPacket::default_instance_ = NULL; + +DrawPacket* DrawPacket::New() const { + return new DrawPacket; +} + +void DrawPacket::Clear() { +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(offsetx_, offsety_); + ZR_(layerref_, totalrects_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + + mvmatrix_.Clear(); + layerrect_.Clear(); + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); +} + +bool DrawPacket::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.DrawPacket) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // required float offsetX = 1; + case 1: { + if (tag == 13) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &offsetx_))); + set_has_offsetx(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(21)) goto parse_offsetY; + break; + } + + // required float offsetY = 2; + case 2: { + if (tag == 21) { + parse_offsetY: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, &offsety_))); + set_has_offsety(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(29)) goto parse_mvMatrix; + break; + } + + // repeated float mvMatrix = 3; + case 3: { + if (tag == 29) { + parse_mvMatrix: + DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + 1, 29, input, this->mutable_mvmatrix()))); + } else if (tag == 26) { + DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline< + float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>( + input, this->mutable_mvmatrix()))); + } else { + goto handle_unusual; + } + if (input->ExpectTag(29)) goto parse_mvMatrix; + if (input->ExpectTag(32)) goto parse_totalRects; + break; + } + + // required uint32 totalRects = 4; + case 4: { + if (tag == 32) { + parse_totalRects: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint32, ::google::protobuf::internal::WireFormatLite::TYPE_UINT32>( + input, &totalrects_))); + set_has_totalrects(); + } else { + goto handle_unusual; + } + if (input->ExpectTag(42)) goto parse_layerRect; + break; + } + + // repeated .mozilla.layers.layerscope.DrawPacket.Rect layerRect = 5; + case 5: { + if (tag == 42) { + parse_layerRect: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_layerrect())); + } else { + goto handle_unusual; + } + if (input->ExpectTag(42)) goto parse_layerRect; + if (input->ExpectTag(48)) goto parse_layerref; + break; + } + + // required uint64 layerref = 6; + case 6: { + if (tag == 48) { + parse_layerref: + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &layerref_))); + set_has_layerref(); + } else { + goto handle_unusual; + } + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.DrawPacket) + return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.DrawPacket) + return false; +#undef DO_ +} + +void DrawPacket::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.DrawPacket) + // required float offsetX = 1; + if (has_offsetx()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->offsetx(), output); + } + + // required float offsetY = 2; + if (has_offsety()) { + ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->offsety(), output); + } + + // repeated float mvMatrix = 3; + for (int i = 0; i < this->mvmatrix_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteFloat( + 3, this->mvmatrix(i), output); + } + + // required uint32 totalRects = 4; + if (has_totalrects()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt32(4, this->totalrects(), output); + } + + // repeated .mozilla.layers.layerscope.DrawPacket.Rect layerRect = 5; + for (int i = 0; i < this->layerrect_size(); i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 5, this->layerrect(i), output); + } + + // required uint64 layerref = 6; + if (has_layerref()) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(6, this->layerref(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.DrawPacket) +} + +int DrawPacket::ByteSize() const { + int total_size = 0; + + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + // required float offsetX = 1; + if (has_offsetx()) { + total_size += 1 + 4; + } + + // required float offsetY = 2; + if (has_offsety()) { + total_size += 1 + 4; + } + + // required uint32 totalRects = 4; + if (has_totalrects()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt32Size( + this->totalrects()); + } + + // required uint64 layerref = 6; + if (has_layerref()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->layerref()); + } + + } + // repeated float mvMatrix = 3; + { + int data_size = 0; + data_size = 4 * this->mvmatrix_size(); + total_size += 1 * this->mvmatrix_size() + data_size; + } + + // repeated .mozilla.layers.layerscope.DrawPacket.Rect layerRect = 5; + total_size += 1 * this->layerrect_size(); + for (int i = 0; i < this->layerrect_size(); i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->layerrect(i)); + } + + total_size += unknown_fields().size(); + + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = total_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void DrawPacket::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void DrawPacket::MergeFrom(const DrawPacket& from) { + GOOGLE_CHECK_NE(&from, this); + mvmatrix_.MergeFrom(from.mvmatrix_); + layerrect_.MergeFrom(from.layerrect_); + if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (from.has_offsetx()) { + set_offsetx(from.offsetx()); + } + if (from.has_offsety()) { + set_offsety(from.offsety()); + } + if (from.has_totalrects()) { + set_totalrects(from.totalrects()); + } + if (from.has_layerref()) { + set_layerref(from.layerref()); + } + } + mutable_unknown_fields()->append(from.unknown_fields()); +} + +void DrawPacket::CopyFrom(const DrawPacket& from) { + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool DrawPacket::IsInitialized() const { + if ((_has_bits_[0] & 0x0000002b) != 0x0000002b) return false; + + if (!::google::protobuf::internal::AllAreInitialized(this->layerrect())) return false; + return true; +} + +void DrawPacket::Swap(DrawPacket* other) { + if (other != this) { + std::swap(offsetx_, other->offsetx_); + std::swap(offsety_, other->offsety_); + mvmatrix_.Swap(&other->mvmatrix_); + std::swap(totalrects_, other->totalrects_); + layerrect_.Swap(&other->layerrect_); + std::swap(layerref_, other->layerref_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); + std::swap(_cached_size_, other->_cached_size_); + } +} + +::std::string DrawPacket::GetTypeName() const { + return "mozilla.layers.layerscope.DrawPacket"; +} + + // =================================================================== bool Packet_DataType_IsValid(int value) { @@ -3200,6 +4549,7 @@ bool Packet_DataType_IsValid(int value) { case 4: case 5: case 6: + case 7: return true; default: return false; @@ -3213,6 +4563,7 @@ const Packet_DataType Packet::COLOR; const Packet_DataType Packet::TEXTURE; const Packet_DataType Packet::LAYERS; const Packet_DataType Packet::META; +const Packet_DataType Packet::DRAW; const Packet_DataType Packet::DataType_MIN; const Packet_DataType Packet::DataType_MAX; const int Packet::DataType_ARRAYSIZE; @@ -3224,25 +4575,59 @@ const int Packet::kColorFieldNumber; const int Packet::kTextureFieldNumber; const int Packet::kLayersFieldNumber; const int Packet::kMetaFieldNumber; +const int Packet::kDrawFieldNumber; #endif // !_MSC_VER Packet::Packet() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.Packet) } void Packet::InitAsDefaultInstance() { +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + frame_ = const_cast< ::mozilla::layers::layerscope::FramePacket*>( + ::mozilla::layers::layerscope::FramePacket::internal_default_instance()); +#else frame_ = const_cast< ::mozilla::layers::layerscope::FramePacket*>(&::mozilla::layers::layerscope::FramePacket::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + color_ = const_cast< ::mozilla::layers::layerscope::ColorPacket*>( + ::mozilla::layers::layerscope::ColorPacket::internal_default_instance()); +#else color_ = const_cast< ::mozilla::layers::layerscope::ColorPacket*>(&::mozilla::layers::layerscope::ColorPacket::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + texture_ = const_cast< ::mozilla::layers::layerscope::TexturePacket*>( + ::mozilla::layers::layerscope::TexturePacket::internal_default_instance()); +#else texture_ = const_cast< ::mozilla::layers::layerscope::TexturePacket*>(&::mozilla::layers::layerscope::TexturePacket::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + layers_ = const_cast< ::mozilla::layers::layerscope::LayersPacket*>( + ::mozilla::layers::layerscope::LayersPacket::internal_default_instance()); +#else layers_ = const_cast< ::mozilla::layers::layerscope::LayersPacket*>(&::mozilla::layers::layerscope::LayersPacket::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + meta_ = const_cast< ::mozilla::layers::layerscope::MetaPacket*>( + ::mozilla::layers::layerscope::MetaPacket::internal_default_instance()); +#else meta_ = const_cast< ::mozilla::layers::layerscope::MetaPacket*>(&::mozilla::layers::layerscope::MetaPacket::default_instance()); +#endif +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + draw_ = const_cast< ::mozilla::layers::layerscope::DrawPacket*>( + ::mozilla::layers::layerscope::DrawPacket::internal_default_instance()); +#else + draw_ = const_cast< ::mozilla::layers::layerscope::DrawPacket*>(&::mozilla::layers::layerscope::DrawPacket::default_instance()); +#endif } Packet::Packet(const Packet& from) : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.Packet) } void Packet::SharedCtor() { @@ -3253,20 +4638,27 @@ void Packet::SharedCtor() { texture_ = NULL; layers_ = NULL; meta_ = NULL; + draw_ = NULL; ::memset(_has_bits_, 0, sizeof(_has_bits_)); } Packet::~Packet() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.Packet) SharedDtor(); } void Packet::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif delete frame_; delete color_; delete texture_; delete layers_; delete meta_; + delete draw_; } } @@ -3276,7 +4668,12 @@ void Packet::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const Packet& Packet::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } Packet* Packet::default_instance_ = NULL; @@ -3286,7 +4683,7 @@ Packet* Packet::New() const { } void Packet::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { + if (_has_bits_[0 / 32] & 127) { type_ = 1; if (has_frame()) { if (frame_ != NULL) frame_->::mozilla::layers::layerscope::FramePacket::Clear(); @@ -3303,205 +4700,253 @@ void Packet::Clear() { if (has_meta()) { if (meta_ != NULL) meta_->::mozilla::layers::layerscope::MetaPacket::Clear(); } + if (has_draw()) { + if (draw_ != NULL) draw_->::mozilla::layers::layerscope::DrawPacket::Clear(); + } } ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool Packet::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.Packet) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // required .mozilla.layers.layerscope.Packet.DataType type = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); if (::mozilla::layers::layerscope::Packet_DataType_IsValid(value)) { set_type(static_cast< ::mozilla::layers::layerscope::Packet_DataType >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); } } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(18)) goto parse_frame; break; } - + // optional .mozilla.layers.layerscope.FramePacket frame = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 18) { parse_frame: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_frame())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(26)) goto parse_color; break; } - + // optional .mozilla.layers.layerscope.ColorPacket color = 3; case 3: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 26) { parse_color: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_color())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(34)) goto parse_texture; break; } - + // optional .mozilla.layers.layerscope.TexturePacket texture = 4; case 4: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 34) { parse_texture: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_texture())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(42)) goto parse_layers; break; } - + // optional .mozilla.layers.layerscope.LayersPacket layers = 5; case 5: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 42) { parse_layers: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_layers())); } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(50)) goto parse_meta; break; } - + // optional .mozilla.layers.layerscope.MetaPacket meta = 6; case 6: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) { + if (tag == 50) { parse_meta: DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, mutable_meta())); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectTag(58)) goto parse_draw; break; } - - default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + + // optional .mozilla.layers.layerscope.DrawPacket draw = 7; + case 7: { + if (tag == 58) { + parse_draw: + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, mutable_draw())); + } else { + goto handle_unusual; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + if (input->ExpectAtEnd()) goto success; + break; + } + + default: { + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.Packet) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.Packet) + return false; #undef DO_ } void Packet::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.Packet) // required .mozilla.layers.layerscope.Packet.DataType type = 1; if (has_type()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 1, this->type(), output); } - + // optional .mozilla.layers.layerscope.FramePacket frame = 2; if (has_frame()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 2, this->frame(), output); } - + // optional .mozilla.layers.layerscope.ColorPacket color = 3; if (has_color()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 3, this->color(), output); } - + // optional .mozilla.layers.layerscope.TexturePacket texture = 4; if (has_texture()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 4, this->texture(), output); } - + // optional .mozilla.layers.layerscope.LayersPacket layers = 5; if (has_layers()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 5, this->layers(), output); } - + // optional .mozilla.layers.layerscope.MetaPacket meta = 6; if (has_meta()) { ::google::protobuf::internal::WireFormatLite::WriteMessage( 6, this->meta(), output); } - + + // optional .mozilla.layers.layerscope.DrawPacket draw = 7; + if (has_draw()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 7, this->draw(), output); + } + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.Packet) } int Packet::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // required .mozilla.layers.layerscope.Packet.DataType type = 1; if (has_type()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); } - + // optional .mozilla.layers.layerscope.FramePacket frame = 2; if (has_frame()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->frame()); } - + // optional .mozilla.layers.layerscope.ColorPacket color = 3; if (has_color()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->color()); } - + // optional .mozilla.layers.layerscope.TexturePacket texture = 4; if (has_texture()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->texture()); } - + // optional .mozilla.layers.layerscope.LayersPacket layers = 5; if (has_layers()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->layers()); } - + // optional .mozilla.layers.layerscope.MetaPacket meta = 6; if (has_meta()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( this->meta()); } - + + // optional .mozilla.layers.layerscope.DrawPacket draw = 7; + if (has_draw()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->draw()); + } + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -3534,7 +4979,11 @@ void Packet::MergeFrom(const Packet& from) { if (from.has_meta()) { mutable_meta()->::mozilla::layers::layerscope::MetaPacket::MergeFrom(from.meta()); } + if (from.has_draw()) { + mutable_draw()->::mozilla::layers::layerscope::DrawPacket::MergeFrom(from.draw()); + } } + mutable_unknown_fields()->append(from.unknown_fields()); } void Packet::CopyFrom(const Packet& from) { @@ -3545,7 +4994,7 @@ void Packet::CopyFrom(const Packet& from) { bool Packet::IsInitialized() const { if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; - + if (has_color()) { if (!this->color().IsInitialized()) return false; } @@ -3555,6 +5004,9 @@ bool Packet::IsInitialized() const { if (has_layers()) { if (!this->layers().IsInitialized()) return false; } + if (has_draw()) { + if (!this->draw().IsInitialized()) return false; + } return true; } @@ -3566,7 +5018,9 @@ void Packet::Swap(Packet* other) { std::swap(texture_, other->texture_); std::swap(layers_, other->layers_); std::swap(meta_, other->meta_); + std::swap(draw_, other->draw_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } @@ -3605,6 +5059,7 @@ const int CommandPacket::kValueFieldNumber; CommandPacket::CommandPacket() : ::google::protobuf::MessageLite() { SharedCtor(); + // @@protoc_insertion_point(constructor:mozilla.layers.layerscope.CommandPacket) } void CommandPacket::InitAsDefaultInstance() { @@ -3614,6 +5069,7 @@ CommandPacket::CommandPacket(const CommandPacket& from) : ::google::protobuf::MessageLite() { SharedCtor(); MergeFrom(from); + // @@protoc_insertion_point(copy_constructor:mozilla.layers.layerscope.CommandPacket) } void CommandPacket::SharedCtor() { @@ -3624,11 +5080,16 @@ void CommandPacket::SharedCtor() { } CommandPacket::~CommandPacket() { + // @@protoc_insertion_point(destructor:mozilla.layers.layerscope.CommandPacket) SharedDtor(); } void CommandPacket::SharedDtor() { + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + if (this != &default_instance()) { + #else if (this != default_instance_) { + #endif } } @@ -3638,7 +5099,12 @@ void CommandPacket::SetCachedSize(int size) const { GOOGLE_SAFE_CONCURRENT_WRITES_END(); } const CommandPacket& CommandPacket::default_instance() { - if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); return *default_instance_; +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + protobuf_AddDesc_LayerScopePacket_2eproto(); +#else + if (default_instance_ == NULL) protobuf_AddDesc_LayerScopePacket_2eproto(); +#endif + return *default_instance_; } CommandPacket* CommandPacket::default_instance_ = NULL; @@ -3648,99 +5114,133 @@ CommandPacket* CommandPacket::New() const { } void CommandPacket::Clear() { - if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { - type_ = 0; - value_ = false; - } +#define OFFSET_OF_FIELD_(f) (reinterpret_cast( \ + &reinterpret_cast(16)->f) - \ + reinterpret_cast(16)) + +#define ZR_(first, last) do { \ + size_t f = OFFSET_OF_FIELD_(first); \ + size_t n = OFFSET_OF_FIELD_(last) - f + sizeof(last); \ + ::memset(&first, 0, n); \ + } while (0) + + ZR_(type_, value_); + +#undef OFFSET_OF_FIELD_ +#undef ZR_ + ::memset(_has_bits_, 0, sizeof(_has_bits_)); + mutable_unknown_fields()->clear(); } bool CommandPacket::MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input) { -#define DO_(EXPRESSION) if (!(EXPRESSION)) return false +#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure ::google::protobuf::uint32 tag; - while ((tag = input->ReadTag()) != 0) { + ::google::protobuf::io::StringOutputStream unknown_fields_string( + mutable_unknown_fields()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string); + // @@protoc_insertion_point(parse_start:mozilla.layers.layerscope.CommandPacket) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127); + tag = p.first; + if (!p.second) goto handle_unusual; switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { // required .mozilla.layers.layerscope.CommandPacket.CmdType type = 1; case 1: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 8) { int value; DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>( input, &value))); if (::mozilla::layers::layerscope::CommandPacket_CmdType_IsValid(value)) { set_type(static_cast< ::mozilla::layers::layerscope::CommandPacket_CmdType >(value)); + } else { + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); } } else { - goto handle_uninterpreted; + goto handle_unusual; } if (input->ExpectTag(16)) goto parse_value; break; } - + // optional bool value = 2; case 2: { - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == - ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) { + if (tag == 16) { parse_value: DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>( input, &value_))); set_has_value(); } else { - goto handle_uninterpreted; + goto handle_unusual; } - if (input->ExpectAtEnd()) return true; + if (input->ExpectAtEnd()) goto success; break; } - + default: { - handle_uninterpreted: - if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == + handle_unusual: + if (tag == 0 || + ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) == ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) { - return true; + goto success; } - DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag)); + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); break; } } } +success: + // @@protoc_insertion_point(parse_success:mozilla.layers.layerscope.CommandPacket) return true; +failure: + // @@protoc_insertion_point(parse_failure:mozilla.layers.layerscope.CommandPacket) + return false; #undef DO_ } void CommandPacket::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:mozilla.layers.layerscope.CommandPacket) // required .mozilla.layers.layerscope.CommandPacket.CmdType type = 1; if (has_type()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 1, this->type(), output); } - + // optional bool value = 2; if (has_value()) { ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->value(), output); } - + + output->WriteRaw(unknown_fields().data(), + unknown_fields().size()); + // @@protoc_insertion_point(serialize_end:mozilla.layers.layerscope.CommandPacket) } int CommandPacket::ByteSize() const { int total_size = 0; - + if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) { // required .mozilla.layers.layerscope.CommandPacket.CmdType type = 1; if (has_type()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::EnumSize(this->type()); } - + // optional bool value = 2; if (has_value()) { total_size += 1 + 1; } - + } + total_size += unknown_fields().size(); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); _cached_size_ = total_size; GOOGLE_SAFE_CONCURRENT_WRITES_END(); @@ -3762,6 +5262,7 @@ void CommandPacket::MergeFrom(const CommandPacket& from) { set_value(from.value()); } } + mutable_unknown_fields()->append(from.unknown_fields()); } void CommandPacket::CopyFrom(const CommandPacket& from) { @@ -3772,7 +5273,7 @@ void CommandPacket::CopyFrom(const CommandPacket& from) { bool CommandPacket::IsInitialized() const { if ((_has_bits_[0] & 0x00000001) != 0x00000001) return false; - + return true; } @@ -3781,6 +5282,7 @@ void CommandPacket::Swap(CommandPacket* other) { std::swap(type_, other->type_); std::swap(value_, other->value_); std::swap(_has_bits_[0], other->_has_bits_[0]); + _unknown_fields_.swap(other->_unknown_fields_); std::swap(_cached_size_, other->_cached_size_); } } diff --git a/gfx/layers/protobuf/LayerScopePacket.pb.h b/gfx/layers/protobuf/LayerScopePacket.pb.h index 4f49ba9a7b..9e27d8a44f 100644 --- a/gfx/layers/protobuf/LayerScopePacket.pb.h +++ b/gfx/layers/protobuf/LayerScopePacket.pb.h @@ -8,18 +8,19 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 2004000 +#if GOOGLE_PROTOBUF_VERSION < 2006000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 2004001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 2006001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. #endif #include +#include #include #include // @@protoc_insertion_point(includes) @@ -44,6 +45,8 @@ class LayersPacket_Layer_Region; class LayersPacket_Layer_Matrix; class LayersPacket_Layer_Shadow; class MetaPacket; +class DrawPacket; +class DrawPacket_Rect; class Packet; class CommandPacket; @@ -92,11 +95,12 @@ enum Packet_DataType { Packet_DataType_COLOR = 3, Packet_DataType_TEXTURE = 4, Packet_DataType_LAYERS = 5, - Packet_DataType_META = 6 + Packet_DataType_META = 6, + Packet_DataType_DRAW = 7 }; bool Packet_DataType_IsValid(int value); const Packet_DataType Packet_DataType_DataType_MIN = Packet_DataType_FRAMESTART; -const Packet_DataType Packet_DataType_DataType_MAX = Packet_DataType_META; +const Packet_DataType Packet_DataType_DataType_MAX = Packet_DataType_DRAW; const int Packet_DataType_DataType_ARRAYSIZE = Packet_DataType_DataType_MAX + 1; enum CommandPacket_CmdType { @@ -115,66 +119,88 @@ class FramePacket : public ::google::protobuf::MessageLite { public: FramePacket(); virtual ~FramePacket(); - + FramePacket(const FramePacket& from); - + inline FramePacket& operator=(const FramePacket& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const FramePacket& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const FramePacket* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(FramePacket* other); - + // implements Message ---------------------------------------------- - + FramePacket* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const FramePacket& from); void MergeFrom(const FramePacket& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + // accessors ------------------------------------------------------- - + // optional uint64 value = 1; inline bool has_value() const; inline void clear_value(); static const int kValueFieldNumber = 1; inline ::google::protobuf::uint64 value() const; inline void set_value(::google::protobuf::uint64 value); - + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.FramePacket) private: inline void set_has_value(); inline void clear_has_value(); - - ::google::protobuf::uint64 value_; - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - + ::google::protobuf::uint64 value_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static FramePacket* default_instance_; }; @@ -184,73 +210,91 @@ class ColorPacket : public ::google::protobuf::MessageLite { public: ColorPacket(); virtual ~ColorPacket(); - + ColorPacket(const ColorPacket& from); - + inline ColorPacket& operator=(const ColorPacket& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const ColorPacket& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const ColorPacket* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(ColorPacket* other); - + // implements Message ---------------------------------------------- - + ColorPacket* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const ColorPacket& from); void MergeFrom(const ColorPacket& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + // accessors ------------------------------------------------------- - + // required uint64 layerref = 1; inline bool has_layerref() const; inline void clear_layerref(); static const int kLayerrefFieldNumber = 1; inline ::google::protobuf::uint64 layerref() const; inline void set_layerref(::google::protobuf::uint64 value); - + // optional uint32 width = 2; inline bool has_width() const; inline void clear_width(); static const int kWidthFieldNumber = 2; inline ::google::protobuf::uint32 width() const; inline void set_width(::google::protobuf::uint32 value); - + // optional uint32 height = 3; inline bool has_height() const; inline void clear_height(); static const int kHeightFieldNumber = 3; inline ::google::protobuf::uint32 height() const; inline void set_height(::google::protobuf::uint32 value); - + // optional uint32 color = 4; inline bool has_color() const; inline void clear_color(); static const int kColorFieldNumber = 4; inline ::google::protobuf::uint32 color() const; inline void set_color(::google::protobuf::uint32 value); - + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.ColorPacket) private: inline void set_has_layerref(); @@ -261,19 +305,23 @@ class ColorPacket : public ::google::protobuf::MessageLite { inline void clear_has_height(); inline void set_has_color(); inline void clear_has_color(); - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; ::google::protobuf::uint64 layerref_; ::google::protobuf::uint32 width_; ::google::protobuf::uint32 height_; ::google::protobuf::uint32 color_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; - + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static ColorPacket* default_instance_; }; @@ -283,101 +331,119 @@ class TexturePacket : public ::google::protobuf::MessageLite { public: TexturePacket(); virtual ~TexturePacket(); - + TexturePacket(const TexturePacket& from); - + inline TexturePacket& operator=(const TexturePacket& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const TexturePacket& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const TexturePacket* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(TexturePacket* other); - + // implements Message ---------------------------------------------- - + TexturePacket* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const TexturePacket& from); void MergeFrom(const TexturePacket& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + // accessors ------------------------------------------------------- - + // required uint64 layerref = 1; inline bool has_layerref() const; inline void clear_layerref(); static const int kLayerrefFieldNumber = 1; inline ::google::protobuf::uint64 layerref() const; inline void set_layerref(::google::protobuf::uint64 value); - + // optional uint32 width = 2; inline bool has_width() const; inline void clear_width(); static const int kWidthFieldNumber = 2; inline ::google::protobuf::uint32 width() const; inline void set_width(::google::protobuf::uint32 value); - + // optional uint32 height = 3; inline bool has_height() const; inline void clear_height(); static const int kHeightFieldNumber = 3; inline ::google::protobuf::uint32 height() const; inline void set_height(::google::protobuf::uint32 value); - + // optional uint32 stride = 4; inline bool has_stride() const; inline void clear_stride(); static const int kStrideFieldNumber = 4; inline ::google::protobuf::uint32 stride() const; inline void set_stride(::google::protobuf::uint32 value); - + // optional uint32 name = 5; inline bool has_name() const; inline void clear_name(); static const int kNameFieldNumber = 5; inline ::google::protobuf::uint32 name() const; inline void set_name(::google::protobuf::uint32 value); - + // optional uint32 target = 6; inline bool has_target() const; inline void clear_target(); static const int kTargetFieldNumber = 6; inline ::google::protobuf::uint32 target() const; inline void set_target(::google::protobuf::uint32 value); - + // optional uint32 dataformat = 7; inline bool has_dataformat() const; inline void clear_dataformat(); static const int kDataformatFieldNumber = 7; inline ::google::protobuf::uint32 dataformat() const; inline void set_dataformat(::google::protobuf::uint32 value); - + // optional uint64 glcontext = 8; inline bool has_glcontext() const; inline void clear_glcontext(); static const int kGlcontextFieldNumber = 8; inline ::google::protobuf::uint64 glcontext() const; inline void set_glcontext(::google::protobuf::uint64 value); - + // optional bytes data = 9; inline bool has_data() const; inline void clear_data(); @@ -388,7 +454,8 @@ class TexturePacket : public ::google::protobuf::MessageLite { inline void set_data(const void* value, size_t size); inline ::std::string* mutable_data(); inline ::std::string* release_data(); - + inline void set_allocated_data(::std::string* data); + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.TexturePacket) private: inline void set_has_layerref(); @@ -409,7 +476,11 @@ class TexturePacket : public ::google::protobuf::MessageLite { inline void clear_has_glcontext(); inline void set_has_data(); inline void clear_has_data(); - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; ::google::protobuf::uint64 layerref_; ::google::protobuf::uint32 width_; ::google::protobuf::uint32 height_; @@ -419,14 +490,14 @@ class TexturePacket : public ::google::protobuf::MessageLite { ::google::protobuf::uint32 dataformat_; ::google::protobuf::uint64 glcontext_; ::std::string* data_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(9 + 31) / 32]; - + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static TexturePacket* default_instance_; }; @@ -436,76 +507,98 @@ class LayersPacket_Layer_Size : public ::google::protobuf::MessageLite { public: LayersPacket_Layer_Size(); virtual ~LayersPacket_Layer_Size(); - + LayersPacket_Layer_Size(const LayersPacket_Layer_Size& from); - + inline LayersPacket_Layer_Size& operator=(const LayersPacket_Layer_Size& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const LayersPacket_Layer_Size& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const LayersPacket_Layer_Size* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(LayersPacket_Layer_Size* other); - + // implements Message ---------------------------------------------- - + LayersPacket_Layer_Size* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const LayersPacket_Layer_Size& from); void MergeFrom(const LayersPacket_Layer_Size& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + // accessors ------------------------------------------------------- - + // optional int32 w = 1; inline bool has_w() const; inline void clear_w(); static const int kWFieldNumber = 1; inline ::google::protobuf::int32 w() const; inline void set_w(::google::protobuf::int32 value); - + // optional int32 h = 2; inline bool has_h() const; inline void clear_h(); static const int kHFieldNumber = 2; inline ::google::protobuf::int32 h() const; inline void set_h(::google::protobuf::int32 value); - + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Size) private: inline void set_has_w(); inline void clear_has_w(); inline void set_has_h(); inline void clear_has_h(); - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; ::google::protobuf::int32 w_; ::google::protobuf::int32 h_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static LayersPacket_Layer_Size* default_instance_; }; @@ -515,73 +608,91 @@ class LayersPacket_Layer_Rect : public ::google::protobuf::MessageLite { public: LayersPacket_Layer_Rect(); virtual ~LayersPacket_Layer_Rect(); - + LayersPacket_Layer_Rect(const LayersPacket_Layer_Rect& from); - + inline LayersPacket_Layer_Rect& operator=(const LayersPacket_Layer_Rect& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const LayersPacket_Layer_Rect& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const LayersPacket_Layer_Rect* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(LayersPacket_Layer_Rect* other); - + // implements Message ---------------------------------------------- - + LayersPacket_Layer_Rect* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const LayersPacket_Layer_Rect& from); void MergeFrom(const LayersPacket_Layer_Rect& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + // accessors ------------------------------------------------------- - + // optional int32 x = 1; inline bool has_x() const; inline void clear_x(); static const int kXFieldNumber = 1; inline ::google::protobuf::int32 x() const; inline void set_x(::google::protobuf::int32 value); - + // optional int32 y = 2; inline bool has_y() const; inline void clear_y(); static const int kYFieldNumber = 2; inline ::google::protobuf::int32 y() const; inline void set_y(::google::protobuf::int32 value); - + // optional int32 w = 3; inline bool has_w() const; inline void clear_w(); static const int kWFieldNumber = 3; inline ::google::protobuf::int32 w() const; inline void set_w(::google::protobuf::int32 value); - + // optional int32 h = 4; inline bool has_h() const; inline void clear_h(); static const int kHFieldNumber = 4; inline ::google::protobuf::int32 h() const; inline void set_h(::google::protobuf::int32 value); - + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Rect) private: inline void set_has_x(); @@ -592,19 +703,23 @@ class LayersPacket_Layer_Rect : public ::google::protobuf::MessageLite { inline void clear_has_w(); inline void set_has_h(); inline void clear_has_h(); - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; ::google::protobuf::int32 x_; ::google::protobuf::int32 y_; ::google::protobuf::int32 w_; ::google::protobuf::int32 h_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(4 + 31) / 32]; - + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static LayersPacket_Layer_Rect* default_instance_; }; @@ -614,45 +729,63 @@ class LayersPacket_Layer_Region : public ::google::protobuf::MessageLite { public: LayersPacket_Layer_Region(); virtual ~LayersPacket_Layer_Region(); - + LayersPacket_Layer_Region(const LayersPacket_Layer_Region& from); - + inline LayersPacket_Layer_Region& operator=(const LayersPacket_Layer_Region& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const LayersPacket_Layer_Region& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const LayersPacket_Layer_Region* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(LayersPacket_Layer_Region* other); - + // implements Message ---------------------------------------------- - + LayersPacket_Layer_Region* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const LayersPacket_Layer_Region& from); void MergeFrom(const LayersPacket_Layer_Region& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + // accessors ------------------------------------------------------- - + // repeated .mozilla.layers.layerscope.LayersPacket.Layer.Rect r = 1; inline int r_size() const; inline void clear_r(); @@ -664,19 +797,23 @@ class LayersPacket_Layer_Region : public ::google::protobuf::MessageLite { r() const; inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect >* mutable_r(); - + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Region) private: - - ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect > r_; - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - + ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect > r_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static LayersPacket_Layer_Region* default_instance_; }; @@ -686,59 +823,77 @@ class LayersPacket_Layer_Matrix : public ::google::protobuf::MessageLite { public: LayersPacket_Layer_Matrix(); virtual ~LayersPacket_Layer_Matrix(); - + LayersPacket_Layer_Matrix(const LayersPacket_Layer_Matrix& from); - + inline LayersPacket_Layer_Matrix& operator=(const LayersPacket_Layer_Matrix& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const LayersPacket_Layer_Matrix& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const LayersPacket_Layer_Matrix* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(LayersPacket_Layer_Matrix* other); - + // implements Message ---------------------------------------------- - + LayersPacket_Layer_Matrix* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const LayersPacket_Layer_Matrix& from); void MergeFrom(const LayersPacket_Layer_Matrix& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + // accessors ------------------------------------------------------- - + // optional bool is2D = 1; inline bool has_is2d() const; inline void clear_is2d(); static const int kIs2DFieldNumber = 1; inline bool is2d() const; inline void set_is2d(bool value); - + // optional bool isId = 2; inline bool has_isid() const; inline void clear_isid(); static const int kIsIdFieldNumber = 2; inline bool isid() const; inline void set_isid(bool value); - + // repeated float m = 3; inline int m_size() const; inline void clear_m(); @@ -750,25 +905,29 @@ class LayersPacket_Layer_Matrix : public ::google::protobuf::MessageLite { m() const; inline ::google::protobuf::RepeatedField< float >* mutable_m(); - + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Matrix) private: inline void set_has_is2d(); inline void clear_has_is2d(); inline void set_has_isid(); inline void clear_has_isid(); - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; ::google::protobuf::RepeatedField< float > m_; bool is2d_; bool isid_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static LayersPacket_Layer_Matrix* default_instance_; }; @@ -778,45 +937,63 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite { public: LayersPacket_Layer_Shadow(); virtual ~LayersPacket_Layer_Shadow(); - + LayersPacket_Layer_Shadow(const LayersPacket_Layer_Shadow& from); - + inline LayersPacket_Layer_Shadow& operator=(const LayersPacket_Layer_Shadow& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const LayersPacket_Layer_Shadow& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const LayersPacket_Layer_Shadow* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(LayersPacket_Layer_Shadow* other); - + // implements Message ---------------------------------------------- - + LayersPacket_Layer_Shadow* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const LayersPacket_Layer_Shadow& from); void MergeFrom(const LayersPacket_Layer_Shadow& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + // accessors ------------------------------------------------------- - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 1; inline bool has_clip() const; inline void clear_clip(); @@ -824,7 +1001,8 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& clip() const; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* mutable_clip(); inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* release_clip(); - + inline void set_allocated_clip(::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip); + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2; inline bool has_transform() const; inline void clear_transform(); @@ -832,7 +1010,8 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix& transform() const; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* mutable_transform(); inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* release_transform(); - + inline void set_allocated_transform(::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform); + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3; inline bool has_vregion() const; inline void clear_vregion(); @@ -840,7 +1019,8 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& vregion() const; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_vregion(); inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_vregion(); - + inline void set_allocated_vregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion); + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer.Shadow) private: inline void set_has_clip(); @@ -849,18 +1029,22 @@ class LayersPacket_Layer_Shadow : public ::google::protobuf::MessageLite { inline void clear_has_transform(); inline void set_has_vregion(); inline void clear_has_vregion(); - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip_; ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform_; ::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(3 + 31) / 32]; - + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static LayersPacket_Layer_Shadow* default_instance_; }; @@ -870,49 +1054,67 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { public: LayersPacket_Layer(); virtual ~LayersPacket_Layer(); - + LayersPacket_Layer(const LayersPacket_Layer& from); - + inline LayersPacket_Layer& operator=(const LayersPacket_Layer& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const LayersPacket_Layer& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const LayersPacket_Layer* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(LayersPacket_Layer* other); - + // implements Message ---------------------------------------------- - + LayersPacket_Layer* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const LayersPacket_Layer& from); void MergeFrom(const LayersPacket_Layer& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + typedef LayersPacket_Layer_Size Size; typedef LayersPacket_Layer_Rect Rect; typedef LayersPacket_Layer_Region Region; typedef LayersPacket_Layer_Matrix Matrix; typedef LayersPacket_Layer_Shadow Shadow; - + typedef LayersPacket_Layer_LayerType LayerType; static const LayerType UnknownLayer = LayersPacket_Layer_LayerType_UnknownLayer; static const LayerType LayerManager = LayersPacket_Layer_LayerType_LayerManager; @@ -932,7 +1134,7 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { LayersPacket_Layer_LayerType_LayerType_MAX; static const int LayerType_ARRAYSIZE = LayersPacket_Layer_LayerType_LayerType_ARRAYSIZE; - + typedef LayersPacket_Layer_ScrollingDirect ScrollingDirect; static const ScrollingDirect VERTICAL = LayersPacket_Layer_ScrollingDirect_VERTICAL; static const ScrollingDirect HORIZONTAL = LayersPacket_Layer_ScrollingDirect_HORIZONTAL; @@ -945,7 +1147,7 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { LayersPacket_Layer_ScrollingDirect_ScrollingDirect_MAX; static const int ScrollingDirect_ARRAYSIZE = LayersPacket_Layer_ScrollingDirect_ScrollingDirect_ARRAYSIZE; - + typedef LayersPacket_Layer_Filter Filter; static const Filter FILTER_FAST = LayersPacket_Layer_Filter_FILTER_FAST; static const Filter FILTER_GOOD = LayersPacket_Layer_Filter_FILTER_GOOD; @@ -963,30 +1165,30 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { LayersPacket_Layer_Filter_Filter_MAX; static const int Filter_ARRAYSIZE = LayersPacket_Layer_Filter_Filter_ARRAYSIZE; - + // accessors ------------------------------------------------------- - + // required .mozilla.layers.layerscope.LayersPacket.Layer.LayerType type = 1; inline bool has_type() const; inline void clear_type(); static const int kTypeFieldNumber = 1; inline ::mozilla::layers::layerscope::LayersPacket_Layer_LayerType type() const; inline void set_type(::mozilla::layers::layerscope::LayersPacket_Layer_LayerType value); - + // required uint64 ptr = 2; inline bool has_ptr() const; inline void clear_ptr(); static const int kPtrFieldNumber = 2; inline ::google::protobuf::uint64 ptr() const; inline void set_ptr(::google::protobuf::uint64 value); - + // required uint64 parentPtr = 3; inline bool has_parentptr() const; inline void clear_parentptr(); static const int kParentPtrFieldNumber = 3; inline ::google::protobuf::uint64 parentptr() const; inline void set_parentptr(::google::protobuf::uint64 value); - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10; inline bool has_clip() const; inline void clear_clip(); @@ -994,7 +1196,8 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& clip() const; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* mutable_clip(); inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* release_clip(); - + inline void set_allocated_clip(::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip); + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11; inline bool has_transform() const; inline void clear_transform(); @@ -1002,7 +1205,8 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix& transform() const; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* mutable_transform(); inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* release_transform(); - + inline void set_allocated_transform(::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform); + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12; inline bool has_vregion() const; inline void clear_vregion(); @@ -1010,7 +1214,8 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& vregion() const; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_vregion(); inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_vregion(); - + inline void set_allocated_vregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion); + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13; inline bool has_shadow() const; inline void clear_shadow(); @@ -1018,49 +1223,95 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow& shadow() const; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* mutable_shadow(); inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* release_shadow(); - + inline void set_allocated_shadow(::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* shadow); + // optional float opacity = 14; inline bool has_opacity() const; inline void clear_opacity(); static const int kOpacityFieldNumber = 14; inline float opacity() const; inline void set_opacity(float value); - + // optional bool cOpaque = 15; inline bool has_copaque() const; inline void clear_copaque(); static const int kCOpaqueFieldNumber = 15; inline bool copaque() const; inline void set_copaque(bool value); - + // optional bool cAlpha = 16; inline bool has_calpha() const; inline void clear_calpha(); static const int kCAlphaFieldNumber = 16; inline bool calpha() const; inline void set_calpha(bool value); - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17; inline bool has_direct() const; inline void clear_direct(); static const int kDirectFieldNumber = 17; inline ::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect direct() const; inline void set_direct(::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect value); - + // optional uint64 barID = 18; inline bool has_barid() const; inline void clear_barid(); static const int kBarIDFieldNumber = 18; inline ::google::protobuf::uint64 barid() const; inline void set_barid(::google::protobuf::uint64 value); - + // optional uint64 mask = 19; inline bool has_mask() const; inline void clear_mask(); static const int kMaskFieldNumber = 19; inline ::google::protobuf::uint64 mask() const; inline void set_mask(::google::protobuf::uint64 value); - + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20; + inline bool has_hitregion() const; + inline void clear_hitregion(); + static const int kHitRegionFieldNumber = 20; + inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& hitregion() const; + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_hitregion(); + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_hitregion(); + inline void set_allocated_hitregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* hitregion); + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21; + inline bool has_dispatchregion() const; + inline void clear_dispatchregion(); + static const int kDispatchRegionFieldNumber = 21; + inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& dispatchregion() const; + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_dispatchregion(); + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_dispatchregion(); + inline void set_allocated_dispatchregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* dispatchregion); + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22; + inline bool has_noactionregion() const; + inline void clear_noactionregion(); + static const int kNoActionRegionFieldNumber = 22; + inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& noactionregion() const; + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_noactionregion(); + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_noactionregion(); + inline void set_allocated_noactionregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* noactionregion); + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23; + inline bool has_hpanregion() const; + inline void clear_hpanregion(); + static const int kHPanRegionFieldNumber = 23; + inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& hpanregion() const; + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_hpanregion(); + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_hpanregion(); + inline void set_allocated_hpanregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* hpanregion); + + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24; + inline bool has_vpanregion() const; + inline void clear_vpanregion(); + static const int kVPanRegionFieldNumber = 24; + inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& vpanregion() const; + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_vpanregion(); + inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_vpanregion(); + inline void set_allocated_vpanregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vpanregion); + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100; inline bool has_valid() const; inline void clear_valid(); @@ -1068,28 +1319,29 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& valid() const; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* mutable_valid(); inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* release_valid(); - + inline void set_allocated_valid(::mozilla::layers::layerscope::LayersPacket_Layer_Region* valid); + // optional uint32 color = 101; inline bool has_color() const; inline void clear_color(); static const int kColorFieldNumber = 101; inline ::google::protobuf::uint32 color() const; inline void set_color(::google::protobuf::uint32 value); - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102; inline bool has_filter() const; inline void clear_filter(); static const int kFilterFieldNumber = 102; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Filter filter() const; inline void set_filter(::mozilla::layers::layerscope::LayersPacket_Layer_Filter value); - + // optional uint64 refID = 103; inline bool has_refid() const; inline void clear_refid(); static const int kRefIDFieldNumber = 103; inline ::google::protobuf::uint64 refid() const; inline void set_refid(::google::protobuf::uint64 value); - + // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104; inline bool has_size() const; inline void clear_size(); @@ -1097,7 +1349,8 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Size& size() const; inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* mutable_size(); inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* release_size(); - + inline void set_allocated_size(::mozilla::layers::layerscope::LayersPacket_Layer_Size* size); + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket.Layer) private: inline void set_has_type(); @@ -1126,6 +1379,16 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { inline void clear_has_barid(); inline void set_has_mask(); inline void clear_has_mask(); + inline void set_has_hitregion(); + inline void clear_has_hitregion(); + inline void set_has_dispatchregion(); + inline void clear_has_dispatchregion(); + inline void set_has_noactionregion(); + inline void clear_has_noactionregion(); + inline void set_has_hpanregion(); + inline void clear_has_hpanregion(); + inline void set_has_vpanregion(); + inline void clear_has_vpanregion(); inline void set_has_valid(); inline void clear_has_valid(); inline void set_has_color(); @@ -1136,7 +1399,11 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { inline void clear_has_refid(); inline void set_has_size(); inline void clear_has_size(); - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; ::google::protobuf::uint64 ptr_; ::google::protobuf::uint64 parentptr_; ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip_; @@ -1150,19 +1417,24 @@ class LayersPacket_Layer : public ::google::protobuf::MessageLite { int direct_; ::google::protobuf::uint64 barid_; ::google::protobuf::uint64 mask_; + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* hitregion_; + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* dispatchregion_; + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* noactionregion_; + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* hpanregion_; + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* vpanregion_; ::mozilla::layers::layerscope::LayersPacket_Layer_Region* valid_; ::google::protobuf::uint32 color_; int filter_; ::google::protobuf::uint64 refid_; ::mozilla::layers::layerscope::LayersPacket_Layer_Size* size_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(18 + 31) / 32]; - + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static LayersPacket_Layer* default_instance_; }; @@ -1172,47 +1444,65 @@ class LayersPacket : public ::google::protobuf::MessageLite { public: LayersPacket(); virtual ~LayersPacket(); - + LayersPacket(const LayersPacket& from); - + inline LayersPacket& operator=(const LayersPacket& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const LayersPacket& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const LayersPacket* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(LayersPacket* other); - + // implements Message ---------------------------------------------- - + LayersPacket* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const LayersPacket& from); void MergeFrom(const LayersPacket& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + typedef LayersPacket_Layer Layer; - + // accessors ------------------------------------------------------- - + // repeated .mozilla.layers.layerscope.LayersPacket.Layer layer = 1; inline int layer_size() const; inline void clear_layer(); @@ -1224,19 +1514,23 @@ class LayersPacket : public ::google::protobuf::MessageLite { layer() const; inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer >* mutable_layer(); - + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.LayersPacket) private: - - ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer > layer_; - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - + ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer > layer_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static LayersPacket* default_instance_; }; @@ -1246,112 +1540,422 @@ class MetaPacket : public ::google::protobuf::MessageLite { public: MetaPacket(); virtual ~MetaPacket(); - + MetaPacket(const MetaPacket& from); - + inline MetaPacket& operator=(const MetaPacket& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const MetaPacket& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const MetaPacket* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(MetaPacket* other); - + // implements Message ---------------------------------------------- - + MetaPacket* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const MetaPacket& from); void MergeFrom(const MetaPacket& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + // accessors ------------------------------------------------------- - + // optional bool composedByHwc = 1; inline bool has_composedbyhwc() const; inline void clear_composedbyhwc(); static const int kComposedByHwcFieldNumber = 1; inline bool composedbyhwc() const; inline void set_composedbyhwc(bool value); - + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.MetaPacket) private: inline void set_has_composedbyhwc(); inline void clear_has_composedbyhwc(); - - bool composedbyhwc_; - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(1 + 31) / 32]; - + bool composedbyhwc_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static MetaPacket* default_instance_; }; // ------------------------------------------------------------------- +class DrawPacket_Rect : public ::google::protobuf::MessageLite { + public: + DrawPacket_Rect(); + virtual ~DrawPacket_Rect(); + + DrawPacket_Rect(const DrawPacket_Rect& from); + + inline DrawPacket_Rect& operator=(const DrawPacket_Rect& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const DrawPacket_Rect& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const DrawPacket_Rect* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(DrawPacket_Rect* other); + + // implements Message ---------------------------------------------- + + DrawPacket_Rect* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const DrawPacket_Rect& from); + void MergeFrom(const DrawPacket_Rect& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // required float x = 1; + inline bool has_x() const; + inline void clear_x(); + static const int kXFieldNumber = 1; + inline float x() const; + inline void set_x(float value); + + // required float y = 2; + inline bool has_y() const; + inline void clear_y(); + static const int kYFieldNumber = 2; + inline float y() const; + inline void set_y(float value); + + // required float w = 3; + inline bool has_w() const; + inline void clear_w(); + static const int kWFieldNumber = 3; + inline float w() const; + inline void set_w(float value); + + // required float h = 4; + inline bool has_h() const; + inline void clear_h(); + static const int kHFieldNumber = 4; + inline float h() const; + inline void set_h(float value); + + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.DrawPacket.Rect) + private: + inline void set_has_x(); + inline void clear_has_x(); + inline void set_has_y(); + inline void clear_has_y(); + inline void set_has_w(); + inline void clear_has_w(); + inline void set_has_h(); + inline void clear_has_h(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + float x_; + float y_; + float w_; + float h_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else + friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif + friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); + friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); + + void InitAsDefaultInstance(); + static DrawPacket_Rect* default_instance_; +}; +// ------------------------------------------------------------------- + +class DrawPacket : public ::google::protobuf::MessageLite { + public: + DrawPacket(); + virtual ~DrawPacket(); + + DrawPacket(const DrawPacket& from); + + inline DrawPacket& operator=(const DrawPacket& from) { + CopyFrom(from); + return *this; + } + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + + static const DrawPacket& default_instance(); + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const DrawPacket* internal_default_instance() { + return default_instance_; + } + #endif + + void Swap(DrawPacket* other); + + // implements Message ---------------------------------------------- + + DrawPacket* New() const; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); + void CopyFrom(const DrawPacket& from); + void MergeFrom(const DrawPacket& from); + void Clear(); + bool IsInitialized() const; + + int ByteSize() const; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input); + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); + int GetCachedSize() const { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + public: + ::std::string GetTypeName() const; + + // nested types ---------------------------------------------------- + + typedef DrawPacket_Rect Rect; + + // accessors ------------------------------------------------------- + + // required float offsetX = 1; + inline bool has_offsetx() const; + inline void clear_offsetx(); + static const int kOffsetXFieldNumber = 1; + inline float offsetx() const; + inline void set_offsetx(float value); + + // required float offsetY = 2; + inline bool has_offsety() const; + inline void clear_offsety(); + static const int kOffsetYFieldNumber = 2; + inline float offsety() const; + inline void set_offsety(float value); + + // repeated float mvMatrix = 3; + inline int mvmatrix_size() const; + inline void clear_mvmatrix(); + static const int kMvMatrixFieldNumber = 3; + inline float mvmatrix(int index) const; + inline void set_mvmatrix(int index, float value); + inline void add_mvmatrix(float value); + inline const ::google::protobuf::RepeatedField< float >& + mvmatrix() const; + inline ::google::protobuf::RepeatedField< float >* + mutable_mvmatrix(); + + // required uint32 totalRects = 4; + inline bool has_totalrects() const; + inline void clear_totalrects(); + static const int kTotalRectsFieldNumber = 4; + inline ::google::protobuf::uint32 totalrects() const; + inline void set_totalrects(::google::protobuf::uint32 value); + + // repeated .mozilla.layers.layerscope.DrawPacket.Rect layerRect = 5; + inline int layerrect_size() const; + inline void clear_layerrect(); + static const int kLayerRectFieldNumber = 5; + inline const ::mozilla::layers::layerscope::DrawPacket_Rect& layerrect(int index) const; + inline ::mozilla::layers::layerscope::DrawPacket_Rect* mutable_layerrect(int index); + inline ::mozilla::layers::layerscope::DrawPacket_Rect* add_layerrect(); + inline const ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::DrawPacket_Rect >& + layerrect() const; + inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::DrawPacket_Rect >* + mutable_layerrect(); + + // required uint64 layerref = 6; + inline bool has_layerref() const; + inline void clear_layerref(); + static const int kLayerrefFieldNumber = 6; + inline ::google::protobuf::uint64 layerref() const; + inline void set_layerref(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.DrawPacket) + private: + inline void set_has_offsetx(); + inline void clear_has_offsetx(); + inline void set_has_offsety(); + inline void clear_has_offsety(); + inline void set_has_totalrects(); + inline void clear_has_totalrects(); + inline void set_has_layerref(); + inline void clear_has_layerref(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; + float offsetx_; + float offsety_; + ::google::protobuf::RepeatedField< float > mvmatrix_; + ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::DrawPacket_Rect > layerrect_; + ::google::protobuf::uint64 layerref_; + ::google::protobuf::uint32 totalrects_; + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else + friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif + friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); + friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); + + void InitAsDefaultInstance(); + static DrawPacket* default_instance_; +}; +// ------------------------------------------------------------------- + class Packet : public ::google::protobuf::MessageLite { public: Packet(); virtual ~Packet(); - + Packet(const Packet& from); - + inline Packet& operator=(const Packet& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const Packet& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const Packet* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(Packet* other); - + // implements Message ---------------------------------------------- - + Packet* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const Packet& from); void MergeFrom(const Packet& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + typedef Packet_DataType DataType; static const DataType FRAMESTART = Packet_DataType_FRAMESTART; static const DataType FRAMEEND = Packet_DataType_FRAMEEND; @@ -1359,6 +1963,7 @@ class Packet : public ::google::protobuf::MessageLite { static const DataType TEXTURE = Packet_DataType_TEXTURE; static const DataType LAYERS = Packet_DataType_LAYERS; static const DataType META = Packet_DataType_META; + static const DataType DRAW = Packet_DataType_DRAW; static inline bool DataType_IsValid(int value) { return Packet_DataType_IsValid(value); } @@ -1368,16 +1973,16 @@ class Packet : public ::google::protobuf::MessageLite { Packet_DataType_DataType_MAX; static const int DataType_ARRAYSIZE = Packet_DataType_DataType_ARRAYSIZE; - + // accessors ------------------------------------------------------- - + // required .mozilla.layers.layerscope.Packet.DataType type = 1; inline bool has_type() const; inline void clear_type(); static const int kTypeFieldNumber = 1; inline ::mozilla::layers::layerscope::Packet_DataType type() const; inline void set_type(::mozilla::layers::layerscope::Packet_DataType value); - + // optional .mozilla.layers.layerscope.FramePacket frame = 2; inline bool has_frame() const; inline void clear_frame(); @@ -1385,7 +1990,8 @@ class Packet : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::FramePacket& frame() const; inline ::mozilla::layers::layerscope::FramePacket* mutable_frame(); inline ::mozilla::layers::layerscope::FramePacket* release_frame(); - + inline void set_allocated_frame(::mozilla::layers::layerscope::FramePacket* frame); + // optional .mozilla.layers.layerscope.ColorPacket color = 3; inline bool has_color() const; inline void clear_color(); @@ -1393,7 +1999,8 @@ class Packet : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::ColorPacket& color() const; inline ::mozilla::layers::layerscope::ColorPacket* mutable_color(); inline ::mozilla::layers::layerscope::ColorPacket* release_color(); - + inline void set_allocated_color(::mozilla::layers::layerscope::ColorPacket* color); + // optional .mozilla.layers.layerscope.TexturePacket texture = 4; inline bool has_texture() const; inline void clear_texture(); @@ -1401,7 +2008,8 @@ class Packet : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::TexturePacket& texture() const; inline ::mozilla::layers::layerscope::TexturePacket* mutable_texture(); inline ::mozilla::layers::layerscope::TexturePacket* release_texture(); - + inline void set_allocated_texture(::mozilla::layers::layerscope::TexturePacket* texture); + // optional .mozilla.layers.layerscope.LayersPacket layers = 5; inline bool has_layers() const; inline void clear_layers(); @@ -1409,7 +2017,8 @@ class Packet : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::LayersPacket& layers() const; inline ::mozilla::layers::layerscope::LayersPacket* mutable_layers(); inline ::mozilla::layers::layerscope::LayersPacket* release_layers(); - + inline void set_allocated_layers(::mozilla::layers::layerscope::LayersPacket* layers); + // optional .mozilla.layers.layerscope.MetaPacket meta = 6; inline bool has_meta() const; inline void clear_meta(); @@ -1417,7 +2026,17 @@ class Packet : public ::google::protobuf::MessageLite { inline const ::mozilla::layers::layerscope::MetaPacket& meta() const; inline ::mozilla::layers::layerscope::MetaPacket* mutable_meta(); inline ::mozilla::layers::layerscope::MetaPacket* release_meta(); - + inline void set_allocated_meta(::mozilla::layers::layerscope::MetaPacket* meta); + + // optional .mozilla.layers.layerscope.DrawPacket draw = 7; + inline bool has_draw() const; + inline void clear_draw(); + static const int kDrawFieldNumber = 7; + inline const ::mozilla::layers::layerscope::DrawPacket& draw() const; + inline ::mozilla::layers::layerscope::DrawPacket* mutable_draw(); + inline ::mozilla::layers::layerscope::DrawPacket* release_draw(); + inline void set_allocated_draw(::mozilla::layers::layerscope::DrawPacket* draw); + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.Packet) private: inline void set_has_type(); @@ -1432,21 +2051,28 @@ class Packet : public ::google::protobuf::MessageLite { inline void clear_has_layers(); inline void set_has_meta(); inline void clear_has_meta(); - + inline void set_has_draw(); + inline void clear_has_draw(); + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; ::mozilla::layers::layerscope::FramePacket* frame_; ::mozilla::layers::layerscope::ColorPacket* color_; ::mozilla::layers::layerscope::TexturePacket* texture_; ::mozilla::layers::layerscope::LayersPacket* layers_; ::mozilla::layers::layerscope::MetaPacket* meta_; + ::mozilla::layers::layerscope::DrawPacket* draw_; int type_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(6 + 31) / 32]; - + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static Packet* default_instance_; }; @@ -1456,43 +2082,61 @@ class CommandPacket : public ::google::protobuf::MessageLite { public: CommandPacket(); virtual ~CommandPacket(); - + CommandPacket(const CommandPacket& from); - + inline CommandPacket& operator=(const CommandPacket& from) { CopyFrom(from); return *this; } - + + inline const ::std::string& unknown_fields() const { + return _unknown_fields_; + } + + inline ::std::string* mutable_unknown_fields() { + return &_unknown_fields_; + } + static const CommandPacket& default_instance(); - + + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + // Returns the internal default instance pointer. This function can + // return NULL thus should not be used by the user. This is intended + // for Protobuf internal code. Please use default_instance() declared + // above instead. + static inline const CommandPacket* internal_default_instance() { + return default_instance_; + } + #endif + void Swap(CommandPacket* other); - + // implements Message ---------------------------------------------- - + CommandPacket* New() const; void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from); void CopyFrom(const CommandPacket& from); void MergeFrom(const CommandPacket& from); void Clear(); bool IsInitialized() const; - + int ByteSize() const; bool MergePartialFromCodedStream( ::google::protobuf::io::CodedInputStream* input); void SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const; + void DiscardUnknownFields(); int GetCachedSize() const { return _cached_size_; } private: void SharedCtor(); void SharedDtor(); void SetCachedSize(int size) const; public: - ::std::string GetTypeName() const; - + // nested types ---------------------------------------------------- - + typedef CommandPacket_CmdType CmdType; static const CmdType NO_OP = CommandPacket_CmdType_NO_OP; static const CmdType LAYERS_TREE = CommandPacket_CmdType_LAYERS_TREE; @@ -1506,40 +2150,44 @@ class CommandPacket : public ::google::protobuf::MessageLite { CommandPacket_CmdType_CmdType_MAX; static const int CmdType_ARRAYSIZE = CommandPacket_CmdType_CmdType_ARRAYSIZE; - + // accessors ------------------------------------------------------- - + // required .mozilla.layers.layerscope.CommandPacket.CmdType type = 1; inline bool has_type() const; inline void clear_type(); static const int kTypeFieldNumber = 1; inline ::mozilla::layers::layerscope::CommandPacket_CmdType type() const; inline void set_type(::mozilla::layers::layerscope::CommandPacket_CmdType value); - + // optional bool value = 2; inline bool has_value() const; inline void clear_value(); static const int kValueFieldNumber = 2; inline bool value() const; inline void set_value(bool value); - + // @@protoc_insertion_point(class_scope:mozilla.layers.layerscope.CommandPacket) private: inline void set_has_type(); inline void clear_has_type(); inline void set_has_value(); inline void clear_has_value(); - + + ::std::string _unknown_fields_; + + ::google::protobuf::uint32 _has_bits_[1]; + mutable int _cached_size_; int type_; bool value_; - - mutable int _cached_size_; - ::google::protobuf::uint32 _has_bits_[(2 + 31) / 32]; - + #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + friend void protobuf_AddDesc_LayerScopePacket_2eproto_impl(); + #else friend void protobuf_AddDesc_LayerScopePacket_2eproto(); + #endif friend void protobuf_AssignDesc_LayerScopePacket_2eproto(); friend void protobuf_ShutdownFile_LayerScopePacket_2eproto(); - + void InitAsDefaultInstance(); static CommandPacket* default_instance_; }; @@ -1565,11 +2213,13 @@ inline void FramePacket::clear_value() { clear_has_value(); } inline ::google::protobuf::uint64 FramePacket::value() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.FramePacket.value) return value_; } inline void FramePacket::set_value(::google::protobuf::uint64 value) { set_has_value(); value_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.FramePacket.value) } // ------------------------------------------------------------------- @@ -1591,11 +2241,13 @@ inline void ColorPacket::clear_layerref() { clear_has_layerref(); } inline ::google::protobuf::uint64 ColorPacket::layerref() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.ColorPacket.layerref) return layerref_; } inline void ColorPacket::set_layerref(::google::protobuf::uint64 value) { set_has_layerref(); layerref_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.ColorPacket.layerref) } // optional uint32 width = 2; @@ -1613,11 +2265,13 @@ inline void ColorPacket::clear_width() { clear_has_width(); } inline ::google::protobuf::uint32 ColorPacket::width() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.ColorPacket.width) return width_; } inline void ColorPacket::set_width(::google::protobuf::uint32 value) { set_has_width(); width_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.ColorPacket.width) } // optional uint32 height = 3; @@ -1635,11 +2289,13 @@ inline void ColorPacket::clear_height() { clear_has_height(); } inline ::google::protobuf::uint32 ColorPacket::height() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.ColorPacket.height) return height_; } inline void ColorPacket::set_height(::google::protobuf::uint32 value) { set_has_height(); height_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.ColorPacket.height) } // optional uint32 color = 4; @@ -1657,11 +2313,13 @@ inline void ColorPacket::clear_color() { clear_has_color(); } inline ::google::protobuf::uint32 ColorPacket::color() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.ColorPacket.color) return color_; } inline void ColorPacket::set_color(::google::protobuf::uint32 value) { set_has_color(); color_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.ColorPacket.color) } // ------------------------------------------------------------------- @@ -1683,11 +2341,13 @@ inline void TexturePacket::clear_layerref() { clear_has_layerref(); } inline ::google::protobuf::uint64 TexturePacket::layerref() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.layerref) return layerref_; } inline void TexturePacket::set_layerref(::google::protobuf::uint64 value) { set_has_layerref(); layerref_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.layerref) } // optional uint32 width = 2; @@ -1705,11 +2365,13 @@ inline void TexturePacket::clear_width() { clear_has_width(); } inline ::google::protobuf::uint32 TexturePacket::width() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.width) return width_; } inline void TexturePacket::set_width(::google::protobuf::uint32 value) { set_has_width(); width_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.width) } // optional uint32 height = 3; @@ -1727,11 +2389,13 @@ inline void TexturePacket::clear_height() { clear_has_height(); } inline ::google::protobuf::uint32 TexturePacket::height() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.height) return height_; } inline void TexturePacket::set_height(::google::protobuf::uint32 value) { set_has_height(); height_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.height) } // optional uint32 stride = 4; @@ -1749,11 +2413,13 @@ inline void TexturePacket::clear_stride() { clear_has_stride(); } inline ::google::protobuf::uint32 TexturePacket::stride() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.stride) return stride_; } inline void TexturePacket::set_stride(::google::protobuf::uint32 value) { set_has_stride(); stride_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.stride) } // optional uint32 name = 5; @@ -1771,11 +2437,13 @@ inline void TexturePacket::clear_name() { clear_has_name(); } inline ::google::protobuf::uint32 TexturePacket::name() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.name) return name_; } inline void TexturePacket::set_name(::google::protobuf::uint32 value) { set_has_name(); name_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.name) } // optional uint32 target = 6; @@ -1793,11 +2461,13 @@ inline void TexturePacket::clear_target() { clear_has_target(); } inline ::google::protobuf::uint32 TexturePacket::target() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.target) return target_; } inline void TexturePacket::set_target(::google::protobuf::uint32 value) { set_has_target(); target_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.target) } // optional uint32 dataformat = 7; @@ -1815,11 +2485,13 @@ inline void TexturePacket::clear_dataformat() { clear_has_dataformat(); } inline ::google::protobuf::uint32 TexturePacket::dataformat() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.dataformat) return dataformat_; } inline void TexturePacket::set_dataformat(::google::protobuf::uint32 value) { set_has_dataformat(); dataformat_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.dataformat) } // optional uint64 glcontext = 8; @@ -1837,11 +2509,13 @@ inline void TexturePacket::clear_glcontext() { clear_has_glcontext(); } inline ::google::protobuf::uint64 TexturePacket::glcontext() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.glcontext) return glcontext_; } inline void TexturePacket::set_glcontext(::google::protobuf::uint64 value) { set_has_glcontext(); glcontext_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.glcontext) } // optional bytes data = 9; @@ -1855,52 +2529,70 @@ inline void TexturePacket::clear_has_data() { _has_bits_[0] &= ~0x00000100u; } inline void TexturePacket::clear_data() { - if (data_ != &::google::protobuf::internal::kEmptyString) { + if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { data_->clear(); } clear_has_data(); } inline const ::std::string& TexturePacket::data() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.TexturePacket.data) return *data_; } inline void TexturePacket::set_data(const ::std::string& value) { set_has_data(); - if (data_ == &::google::protobuf::internal::kEmptyString) { + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { data_ = new ::std::string; } data_->assign(value); + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.TexturePacket.data) } inline void TexturePacket::set_data(const char* value) { set_has_data(); - if (data_ == &::google::protobuf::internal::kEmptyString) { + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { data_ = new ::std::string; } data_->assign(value); + // @@protoc_insertion_point(field_set_char:mozilla.layers.layerscope.TexturePacket.data) } inline void TexturePacket::set_data(const void* value, size_t size) { set_has_data(); - if (data_ == &::google::protobuf::internal::kEmptyString) { + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { data_ = new ::std::string; } data_->assign(reinterpret_cast(value), size); + // @@protoc_insertion_point(field_set_pointer:mozilla.layers.layerscope.TexturePacket.data) } inline ::std::string* TexturePacket::mutable_data() { set_has_data(); - if (data_ == &::google::protobuf::internal::kEmptyString) { + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { data_ = new ::std::string; } + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.TexturePacket.data) return data_; } inline ::std::string* TexturePacket::release_data() { clear_has_data(); - if (data_ == &::google::protobuf::internal::kEmptyString) { + if (data_ == &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { return NULL; } else { ::std::string* temp = data_; - data_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString); + data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); return temp; } } +inline void TexturePacket::set_allocated_data(::std::string* data) { + if (data_ != &::google::protobuf::internal::GetEmptyStringAlreadyInited()) { + delete data_; + } + if (data) { + set_has_data(); + data_ = data; + } else { + clear_has_data(); + data_ = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.TexturePacket.data) +} // ------------------------------------------------------------------- @@ -1921,11 +2613,13 @@ inline void LayersPacket_Layer_Size::clear_w() { clear_has_w(); } inline ::google::protobuf::int32 LayersPacket_Layer_Size::w() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Size.w) return w_; } inline void LayersPacket_Layer_Size::set_w(::google::protobuf::int32 value) { set_has_w(); w_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Size.w) } // optional int32 h = 2; @@ -1943,11 +2637,13 @@ inline void LayersPacket_Layer_Size::clear_h() { clear_has_h(); } inline ::google::protobuf::int32 LayersPacket_Layer_Size::h() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Size.h) return h_; } inline void LayersPacket_Layer_Size::set_h(::google::protobuf::int32 value) { set_has_h(); h_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Size.h) } // ------------------------------------------------------------------- @@ -1969,11 +2665,13 @@ inline void LayersPacket_Layer_Rect::clear_x() { clear_has_x(); } inline ::google::protobuf::int32 LayersPacket_Layer_Rect::x() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Rect.x) return x_; } inline void LayersPacket_Layer_Rect::set_x(::google::protobuf::int32 value) { set_has_x(); x_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Rect.x) } // optional int32 y = 2; @@ -1991,11 +2689,13 @@ inline void LayersPacket_Layer_Rect::clear_y() { clear_has_y(); } inline ::google::protobuf::int32 LayersPacket_Layer_Rect::y() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Rect.y) return y_; } inline void LayersPacket_Layer_Rect::set_y(::google::protobuf::int32 value) { set_has_y(); y_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Rect.y) } // optional int32 w = 3; @@ -2013,11 +2713,13 @@ inline void LayersPacket_Layer_Rect::clear_w() { clear_has_w(); } inline ::google::protobuf::int32 LayersPacket_Layer_Rect::w() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Rect.w) return w_; } inline void LayersPacket_Layer_Rect::set_w(::google::protobuf::int32 value) { set_has_w(); w_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Rect.w) } // optional int32 h = 4; @@ -2035,11 +2737,13 @@ inline void LayersPacket_Layer_Rect::clear_h() { clear_has_h(); } inline ::google::protobuf::int32 LayersPacket_Layer_Rect::h() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Rect.h) return h_; } inline void LayersPacket_Layer_Rect::set_h(::google::protobuf::int32 value) { set_has_h(); h_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Rect.h) } // ------------------------------------------------------------------- @@ -2054,20 +2758,25 @@ inline void LayersPacket_Layer_Region::clear_r() { r_.Clear(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& LayersPacket_Layer_Region::r(int index) const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Region.r) return r_.Get(index); } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer_Region::mutable_r(int index) { + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.Region.r) return r_.Mutable(index); } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer_Region::add_r() { + // @@protoc_insertion_point(field_add:mozilla.layers.layerscope.LayersPacket.Layer.Region.r) return r_.Add(); } inline const ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect >& LayersPacket_Layer_Region::r() const { + // @@protoc_insertion_point(field_list:mozilla.layers.layerscope.LayersPacket.Layer.Region.r) return r_; } inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer_Rect >* LayersPacket_Layer_Region::mutable_r() { + // @@protoc_insertion_point(field_mutable_list:mozilla.layers.layerscope.LayersPacket.Layer.Region.r) return &r_; } @@ -2090,11 +2799,13 @@ inline void LayersPacket_Layer_Matrix::clear_is2d() { clear_has_is2d(); } inline bool LayersPacket_Layer_Matrix::is2d() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.is2D) return is2d_; } inline void LayersPacket_Layer_Matrix::set_is2d(bool value) { set_has_is2d(); is2d_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.is2D) } // optional bool isId = 2; @@ -2112,11 +2823,13 @@ inline void LayersPacket_Layer_Matrix::clear_isid() { clear_has_isid(); } inline bool LayersPacket_Layer_Matrix::isid() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.isId) return isid_; } inline void LayersPacket_Layer_Matrix::set_isid(bool value) { set_has_isid(); isid_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.isId) } // repeated float m = 3; @@ -2127,20 +2840,25 @@ inline void LayersPacket_Layer_Matrix::clear_m() { m_.Clear(); } inline float LayersPacket_Layer_Matrix::m(int index) const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m) return m_.Get(index); } inline void LayersPacket_Layer_Matrix::set_m(int index, float value) { m_.Set(index, value); + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m) } inline void LayersPacket_Layer_Matrix::add_m(float value) { m_.Add(value); + // @@protoc_insertion_point(field_add:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m) } inline const ::google::protobuf::RepeatedField< float >& LayersPacket_Layer_Matrix::m() const { + // @@protoc_insertion_point(field_list:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m) return m_; } inline ::google::protobuf::RepeatedField< float >* LayersPacket_Layer_Matrix::mutable_m() { + // @@protoc_insertion_point(field_mutable_list:mozilla.layers.layerscope.LayersPacket.Layer.Matrix.m) return &m_; } @@ -2163,11 +2881,17 @@ inline void LayersPacket_Layer_Shadow::clear_clip() { clear_has_clip(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& LayersPacket_Layer_Shadow::clip() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.clip) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return clip_ != NULL ? *clip_ : *default_instance().clip_; +#else return clip_ != NULL ? *clip_ : *default_instance_->clip_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer_Shadow::mutable_clip() { set_has_clip(); if (clip_ == NULL) clip_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Rect; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.clip) return clip_; } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer_Shadow::release_clip() { @@ -2176,6 +2900,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Laye clip_ = NULL; return temp; } +inline void LayersPacket_Layer_Shadow::set_allocated_clip(::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip) { + delete clip_; + clip_ = clip; + if (clip) { + set_has_clip(); + } else { + clear_has_clip(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.clip) +} // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 2; inline bool LayersPacket_Layer_Shadow::has_transform() const { @@ -2192,11 +2926,17 @@ inline void LayersPacket_Layer_Shadow::clear_transform() { clear_has_transform(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix& LayersPacket_Layer_Shadow::transform() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.transform) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return transform_ != NULL ? *transform_ : *default_instance().transform_; +#else return transform_ != NULL ? *transform_ : *default_instance_->transform_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_Layer_Shadow::mutable_transform() { set_has_transform(); if (transform_ == NULL) transform_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.transform) return transform_; } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_Layer_Shadow::release_transform() { @@ -2205,6 +2945,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_La transform_ = NULL; return temp; } +inline void LayersPacket_Layer_Shadow::set_allocated_transform(::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform) { + delete transform_; + transform_ = transform; + if (transform) { + set_has_transform(); + } else { + clear_has_transform(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.transform) +} // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 3; inline bool LayersPacket_Layer_Shadow::has_vregion() const { @@ -2221,11 +2971,17 @@ inline void LayersPacket_Layer_Shadow::clear_vregion() { clear_has_vregion(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer_Shadow::vregion() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.vRegion) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return vregion_ != NULL ? *vregion_ : *default_instance().vregion_; +#else return vregion_ != NULL ? *vregion_ : *default_instance_->vregion_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer_Shadow::mutable_vregion() { set_has_vregion(); if (vregion_ == NULL) vregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.vRegion) return vregion_; } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer_Shadow::release_vregion() { @@ -2234,6 +2990,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_La vregion_ = NULL; return temp; } +inline void LayersPacket_Layer_Shadow::set_allocated_vregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion) { + delete vregion_; + vregion_ = vregion; + if (vregion) { + set_has_vregion(); + } else { + clear_has_vregion(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.Shadow.vRegion) +} // ------------------------------------------------------------------- @@ -2254,12 +3020,14 @@ inline void LayersPacket_Layer::clear_type() { clear_has_type(); } inline ::mozilla::layers::layerscope::LayersPacket_Layer_LayerType LayersPacket_Layer::type() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.type) return static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_LayerType >(type_); } inline void LayersPacket_Layer::set_type(::mozilla::layers::layerscope::LayersPacket_Layer_LayerType value) { - GOOGLE_DCHECK(::mozilla::layers::layerscope::LayersPacket_Layer_LayerType_IsValid(value)); + assert(::mozilla::layers::layerscope::LayersPacket_Layer_LayerType_IsValid(value)); set_has_type(); type_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.type) } // required uint64 ptr = 2; @@ -2277,11 +3045,13 @@ inline void LayersPacket_Layer::clear_ptr() { clear_has_ptr(); } inline ::google::protobuf::uint64 LayersPacket_Layer::ptr() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.ptr) return ptr_; } inline void LayersPacket_Layer::set_ptr(::google::protobuf::uint64 value) { set_has_ptr(); ptr_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.ptr) } // required uint64 parentPtr = 3; @@ -2299,11 +3069,13 @@ inline void LayersPacket_Layer::clear_parentptr() { clear_has_parentptr(); } inline ::google::protobuf::uint64 LayersPacket_Layer::parentptr() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.parentPtr) return parentptr_; } inline void LayersPacket_Layer::set_parentptr(::google::protobuf::uint64 value) { set_has_parentptr(); parentptr_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.parentPtr) } // optional .mozilla.layers.layerscope.LayersPacket.Layer.Rect clip = 10; @@ -2321,11 +3093,17 @@ inline void LayersPacket_Layer::clear_clip() { clear_has_clip(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Rect& LayersPacket_Layer::clip() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.clip) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return clip_ != NULL ? *clip_ : *default_instance().clip_; +#else return clip_ != NULL ? *clip_ : *default_instance_->clip_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer::mutable_clip() { set_has_clip(); if (clip_ == NULL) clip_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Rect; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.clip) return clip_; } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Layer::release_clip() { @@ -2334,6 +3112,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Rect* LayersPacket_Laye clip_ = NULL; return temp; } +inline void LayersPacket_Layer::set_allocated_clip(::mozilla::layers::layerscope::LayersPacket_Layer_Rect* clip) { + delete clip_; + clip_ = clip; + if (clip) { + set_has_clip(); + } else { + clear_has_clip(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.clip) +} // optional .mozilla.layers.layerscope.LayersPacket.Layer.Matrix transform = 11; inline bool LayersPacket_Layer::has_transform() const { @@ -2350,11 +3138,17 @@ inline void LayersPacket_Layer::clear_transform() { clear_has_transform(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix& LayersPacket_Layer::transform() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.transform) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return transform_ != NULL ? *transform_ : *default_instance().transform_; +#else return transform_ != NULL ? *transform_ : *default_instance_->transform_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_Layer::mutable_transform() { set_has_transform(); if (transform_ == NULL) transform_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.transform) return transform_; } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_Layer::release_transform() { @@ -2363,6 +3157,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* LayersPacket_La transform_ = NULL; return temp; } +inline void LayersPacket_Layer::set_allocated_transform(::mozilla::layers::layerscope::LayersPacket_Layer_Matrix* transform) { + delete transform_; + transform_ = transform; + if (transform) { + set_has_transform(); + } else { + clear_has_transform(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.transform) +} // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vRegion = 12; inline bool LayersPacket_Layer::has_vregion() const { @@ -2379,11 +3183,17 @@ inline void LayersPacket_Layer::clear_vregion() { clear_has_vregion(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::vregion() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.vRegion) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return vregion_ != NULL ? *vregion_ : *default_instance().vregion_; +#else return vregion_ != NULL ? *vregion_ : *default_instance_->vregion_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_vregion() { set_has_vregion(); if (vregion_ == NULL) vregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.vRegion) return vregion_; } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_vregion() { @@ -2392,6 +3202,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_La vregion_ = NULL; return temp; } +inline void LayersPacket_Layer::set_allocated_vregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vregion) { + delete vregion_; + vregion_ = vregion; + if (vregion) { + set_has_vregion(); + } else { + clear_has_vregion(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.vRegion) +} // optional .mozilla.layers.layerscope.LayersPacket.Layer.Shadow shadow = 13; inline bool LayersPacket_Layer::has_shadow() const { @@ -2408,11 +3228,17 @@ inline void LayersPacket_Layer::clear_shadow() { clear_has_shadow(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow& LayersPacket_Layer::shadow() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.shadow) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return shadow_ != NULL ? *shadow_ : *default_instance().shadow_; +#else return shadow_ != NULL ? *shadow_ : *default_instance_->shadow_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* LayersPacket_Layer::mutable_shadow() { set_has_shadow(); if (shadow_ == NULL) shadow_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.shadow) return shadow_; } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* LayersPacket_Layer::release_shadow() { @@ -2421,6 +3247,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* LayersPacket_La shadow_ = NULL; return temp; } +inline void LayersPacket_Layer::set_allocated_shadow(::mozilla::layers::layerscope::LayersPacket_Layer_Shadow* shadow) { + delete shadow_; + shadow_ = shadow; + if (shadow) { + set_has_shadow(); + } else { + clear_has_shadow(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.shadow) +} // optional float opacity = 14; inline bool LayersPacket_Layer::has_opacity() const { @@ -2437,11 +3273,13 @@ inline void LayersPacket_Layer::clear_opacity() { clear_has_opacity(); } inline float LayersPacket_Layer::opacity() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.opacity) return opacity_; } inline void LayersPacket_Layer::set_opacity(float value) { set_has_opacity(); opacity_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.opacity) } // optional bool cOpaque = 15; @@ -2459,11 +3297,13 @@ inline void LayersPacket_Layer::clear_copaque() { clear_has_copaque(); } inline bool LayersPacket_Layer::copaque() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.cOpaque) return copaque_; } inline void LayersPacket_Layer::set_copaque(bool value) { set_has_copaque(); copaque_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.cOpaque) } // optional bool cAlpha = 16; @@ -2481,11 +3321,13 @@ inline void LayersPacket_Layer::clear_calpha() { clear_has_calpha(); } inline bool LayersPacket_Layer::calpha() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.cAlpha) return calpha_; } inline void LayersPacket_Layer::set_calpha(bool value) { set_has_calpha(); calpha_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.cAlpha) } // optional .mozilla.layers.layerscope.LayersPacket.Layer.ScrollingDirect direct = 17; @@ -2503,12 +3345,14 @@ inline void LayersPacket_Layer::clear_direct() { clear_has_direct(); } inline ::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect LayersPacket_Layer::direct() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.direct) return static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect >(direct_); } inline void LayersPacket_Layer::set_direct(::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect value) { - GOOGLE_DCHECK(::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect_IsValid(value)); + assert(::mozilla::layers::layerscope::LayersPacket_Layer_ScrollingDirect_IsValid(value)); set_has_direct(); direct_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.direct) } // optional uint64 barID = 18; @@ -2526,11 +3370,13 @@ inline void LayersPacket_Layer::clear_barid() { clear_has_barid(); } inline ::google::protobuf::uint64 LayersPacket_Layer::barid() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.barID) return barid_; } inline void LayersPacket_Layer::set_barid(::google::protobuf::uint64 value) { set_has_barid(); barid_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.barID) } // optional uint64 mask = 19; @@ -2548,33 +3394,266 @@ inline void LayersPacket_Layer::clear_mask() { clear_has_mask(); } inline ::google::protobuf::uint64 LayersPacket_Layer::mask() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.mask) return mask_; } inline void LayersPacket_Layer::set_mask(::google::protobuf::uint64 value) { set_has_mask(); mask_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.mask) +} + +// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hitRegion = 20; +inline bool LayersPacket_Layer::has_hitregion() const { + return (_has_bits_[0] & 0x00002000u) != 0; +} +inline void LayersPacket_Layer::set_has_hitregion() { + _has_bits_[0] |= 0x00002000u; +} +inline void LayersPacket_Layer::clear_has_hitregion() { + _has_bits_[0] &= ~0x00002000u; +} +inline void LayersPacket_Layer::clear_hitregion() { + if (hitregion_ != NULL) hitregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + clear_has_hitregion(); +} +inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::hitregion() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.hitRegion) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return hitregion_ != NULL ? *hitregion_ : *default_instance().hitregion_; +#else + return hitregion_ != NULL ? *hitregion_ : *default_instance_->hitregion_; +#endif +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_hitregion() { + set_has_hitregion(); + if (hitregion_ == NULL) hitregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.hitRegion) + return hitregion_; +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_hitregion() { + clear_has_hitregion(); + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = hitregion_; + hitregion_ = NULL; + return temp; +} +inline void LayersPacket_Layer::set_allocated_hitregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* hitregion) { + delete hitregion_; + hitregion_ = hitregion; + if (hitregion) { + set_has_hitregion(); + } else { + clear_has_hitregion(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.hitRegion) +} + +// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region dispatchRegion = 21; +inline bool LayersPacket_Layer::has_dispatchregion() const { + return (_has_bits_[0] & 0x00004000u) != 0; +} +inline void LayersPacket_Layer::set_has_dispatchregion() { + _has_bits_[0] |= 0x00004000u; +} +inline void LayersPacket_Layer::clear_has_dispatchregion() { + _has_bits_[0] &= ~0x00004000u; +} +inline void LayersPacket_Layer::clear_dispatchregion() { + if (dispatchregion_ != NULL) dispatchregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + clear_has_dispatchregion(); +} +inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::dispatchregion() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.dispatchRegion) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return dispatchregion_ != NULL ? *dispatchregion_ : *default_instance().dispatchregion_; +#else + return dispatchregion_ != NULL ? *dispatchregion_ : *default_instance_->dispatchregion_; +#endif +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_dispatchregion() { + set_has_dispatchregion(); + if (dispatchregion_ == NULL) dispatchregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.dispatchRegion) + return dispatchregion_; +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_dispatchregion() { + clear_has_dispatchregion(); + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = dispatchregion_; + dispatchregion_ = NULL; + return temp; +} +inline void LayersPacket_Layer::set_allocated_dispatchregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* dispatchregion) { + delete dispatchregion_; + dispatchregion_ = dispatchregion; + if (dispatchregion) { + set_has_dispatchregion(); + } else { + clear_has_dispatchregion(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.dispatchRegion) +} + +// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region noActionRegion = 22; +inline bool LayersPacket_Layer::has_noactionregion() const { + return (_has_bits_[0] & 0x00008000u) != 0; +} +inline void LayersPacket_Layer::set_has_noactionregion() { + _has_bits_[0] |= 0x00008000u; +} +inline void LayersPacket_Layer::clear_has_noactionregion() { + _has_bits_[0] &= ~0x00008000u; +} +inline void LayersPacket_Layer::clear_noactionregion() { + if (noactionregion_ != NULL) noactionregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + clear_has_noactionregion(); +} +inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::noactionregion() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.noActionRegion) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return noactionregion_ != NULL ? *noactionregion_ : *default_instance().noactionregion_; +#else + return noactionregion_ != NULL ? *noactionregion_ : *default_instance_->noactionregion_; +#endif +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_noactionregion() { + set_has_noactionregion(); + if (noactionregion_ == NULL) noactionregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.noActionRegion) + return noactionregion_; +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_noactionregion() { + clear_has_noactionregion(); + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = noactionregion_; + noactionregion_ = NULL; + return temp; +} +inline void LayersPacket_Layer::set_allocated_noactionregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* noactionregion) { + delete noactionregion_; + noactionregion_ = noactionregion; + if (noactionregion) { + set_has_noactionregion(); + } else { + clear_has_noactionregion(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.noActionRegion) +} + +// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region hPanRegion = 23; +inline bool LayersPacket_Layer::has_hpanregion() const { + return (_has_bits_[0] & 0x00010000u) != 0; +} +inline void LayersPacket_Layer::set_has_hpanregion() { + _has_bits_[0] |= 0x00010000u; +} +inline void LayersPacket_Layer::clear_has_hpanregion() { + _has_bits_[0] &= ~0x00010000u; +} +inline void LayersPacket_Layer::clear_hpanregion() { + if (hpanregion_ != NULL) hpanregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + clear_has_hpanregion(); +} +inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::hpanregion() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.hPanRegion) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return hpanregion_ != NULL ? *hpanregion_ : *default_instance().hpanregion_; +#else + return hpanregion_ != NULL ? *hpanregion_ : *default_instance_->hpanregion_; +#endif +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_hpanregion() { + set_has_hpanregion(); + if (hpanregion_ == NULL) hpanregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.hPanRegion) + return hpanregion_; +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_hpanregion() { + clear_has_hpanregion(); + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = hpanregion_; + hpanregion_ = NULL; + return temp; +} +inline void LayersPacket_Layer::set_allocated_hpanregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* hpanregion) { + delete hpanregion_; + hpanregion_ = hpanregion; + if (hpanregion) { + set_has_hpanregion(); + } else { + clear_has_hpanregion(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.hPanRegion) +} + +// optional .mozilla.layers.layerscope.LayersPacket.Layer.Region vPanRegion = 24; +inline bool LayersPacket_Layer::has_vpanregion() const { + return (_has_bits_[0] & 0x00020000u) != 0; +} +inline void LayersPacket_Layer::set_has_vpanregion() { + _has_bits_[0] |= 0x00020000u; +} +inline void LayersPacket_Layer::clear_has_vpanregion() { + _has_bits_[0] &= ~0x00020000u; +} +inline void LayersPacket_Layer::clear_vpanregion() { + if (vpanregion_ != NULL) vpanregion_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); + clear_has_vpanregion(); +} +inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::vpanregion() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.vPanRegion) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return vpanregion_ != NULL ? *vpanregion_ : *default_instance().vpanregion_; +#else + return vpanregion_ != NULL ? *vpanregion_ : *default_instance_->vpanregion_; +#endif +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_vpanregion() { + set_has_vpanregion(); + if (vpanregion_ == NULL) vpanregion_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.vPanRegion) + return vpanregion_; +} +inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_vpanregion() { + clear_has_vpanregion(); + ::mozilla::layers::layerscope::LayersPacket_Layer_Region* temp = vpanregion_; + vpanregion_ = NULL; + return temp; +} +inline void LayersPacket_Layer::set_allocated_vpanregion(::mozilla::layers::layerscope::LayersPacket_Layer_Region* vpanregion) { + delete vpanregion_; + vpanregion_ = vpanregion; + if (vpanregion) { + set_has_vpanregion(); + } else { + clear_has_vpanregion(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.vPanRegion) } // optional .mozilla.layers.layerscope.LayersPacket.Layer.Region valid = 100; inline bool LayersPacket_Layer::has_valid() const { - return (_has_bits_[0] & 0x00002000u) != 0; + return (_has_bits_[0] & 0x00040000u) != 0; } inline void LayersPacket_Layer::set_has_valid() { - _has_bits_[0] |= 0x00002000u; + _has_bits_[0] |= 0x00040000u; } inline void LayersPacket_Layer::clear_has_valid() { - _has_bits_[0] &= ~0x00002000u; + _has_bits_[0] &= ~0x00040000u; } inline void LayersPacket_Layer::clear_valid() { if (valid_ != NULL) valid_->::mozilla::layers::layerscope::LayersPacket_Layer_Region::Clear(); clear_has_valid(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Region& LayersPacket_Layer::valid() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.valid) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return valid_ != NULL ? *valid_ : *default_instance().valid_; +#else return valid_ != NULL ? *valid_ : *default_instance_->valid_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::mutable_valid() { set_has_valid(); if (valid_ == NULL) valid_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Region; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.valid) return valid_; } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_Layer::release_valid() { @@ -2583,94 +3662,116 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Region* LayersPacket_La valid_ = NULL; return temp; } +inline void LayersPacket_Layer::set_allocated_valid(::mozilla::layers::layerscope::LayersPacket_Layer_Region* valid) { + delete valid_; + valid_ = valid; + if (valid) { + set_has_valid(); + } else { + clear_has_valid(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.valid) +} // optional uint32 color = 101; inline bool LayersPacket_Layer::has_color() const { - return (_has_bits_[0] & 0x00004000u) != 0; + return (_has_bits_[0] & 0x00080000u) != 0; } inline void LayersPacket_Layer::set_has_color() { - _has_bits_[0] |= 0x00004000u; + _has_bits_[0] |= 0x00080000u; } inline void LayersPacket_Layer::clear_has_color() { - _has_bits_[0] &= ~0x00004000u; + _has_bits_[0] &= ~0x00080000u; } inline void LayersPacket_Layer::clear_color() { color_ = 0u; clear_has_color(); } inline ::google::protobuf::uint32 LayersPacket_Layer::color() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.color) return color_; } inline void LayersPacket_Layer::set_color(::google::protobuf::uint32 value) { set_has_color(); color_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.color) } // optional .mozilla.layers.layerscope.LayersPacket.Layer.Filter filter = 102; inline bool LayersPacket_Layer::has_filter() const { - return (_has_bits_[0] & 0x00008000u) != 0; + return (_has_bits_[0] & 0x00100000u) != 0; } inline void LayersPacket_Layer::set_has_filter() { - _has_bits_[0] |= 0x00008000u; + _has_bits_[0] |= 0x00100000u; } inline void LayersPacket_Layer::clear_has_filter() { - _has_bits_[0] &= ~0x00008000u; + _has_bits_[0] &= ~0x00100000u; } inline void LayersPacket_Layer::clear_filter() { filter_ = 0; clear_has_filter(); } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Filter LayersPacket_Layer::filter() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.filter) return static_cast< ::mozilla::layers::layerscope::LayersPacket_Layer_Filter >(filter_); } inline void LayersPacket_Layer::set_filter(::mozilla::layers::layerscope::LayersPacket_Layer_Filter value) { - GOOGLE_DCHECK(::mozilla::layers::layerscope::LayersPacket_Layer_Filter_IsValid(value)); + assert(::mozilla::layers::layerscope::LayersPacket_Layer_Filter_IsValid(value)); set_has_filter(); filter_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.filter) } // optional uint64 refID = 103; inline bool LayersPacket_Layer::has_refid() const { - return (_has_bits_[0] & 0x00010000u) != 0; + return (_has_bits_[0] & 0x00200000u) != 0; } inline void LayersPacket_Layer::set_has_refid() { - _has_bits_[0] |= 0x00010000u; + _has_bits_[0] |= 0x00200000u; } inline void LayersPacket_Layer::clear_has_refid() { - _has_bits_[0] &= ~0x00010000u; + _has_bits_[0] &= ~0x00200000u; } inline void LayersPacket_Layer::clear_refid() { refid_ = GOOGLE_ULONGLONG(0); clear_has_refid(); } inline ::google::protobuf::uint64 LayersPacket_Layer::refid() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.refID) return refid_; } inline void LayersPacket_Layer::set_refid(::google::protobuf::uint64 value) { set_has_refid(); refid_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.LayersPacket.Layer.refID) } // optional .mozilla.layers.layerscope.LayersPacket.Layer.Size size = 104; inline bool LayersPacket_Layer::has_size() const { - return (_has_bits_[0] & 0x00020000u) != 0; + return (_has_bits_[0] & 0x00400000u) != 0; } inline void LayersPacket_Layer::set_has_size() { - _has_bits_[0] |= 0x00020000u; + _has_bits_[0] |= 0x00400000u; } inline void LayersPacket_Layer::clear_has_size() { - _has_bits_[0] &= ~0x00020000u; + _has_bits_[0] &= ~0x00400000u; } inline void LayersPacket_Layer::clear_size() { if (size_ != NULL) size_->::mozilla::layers::layerscope::LayersPacket_Layer_Size::Clear(); clear_has_size(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer_Size& LayersPacket_Layer::size() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.Layer.size) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return size_ != NULL ? *size_ : *default_instance().size_; +#else return size_ != NULL ? *size_ : *default_instance_->size_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* LayersPacket_Layer::mutable_size() { set_has_size(); if (size_ == NULL) size_ = new ::mozilla::layers::layerscope::LayersPacket_Layer_Size; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.Layer.size) return size_; } inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* LayersPacket_Layer::release_size() { @@ -2679,6 +3780,16 @@ inline ::mozilla::layers::layerscope::LayersPacket_Layer_Size* LayersPacket_Laye size_ = NULL; return temp; } +inline void LayersPacket_Layer::set_allocated_size(::mozilla::layers::layerscope::LayersPacket_Layer_Size* size) { + delete size_; + size_ = size; + if (size) { + set_has_size(); + } else { + clear_has_size(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.LayersPacket.Layer.size) +} // ------------------------------------------------------------------- @@ -2692,20 +3803,25 @@ inline void LayersPacket::clear_layer() { layer_.Clear(); } inline const ::mozilla::layers::layerscope::LayersPacket_Layer& LayersPacket::layer(int index) const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.LayersPacket.layer) return layer_.Get(index); } inline ::mozilla::layers::layerscope::LayersPacket_Layer* LayersPacket::mutable_layer(int index) { + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.LayersPacket.layer) return layer_.Mutable(index); } inline ::mozilla::layers::layerscope::LayersPacket_Layer* LayersPacket::add_layer() { + // @@protoc_insertion_point(field_add:mozilla.layers.layerscope.LayersPacket.layer) return layer_.Add(); } inline const ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer >& LayersPacket::layer() const { + // @@protoc_insertion_point(field_list:mozilla.layers.layerscope.LayersPacket.layer) return layer_; } inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::LayersPacket_Layer >* LayersPacket::mutable_layer() { + // @@protoc_insertion_point(field_mutable_list:mozilla.layers.layerscope.LayersPacket.layer) return &layer_; } @@ -2728,11 +3844,273 @@ inline void MetaPacket::clear_composedbyhwc() { clear_has_composedbyhwc(); } inline bool MetaPacket::composedbyhwc() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.MetaPacket.composedByHwc) return composedbyhwc_; } inline void MetaPacket::set_composedbyhwc(bool value) { set_has_composedbyhwc(); composedbyhwc_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.MetaPacket.composedByHwc) +} + +// ------------------------------------------------------------------- + +// DrawPacket_Rect + +// required float x = 1; +inline bool DrawPacket_Rect::has_x() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DrawPacket_Rect::set_has_x() { + _has_bits_[0] |= 0x00000001u; +} +inline void DrawPacket_Rect::clear_has_x() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DrawPacket_Rect::clear_x() { + x_ = 0; + clear_has_x(); +} +inline float DrawPacket_Rect::x() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.Rect.x) + return x_; +} +inline void DrawPacket_Rect::set_x(float value) { + set_has_x(); + x_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.DrawPacket.Rect.x) +} + +// required float y = 2; +inline bool DrawPacket_Rect::has_y() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void DrawPacket_Rect::set_has_y() { + _has_bits_[0] |= 0x00000002u; +} +inline void DrawPacket_Rect::clear_has_y() { + _has_bits_[0] &= ~0x00000002u; +} +inline void DrawPacket_Rect::clear_y() { + y_ = 0; + clear_has_y(); +} +inline float DrawPacket_Rect::y() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.Rect.y) + return y_; +} +inline void DrawPacket_Rect::set_y(float value) { + set_has_y(); + y_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.DrawPacket.Rect.y) +} + +// required float w = 3; +inline bool DrawPacket_Rect::has_w() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void DrawPacket_Rect::set_has_w() { + _has_bits_[0] |= 0x00000004u; +} +inline void DrawPacket_Rect::clear_has_w() { + _has_bits_[0] &= ~0x00000004u; +} +inline void DrawPacket_Rect::clear_w() { + w_ = 0; + clear_has_w(); +} +inline float DrawPacket_Rect::w() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.Rect.w) + return w_; +} +inline void DrawPacket_Rect::set_w(float value) { + set_has_w(); + w_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.DrawPacket.Rect.w) +} + +// required float h = 4; +inline bool DrawPacket_Rect::has_h() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void DrawPacket_Rect::set_has_h() { + _has_bits_[0] |= 0x00000008u; +} +inline void DrawPacket_Rect::clear_has_h() { + _has_bits_[0] &= ~0x00000008u; +} +inline void DrawPacket_Rect::clear_h() { + h_ = 0; + clear_has_h(); +} +inline float DrawPacket_Rect::h() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.Rect.h) + return h_; +} +inline void DrawPacket_Rect::set_h(float value) { + set_has_h(); + h_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.DrawPacket.Rect.h) +} + +// ------------------------------------------------------------------- + +// DrawPacket + +// required float offsetX = 1; +inline bool DrawPacket::has_offsetx() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void DrawPacket::set_has_offsetx() { + _has_bits_[0] |= 0x00000001u; +} +inline void DrawPacket::clear_has_offsetx() { + _has_bits_[0] &= ~0x00000001u; +} +inline void DrawPacket::clear_offsetx() { + offsetx_ = 0; + clear_has_offsetx(); +} +inline float DrawPacket::offsetx() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.offsetX) + return offsetx_; +} +inline void DrawPacket::set_offsetx(float value) { + set_has_offsetx(); + offsetx_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.DrawPacket.offsetX) +} + +// required float offsetY = 2; +inline bool DrawPacket::has_offsety() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void DrawPacket::set_has_offsety() { + _has_bits_[0] |= 0x00000002u; +} +inline void DrawPacket::clear_has_offsety() { + _has_bits_[0] &= ~0x00000002u; +} +inline void DrawPacket::clear_offsety() { + offsety_ = 0; + clear_has_offsety(); +} +inline float DrawPacket::offsety() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.offsetY) + return offsety_; +} +inline void DrawPacket::set_offsety(float value) { + set_has_offsety(); + offsety_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.DrawPacket.offsetY) +} + +// repeated float mvMatrix = 3; +inline int DrawPacket::mvmatrix_size() const { + return mvmatrix_.size(); +} +inline void DrawPacket::clear_mvmatrix() { + mvmatrix_.Clear(); +} +inline float DrawPacket::mvmatrix(int index) const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.mvMatrix) + return mvmatrix_.Get(index); +} +inline void DrawPacket::set_mvmatrix(int index, float value) { + mvmatrix_.Set(index, value); + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.DrawPacket.mvMatrix) +} +inline void DrawPacket::add_mvmatrix(float value) { + mvmatrix_.Add(value); + // @@protoc_insertion_point(field_add:mozilla.layers.layerscope.DrawPacket.mvMatrix) +} +inline const ::google::protobuf::RepeatedField< float >& +DrawPacket::mvmatrix() const { + // @@protoc_insertion_point(field_list:mozilla.layers.layerscope.DrawPacket.mvMatrix) + return mvmatrix_; +} +inline ::google::protobuf::RepeatedField< float >* +DrawPacket::mutable_mvmatrix() { + // @@protoc_insertion_point(field_mutable_list:mozilla.layers.layerscope.DrawPacket.mvMatrix) + return &mvmatrix_; +} + +// required uint32 totalRects = 4; +inline bool DrawPacket::has_totalrects() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void DrawPacket::set_has_totalrects() { + _has_bits_[0] |= 0x00000008u; +} +inline void DrawPacket::clear_has_totalrects() { + _has_bits_[0] &= ~0x00000008u; +} +inline void DrawPacket::clear_totalrects() { + totalrects_ = 0u; + clear_has_totalrects(); +} +inline ::google::protobuf::uint32 DrawPacket::totalrects() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.totalRects) + return totalrects_; +} +inline void DrawPacket::set_totalrects(::google::protobuf::uint32 value) { + set_has_totalrects(); + totalrects_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.DrawPacket.totalRects) +} + +// repeated .mozilla.layers.layerscope.DrawPacket.Rect layerRect = 5; +inline int DrawPacket::layerrect_size() const { + return layerrect_.size(); +} +inline void DrawPacket::clear_layerrect() { + layerrect_.Clear(); +} +inline const ::mozilla::layers::layerscope::DrawPacket_Rect& DrawPacket::layerrect(int index) const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.layerRect) + return layerrect_.Get(index); +} +inline ::mozilla::layers::layerscope::DrawPacket_Rect* DrawPacket::mutable_layerrect(int index) { + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.DrawPacket.layerRect) + return layerrect_.Mutable(index); +} +inline ::mozilla::layers::layerscope::DrawPacket_Rect* DrawPacket::add_layerrect() { + // @@protoc_insertion_point(field_add:mozilla.layers.layerscope.DrawPacket.layerRect) + return layerrect_.Add(); +} +inline const ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::DrawPacket_Rect >& +DrawPacket::layerrect() const { + // @@protoc_insertion_point(field_list:mozilla.layers.layerscope.DrawPacket.layerRect) + return layerrect_; +} +inline ::google::protobuf::RepeatedPtrField< ::mozilla::layers::layerscope::DrawPacket_Rect >* +DrawPacket::mutable_layerrect() { + // @@protoc_insertion_point(field_mutable_list:mozilla.layers.layerscope.DrawPacket.layerRect) + return &layerrect_; +} + +// required uint64 layerref = 6; +inline bool DrawPacket::has_layerref() const { + return (_has_bits_[0] & 0x00000020u) != 0; +} +inline void DrawPacket::set_has_layerref() { + _has_bits_[0] |= 0x00000020u; +} +inline void DrawPacket::clear_has_layerref() { + _has_bits_[0] &= ~0x00000020u; +} +inline void DrawPacket::clear_layerref() { + layerref_ = GOOGLE_ULONGLONG(0); + clear_has_layerref(); +} +inline ::google::protobuf::uint64 DrawPacket::layerref() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.DrawPacket.layerref) + return layerref_; +} +inline void DrawPacket::set_layerref(::google::protobuf::uint64 value) { + set_has_layerref(); + layerref_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.DrawPacket.layerref) } // ------------------------------------------------------------------- @@ -2754,12 +4132,14 @@ inline void Packet::clear_type() { clear_has_type(); } inline ::mozilla::layers::layerscope::Packet_DataType Packet::type() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.type) return static_cast< ::mozilla::layers::layerscope::Packet_DataType >(type_); } inline void Packet::set_type(::mozilla::layers::layerscope::Packet_DataType value) { - GOOGLE_DCHECK(::mozilla::layers::layerscope::Packet_DataType_IsValid(value)); + assert(::mozilla::layers::layerscope::Packet_DataType_IsValid(value)); set_has_type(); type_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.Packet.type) } // optional .mozilla.layers.layerscope.FramePacket frame = 2; @@ -2777,11 +4157,17 @@ inline void Packet::clear_frame() { clear_has_frame(); } inline const ::mozilla::layers::layerscope::FramePacket& Packet::frame() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.frame) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return frame_ != NULL ? *frame_ : *default_instance().frame_; +#else return frame_ != NULL ? *frame_ : *default_instance_->frame_; +#endif } inline ::mozilla::layers::layerscope::FramePacket* Packet::mutable_frame() { set_has_frame(); if (frame_ == NULL) frame_ = new ::mozilla::layers::layerscope::FramePacket; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.frame) return frame_; } inline ::mozilla::layers::layerscope::FramePacket* Packet::release_frame() { @@ -2790,6 +4176,16 @@ inline ::mozilla::layers::layerscope::FramePacket* Packet::release_frame() { frame_ = NULL; return temp; } +inline void Packet::set_allocated_frame(::mozilla::layers::layerscope::FramePacket* frame) { + delete frame_; + frame_ = frame; + if (frame) { + set_has_frame(); + } else { + clear_has_frame(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.frame) +} // optional .mozilla.layers.layerscope.ColorPacket color = 3; inline bool Packet::has_color() const { @@ -2806,11 +4202,17 @@ inline void Packet::clear_color() { clear_has_color(); } inline const ::mozilla::layers::layerscope::ColorPacket& Packet::color() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.color) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return color_ != NULL ? *color_ : *default_instance().color_; +#else return color_ != NULL ? *color_ : *default_instance_->color_; +#endif } inline ::mozilla::layers::layerscope::ColorPacket* Packet::mutable_color() { set_has_color(); if (color_ == NULL) color_ = new ::mozilla::layers::layerscope::ColorPacket; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.color) return color_; } inline ::mozilla::layers::layerscope::ColorPacket* Packet::release_color() { @@ -2819,6 +4221,16 @@ inline ::mozilla::layers::layerscope::ColorPacket* Packet::release_color() { color_ = NULL; return temp; } +inline void Packet::set_allocated_color(::mozilla::layers::layerscope::ColorPacket* color) { + delete color_; + color_ = color; + if (color) { + set_has_color(); + } else { + clear_has_color(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.color) +} // optional .mozilla.layers.layerscope.TexturePacket texture = 4; inline bool Packet::has_texture() const { @@ -2835,11 +4247,17 @@ inline void Packet::clear_texture() { clear_has_texture(); } inline const ::mozilla::layers::layerscope::TexturePacket& Packet::texture() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.texture) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return texture_ != NULL ? *texture_ : *default_instance().texture_; +#else return texture_ != NULL ? *texture_ : *default_instance_->texture_; +#endif } inline ::mozilla::layers::layerscope::TexturePacket* Packet::mutable_texture() { set_has_texture(); if (texture_ == NULL) texture_ = new ::mozilla::layers::layerscope::TexturePacket; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.texture) return texture_; } inline ::mozilla::layers::layerscope::TexturePacket* Packet::release_texture() { @@ -2848,6 +4266,16 @@ inline ::mozilla::layers::layerscope::TexturePacket* Packet::release_texture() { texture_ = NULL; return temp; } +inline void Packet::set_allocated_texture(::mozilla::layers::layerscope::TexturePacket* texture) { + delete texture_; + texture_ = texture; + if (texture) { + set_has_texture(); + } else { + clear_has_texture(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.texture) +} // optional .mozilla.layers.layerscope.LayersPacket layers = 5; inline bool Packet::has_layers() const { @@ -2864,11 +4292,17 @@ inline void Packet::clear_layers() { clear_has_layers(); } inline const ::mozilla::layers::layerscope::LayersPacket& Packet::layers() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.layers) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return layers_ != NULL ? *layers_ : *default_instance().layers_; +#else return layers_ != NULL ? *layers_ : *default_instance_->layers_; +#endif } inline ::mozilla::layers::layerscope::LayersPacket* Packet::mutable_layers() { set_has_layers(); if (layers_ == NULL) layers_ = new ::mozilla::layers::layerscope::LayersPacket; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.layers) return layers_; } inline ::mozilla::layers::layerscope::LayersPacket* Packet::release_layers() { @@ -2877,6 +4311,16 @@ inline ::mozilla::layers::layerscope::LayersPacket* Packet::release_layers() { layers_ = NULL; return temp; } +inline void Packet::set_allocated_layers(::mozilla::layers::layerscope::LayersPacket* layers) { + delete layers_; + layers_ = layers; + if (layers) { + set_has_layers(); + } else { + clear_has_layers(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.layers) +} // optional .mozilla.layers.layerscope.MetaPacket meta = 6; inline bool Packet::has_meta() const { @@ -2893,11 +4337,17 @@ inline void Packet::clear_meta() { clear_has_meta(); } inline const ::mozilla::layers::layerscope::MetaPacket& Packet::meta() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.meta) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return meta_ != NULL ? *meta_ : *default_instance().meta_; +#else return meta_ != NULL ? *meta_ : *default_instance_->meta_; +#endif } inline ::mozilla::layers::layerscope::MetaPacket* Packet::mutable_meta() { set_has_meta(); if (meta_ == NULL) meta_ = new ::mozilla::layers::layerscope::MetaPacket; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.meta) return meta_; } inline ::mozilla::layers::layerscope::MetaPacket* Packet::release_meta() { @@ -2906,6 +4356,61 @@ inline ::mozilla::layers::layerscope::MetaPacket* Packet::release_meta() { meta_ = NULL; return temp; } +inline void Packet::set_allocated_meta(::mozilla::layers::layerscope::MetaPacket* meta) { + delete meta_; + meta_ = meta; + if (meta) { + set_has_meta(); + } else { + clear_has_meta(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.meta) +} + +// optional .mozilla.layers.layerscope.DrawPacket draw = 7; +inline bool Packet::has_draw() const { + return (_has_bits_[0] & 0x00000040u) != 0; +} +inline void Packet::set_has_draw() { + _has_bits_[0] |= 0x00000040u; +} +inline void Packet::clear_has_draw() { + _has_bits_[0] &= ~0x00000040u; +} +inline void Packet::clear_draw() { + if (draw_ != NULL) draw_->::mozilla::layers::layerscope::DrawPacket::Clear(); + clear_has_draw(); +} +inline const ::mozilla::layers::layerscope::DrawPacket& Packet::draw() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.Packet.draw) +#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER + return draw_ != NULL ? *draw_ : *default_instance().draw_; +#else + return draw_ != NULL ? *draw_ : *default_instance_->draw_; +#endif +} +inline ::mozilla::layers::layerscope::DrawPacket* Packet::mutable_draw() { + set_has_draw(); + if (draw_ == NULL) draw_ = new ::mozilla::layers::layerscope::DrawPacket; + // @@protoc_insertion_point(field_mutable:mozilla.layers.layerscope.Packet.draw) + return draw_; +} +inline ::mozilla::layers::layerscope::DrawPacket* Packet::release_draw() { + clear_has_draw(); + ::mozilla::layers::layerscope::DrawPacket* temp = draw_; + draw_ = NULL; + return temp; +} +inline void Packet::set_allocated_draw(::mozilla::layers::layerscope::DrawPacket* draw) { + delete draw_; + draw_ = draw; + if (draw) { + set_has_draw(); + } else { + clear_has_draw(); + } + // @@protoc_insertion_point(field_set_allocated:mozilla.layers.layerscope.Packet.draw) +} // ------------------------------------------------------------------- @@ -2926,12 +4431,14 @@ inline void CommandPacket::clear_type() { clear_has_type(); } inline ::mozilla::layers::layerscope::CommandPacket_CmdType CommandPacket::type() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.CommandPacket.type) return static_cast< ::mozilla::layers::layerscope::CommandPacket_CmdType >(type_); } inline void CommandPacket::set_type(::mozilla::layers::layerscope::CommandPacket_CmdType value) { - GOOGLE_DCHECK(::mozilla::layers::layerscope::CommandPacket_CmdType_IsValid(value)); + assert(::mozilla::layers::layerscope::CommandPacket_CmdType_IsValid(value)); set_has_type(); type_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.CommandPacket.type) } // optional bool value = 2; @@ -2949,11 +4456,13 @@ inline void CommandPacket::clear_value() { clear_has_value(); } inline bool CommandPacket::value() const { + // @@protoc_insertion_point(field_get:mozilla.layers.layerscope.CommandPacket.value) return value_; } inline void CommandPacket::set_value(bool value) { set_has_value(); value_ = value; + // @@protoc_insertion_point(field_set:mozilla.layers.layerscope.CommandPacket.value) } diff --git a/gfx/layers/protobuf/LayerScopePacket.proto b/gfx/layers/protobuf/LayerScopePacket.proto index 11341e216e..9beaafc81b 100644 --- a/gfx/layers/protobuf/LayerScopePacket.proto +++ b/gfx/layers/protobuf/LayerScopePacket.proto @@ -97,6 +97,11 @@ message LayersPacket { optional ScrollingDirect direct = 17; optional uint64 barID = 18; optional uint64 mask = 19; // mask layer + optional Region hitRegion = 20; + optional Region dispatchRegion = 21; + optional Region noActionRegion = 22; + optional Region hPanRegion = 23; + optional Region vPanRegion = 24; // Specific info (100 to max) // Painted Layer @@ -117,6 +122,22 @@ message MetaPacket { optional bool composedByHwc = 1; } +message DrawPacket { + message Rect { + required float x = 1; + required float y = 2; + required float w = 3; + required float h = 4; + } + + required float offsetX = 1; + required float offsetY = 2; + repeated float mvMatrix = 3; + required uint32 totalRects = 4; + repeated Rect layerRect = 5; + required uint64 layerref = 6; +} + // We only need to use this Packet. // Other packet definitions are just type defines message Packet { @@ -127,6 +148,7 @@ message Packet { TEXTURE = 4; LAYERS = 5; META = 6; + DRAW = 7; } required DataType type = 1; @@ -135,6 +157,7 @@ message Packet { optional TexturePacket texture = 4; optional LayersPacket layers = 5; optional MetaPacket meta = 6; + optional DrawPacket draw = 7; } diff --git a/js/public/Debug.h b/js/public/Debug.h index e4379be782..bec9b40443 100644 --- a/js/public/Debug.h +++ b/js/public/Debug.h @@ -262,7 +262,13 @@ class BuilderOrigin : public Builder { // Tell Debuggers in |runtime| to use |mallocSizeOf| to find the size of // malloc'd blocks. -void SetDebuggerMallocSizeOf(JSRuntime* runtime, mozilla::MallocSizeOf mallocSizeOf); +JS_PUBLIC_API(void) +SetDebuggerMallocSizeOf(JSRuntime* runtime, mozilla::MallocSizeOf mallocSizeOf); + +// Get the MallocSizeOf function that the given runtime is using to find the +// size of malloc'd blocks. +JS_PUBLIC_API(mozilla::MallocSizeOf) +GetDebuggerMallocSizeOf(JSRuntime* runtime); @@ -316,7 +322,12 @@ onPromiseSettled(JSContext* cx, HandleObject promise); // Return true if the given value is a Debugger object, false otherwise. JS_PUBLIC_API(bool) -IsDebugger(JS::Value val); +IsDebugger(const JSObject& obj); + +// Append each of the debuggee global objects observed by the Debugger object +// |dbgObj| to |vector|. Returns true on success, false on failure. +JS_PUBLIC_API(bool) +GetDebuggeeGlobals(JSContext* cx, const JSObject& dbgObj, AutoObjectVector& vector); // Hooks for reporting where JavaScript execution began. diff --git a/js/public/HeapAPI.h b/js/public/HeapAPI.h index f1b9cc6882..5aa41dcfc2 100644 --- a/js/public/HeapAPI.h +++ b/js/public/HeapAPI.h @@ -328,10 +328,16 @@ IsInsideNursery(const js::gc::Cell* cell) namespace JS { static MOZ_ALWAYS_INLINE Zone* -GetTenuredGCThingZone(void* thing) +GetTenuredGCThingZone(GCCellPtr thing) { - MOZ_ASSERT(!js::gc::IsInsideNursery((js::gc::Cell*)thing)); - return js::gc::detail::GetGCThingZone(uintptr_t(thing)); + MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); + return js::gc::detail::GetGCThingZone(thing.unsafeAsUIntPtr()); +} + +static MOZ_ALWAYS_INLINE Zone* +GetStringZone(JSString* str) +{ + return js::gc::detail::GetGCThingZone(uintptr_t(str)); } extern JS_PUBLIC_API(Zone*) @@ -382,9 +388,9 @@ IsIncrementalBarrierNeededOnTenuredGCThing(JS::shadow::Runtime* rt, const JS::GC { MOZ_ASSERT(thing); MOZ_ASSERT(!js::gc::IsInsideNursery(thing.asCell())); - if (!rt->needsIncrementalBarrier()) + if (rt->isHeapBusy()) return false; - JS::Zone* zone = JS::GetTenuredGCThingZone(thing.asCell()); + JS::Zone* zone = JS::GetTenuredGCThingZone(thing); return JS::shadow::Zone::asShadowZone(zone)->needsIncrementalBarrier(); } diff --git a/js/public/TrackedOptimizationInfo.h b/js/public/TrackedOptimizationInfo.h index 254236ff5a..7ec6318083 100644 --- a/js/public/TrackedOptimizationInfo.h +++ b/js/public/TrackedOptimizationInfo.h @@ -108,6 +108,7 @@ namespace JS { _(CantInlineNoBaseline) \ _(CantInlineLazy) \ _(CantInlineNotConstructor) \ + _(CantInlineClassConstructor) \ _(CantInlineDisabledIon) \ _(CantInlineTooManyArgs) \ _(CantInlineRecursive) \ diff --git a/js/public/UbiNode.h b/js/public/UbiNode.h index d3a133460e..872ebd12de 100644 --- a/js/public/UbiNode.h +++ b/js/public/UbiNode.h @@ -93,7 +93,7 @@ // represented by a "rope", a structure that points to the two original // strings. // - +// // We intend to use ubi::Node to write tools that report memory usage, so it's // important that ubi::Node accurately portray how much memory nodes consume. // Thus, for example, when data that apparently belongs to multiple nodes is @@ -142,15 +142,26 @@ namespace JS { namespace ubi { -using mozilla::Maybe; -using mozilla::UniquePtr; - class Edge; class EdgeRange; +} +} + +namespace mozilla { +template<> +class DefaultDelete : public JS::DeletePolicy { }; +} + +namespace JS { +namespace ubi { + +using mozilla::Maybe; +using mozilla::UniquePtr; + // The base class implemented by each ubi::Node referent type. Subclasses must // not add data members to this class. -class Base { +class JS_FRIEND_API(Base) { friend class Node; // For performance's sake, we'd prefer to avoid a virtual destructor; and @@ -176,6 +187,26 @@ class Base { } bool operator!=(const Base& rhs) const { return !(*this == rhs); } + // An identifier for this node, guaranteed to be stable and unique for as + // long as this ubi::Node's referent is alive and at the same address. + // + // This is probably suitable for use in serializations, as it is an integral + // type. It may also help save memory when constructing HashSets of + // ubi::Nodes: since a uintptr_t will always be smaller than a ubi::Node, a + // HashSet will use less space per element than a + // HashSet. + // + // (Note that 'unique' only means 'up to equality on ubi::Node'; see the + // caveats about multiple objects allocated at the same address for + // 'ubi::Node::operator=='.) + typedef uintptr_t Id; + virtual Id identifier() const { return reinterpret_cast(ptr); } + + // Returns true if this node is pointing to something on the live heap, as + // opposed to something from a deserialized core dump. Returns false, + // otherwise. + virtual bool isLive() const { return true; }; + // Return a human-readable name for the referent's type. The result should // be statically allocated. (You can use MOZ_UTF16("strings") for this.) // @@ -190,13 +221,11 @@ class Base { virtual size_t size(mozilla::MallocSizeOf mallocSizeof) const { return 0; } // Return an EdgeRange that initially contains all the referent's outgoing - // edges. The EdgeRange should be freed with 'js_delete'. (You could use - // ScopedDJSeletePtr to manage it.) On OOM, report an exception - // on |cx| and return nullptr. + // edges. The caller takes ownership of the EdgeRange. // // If wantNames is true, compute names for edges. Doing so can be expensive // in time and memory. - virtual EdgeRange* edges(JSContext* cx, bool wantNames) const = 0; + virtual UniquePtr edges(JSContext* cx, bool wantNames) const = 0; // Return the Zone to which this node's referent belongs, or nullptr if the // referent is not of a type allocated in SpiderMonkey Zones. @@ -238,7 +267,7 @@ class Base { // Base that represents a pointer to the referent type. It must also // include the members described here. template -struct Concrete { +struct JS_FRIEND_API(Concrete) { // The specific char16_t array returned by Concrete::typeName. static const char16_t concreteTypeName[]; @@ -257,9 +286,9 @@ struct Concrete { static void construct(void* storage, Referent* referent); }; -// A container for a Base instance; all members simply forward to the contained instance. -// This container allows us to pass ubi::Node instances by value. -class Node { +// A container for a Base instance; all members simply forward to the contained +// instance. This container allows us to pass ubi::Node instances by value. +class JS_FRIEND_API(Node) { // Storage in which we allocate Base subclasses. mozilla::AlignedStorage2 storage; Base* base() { return storage.addr(); } @@ -328,6 +357,8 @@ class Node { return base()->ptr != nullptr; } + bool isLive() const { return base()->isLive(); } + template bool is() const { return base()->typeName() == Concrete::concreteTypeName; @@ -335,12 +366,14 @@ class Node { template T* as() const { + MOZ_ASSERT(isLive()); MOZ_ASSERT(is()); return static_cast(base()->ptr); } template T* asOrNull() const { + MOZ_ASSERT(isLive()); return is() ? static_cast(base()->ptr) : nullptr; } @@ -363,10 +396,13 @@ class Node { return base()->size(mallocSizeof); } - EdgeRange* edges(JSContext* cx, bool wantNames = true) const { + UniquePtr edges(JSContext* cx, bool wantNames = true) const { return base()->edges(cx, wantNames); } + typedef Base::Id Id; + Id identifier() const { return base()->identifier(); } + // A hash policy for ubi::Nodes. // This simply uses the stock PointerHasher on the ubi::Node's pointer. // We specialize DefaultHasher below to make this the default. @@ -486,6 +522,33 @@ class SimpleEdge : public Edge { typedef mozilla::Vector SimpleEdgeVector; +// An EdgeRange concrete class that holds a pre-existing vector of +// SimpleEdges. A PreComputedEdgeRange does not take ownership of its +// SimpleEdgeVector; it is up to the PreComputedEdgeRange's consumer to manage +// that lifetime. +class PreComputedEdgeRange : public EdgeRange { + SimpleEdgeVector& edges; + size_t i; + + void settle() { + front_ = i < edges.length() ? &edges[i] : nullptr; + } + + public: + explicit PreComputedEdgeRange(JSContext* cx, SimpleEdgeVector& edges) + : edges(edges), + i(0) + { + settle(); + } + + void popFront() override { + MOZ_ASSERT(!empty()); + i++; + settle(); + } +}; + // RootList is a class that can be pointed to by a |ubi::Node|, creating a // fictional root-of-roots which has edges to every GC root in the JS @@ -515,7 +578,7 @@ typedef mozilla::Vector SimpleEdgeVector; // // ... // } -class MOZ_STACK_CLASS RootList { +class MOZ_STACK_CLASS JS_FRIEND_API(RootList) { Maybe& noGC; JSContext* cx; @@ -532,6 +595,10 @@ class MOZ_STACK_CLASS RootList { // Find only GC roots in the given Debugger object's set of debuggee zones. bool init(HandleObject debuggees); + // Returns true if the RootList has been initialized successfully, false + // otherwise. + bool initialized() { return noGC.isSome(); } + // Explicitly add the given Node as a root in this RootList. If wantNames is // true, you must pass an edgeName. The RootList does not take ownership of // edgeName. @@ -542,8 +609,8 @@ class MOZ_STACK_CLASS RootList { // Concrete classes for ubi::Node referent types. template<> -struct Concrete : public Base { - EdgeRange* edges(JSContext* cx, bool wantNames) const override; +struct JS_FRIEND_API(Concrete) : public Base { + UniquePtr edges(JSContext* cx, bool wantNames) const override; const char16_t* typeName() const override { return concreteTypeName; } protected: @@ -558,9 +625,9 @@ struct Concrete : public Base { // A reusable ubi::Concrete specialization base class for types supported by // JS_TraceChildren. template -class TracerConcrete : public Base { +class JS_FRIEND_API(TracerConcrete) : public Base { const char16_t* typeName() const override { return concreteTypeName; } - EdgeRange* edges(JSContext*, bool wantNames) const override; + UniquePtr edges(JSContext*, bool wantNames) const override; JS::Zone* zone() const override; protected: @@ -574,7 +641,7 @@ class TracerConcrete : public Base { // For JS_TraceChildren-based types that have a 'compartment' method. template -class TracerConcreteWithCompartment : public TracerConcrete { +class JS_FRIEND_API(TracerConcreteWithCompartment) : public TracerConcrete { typedef TracerConcrete TracerBase; JSCompartment* compartment() const override; @@ -594,7 +661,7 @@ template<> struct Concrete : TracerConcreteWithCompartment { // The JSObject specialization. template<> -class Concrete : public TracerConcreteWithCompartment { +class JS_FRIEND_API(Concrete) : public TracerConcreteWithCompartment { const char* jsObjectClassName() const override; bool jsObjectConstructorName(JSContext* cx, UniquePtr& outName) const override; @@ -622,10 +689,10 @@ template<> struct Concrete : TracerConcrete { // The ubi::Node null pointer. Any attempt to operate on a null ubi::Node asserts. template<> -class Concrete : public Base { +class JS_FRIEND_API(Concrete) : public Base { const char16_t* typeName() const override; size_t size(mozilla::MallocSizeOf mallocSizeOf) const override; - EdgeRange* edges(JSContext* cx, bool wantNames) const override; + UniquePtr edges(JSContext* cx, bool wantNames) const override; JS::Zone* zone() const override; JSCompartment* compartment() const override; diff --git a/js/public/UbiNodeTraverse.h b/js/public/UbiNodeTraverse.h index 363a7f6b0b..5d8650f047 100644 --- a/js/public/UbiNodeTraverse.h +++ b/js/public/UbiNodeTraverse.h @@ -120,13 +120,13 @@ struct BreadthFirst { MOZ_ASSERT(!traversalBegun); traversalBegun = true; - // While there are pending nodes, visit them, until we've found a path to the target. + // While there are pending nodes, visit them. while (!pending.empty()) { Node origin = pending.front(); pending.popFront(); // Get a range containing all origin's outgoing edges. - js::ScopedJSDeletePtr range(origin.edges(cx, wantNames)); + auto range = origin.edges(cx, wantNames); if (!range) return false; diff --git a/js/public/Utility.h b/js/public/Utility.h index ab6578cda2..10181061c2 100644 --- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -438,23 +438,11 @@ ScrambleHashCode(HashNumber h) # define STATIC_POSTCONDITION_ASSUME(COND) __attribute__((postcondition_assume(#COND))) # define STATIC_INVARIANT(COND) __attribute__((invariant(#COND))) # define STATIC_INVARIANT_ASSUME(COND) __attribute__((invariant_assume(#COND))) -# define STATIC_PASTE2(X,Y) X ## Y -# define STATIC_PASTE1(X,Y) STATIC_PASTE2(X,Y) -# define STATIC_ASSERT(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assert_static(#COND), unused)) \ - int STATIC_PASTE1(assert_static_, __COUNTER__); \ - JS_END_MACRO # define STATIC_ASSUME(COND) \ JS_BEGIN_MACRO \ __attribute__((assume_static(#COND), unused)) \ int STATIC_PASTE1(assume_static_, __COUNTER__); \ JS_END_MACRO -# define STATIC_ASSERT_RUNTIME(COND) \ - JS_BEGIN_MACRO \ - __attribute__((assert_static_runtime(#COND), unused)) \ - int STATIC_PASTE1(assert_static_runtime_, __COUNTER__); \ - JS_END_MACRO # else /* XGILL_PLUGIN */ # define STATIC_PRECONDITION(COND) /* nothing */ # define STATIC_PRECONDITION_ASSUME(COND) /* nothing */ @@ -462,9 +450,7 @@ ScrambleHashCode(HashNumber h) # define STATIC_POSTCONDITION_ASSUME(COND) /* nothing */ # define STATIC_INVARIANT(COND) /* nothing */ # define STATIC_INVARIANT_ASSUME(COND) /* nothing */ -# define STATIC_ASSERT(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO # define STATIC_ASSUME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO -# define STATIC_ASSERT_RUNTIME(COND) JS_BEGIN_MACRO /* nothing */ JS_END_MACRO # endif /* XGILL_PLUGIN */ # define STATIC_SKIP_INFERENCE STATIC_INVARIANT(skip_inference()) #endif /* HAVE_STATIC_ANNOTATIONS */ diff --git a/js/src/asmjs/AsmJSLink.cpp b/js/src/asmjs/AsmJSLink.cpp index 26f5d307fc..4252976774 100644 --- a/js/src/asmjs/AsmJSLink.cpp +++ b/js/src/asmjs/AsmJSLink.cpp @@ -598,6 +598,9 @@ DynamicallyLinkModule(JSContext* cx, const CallArgs& args, AsmJSModule& module) module.initGlobalNaN(); + // See the comment in AllocateExecutableMemory. + ExecutableAllocator::makeExecutable(module.codeBase(), module.codeBytes()); + return true; } diff --git a/js/src/asmjs/AsmJSModule.cpp b/js/src/asmjs/AsmJSModule.cpp index 1646d7a30b..2ebe8fd62e 100644 --- a/js/src/asmjs/AsmJSModule.cpp +++ b/js/src/asmjs/AsmJSModule.cpp @@ -62,11 +62,11 @@ using mozilla::Swap; static uint8_t* AllocateExecutableMemory(ExclusiveContext* cx, size_t bytes) { -#ifdef XP_WIN - unsigned permissions = PAGE_EXECUTE_READWRITE; -#else - unsigned permissions = PROT_READ | PROT_WRITE | PROT_EXEC; -#endif + // On most platforms, this will allocate RWX memory. On iOS, or when + // --non-writable-jitcode is used, this will allocate RW memory. In this + // case, DynamicallyLinkModule will reprotect the code as RX. + unsigned permissions = + ExecutableAllocator::initialProtectionFlags(ExecutableAllocator::Writable); void* p = AllocateExecutableMemory(nullptr, bytes, permissions, "asm-js-code", AsmJSPageSize); if (!p) ReportOutOfMemory(cx); @@ -295,10 +295,9 @@ AsmJSModule::finish(ExclusiveContext* cx, TokenStream& tokenStream, MacroAssembl pod.srcLength_ = endBeforeCurly - srcStart_; pod.srcLengthWithRightBrace_ = endAfterCurly - srcStart_; - // The global data section sits immediately after the executable (and - // other) data allocated by the MacroAssembler, so ensure it is - // SIMD-aligned. - pod.codeBytes_ = AlignBytes(masm.bytesNeeded(), SimdMemoryAlignment); + // Start global data on a new page so JIT code may be given independent + // protection flags. + pod.codeBytes_ = AlignBytes(masm.bytesNeeded(), AsmJSPageSize); // The entire region is allocated via mmap/VirtualAlloc which requires // units of pages. @@ -655,7 +654,7 @@ FuncCast(F* pf) static void* RedirectCall(void* fun, ABIFunctionType type) { -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR fun = Simulator::RedirectNativeFunction(fun, type); #endif return fun; @@ -938,6 +937,24 @@ AsmJSModule::restoreToInitialState(ArrayBufferObjectMaybeShared* maybePrevBuffer restoreHeapToInitialState(maybePrevBuffer); } +namespace { + +class MOZ_STACK_CLASS AutoMutateCode +{ + AutoWritableJitCode awjc_; + AutoFlushICache afc_; + + public: + AutoMutateCode(JSContext* cx, AsmJSModule& module, const char* name) + : awjc_(cx->runtime(), module.codeBase(), module.codeBytes()), + afc_(name) + { + module.setAutoFlushICacheRange(); + } +}; + +}; // anonymous namespace + bool AsmJSModule::detachHeap(JSContext* cx) { @@ -958,9 +975,7 @@ AsmJSModule::detachHeap(JSContext* cx) MOZ_ASSERT_IF(active(), activation()->exitReason() == AsmJSExit::Reason_JitFFI || activation()->exitReason() == AsmJSExit::Reason_SlowFFI); - AutoFlushICache afc("AsmJSModule::detachHeap"); - setAutoFlushICacheRange(); - + AutoMutateCode amc(cx, *this, "AsmJSModule::detachHeap"); restoreHeapToInitialState(maybeHeap_); MOZ_ASSERT(hasDetachedHeap()); @@ -1697,9 +1712,7 @@ AsmJSModule::changeHeap(Handle newHeap, JSContext* cx) if (interrupted_) return false; - AutoFlushICache afc("AsmJSModule::changeHeap"); - setAutoFlushICacheRange(); - + AutoMutateCode amc(cx, *this, "AsmJSModule::changeHeap"); restoreHeapToInitialState(maybeHeap_); initHeap(newHeap, cx); return true; @@ -1743,9 +1756,7 @@ AsmJSModule::setProfilingEnabled(JSContext* cx, bool enabled) profilingLabels_.clear(); } - // Conservatively flush the icache for the entire module. - AutoFlushICache afc("AsmJSModule::setProfilingEnabled"); - setAutoFlushICacheRange(); + AutoMutateCode amc(cx, *this, "AsmJSModule::setProfilingEnabled"); // Patch all internal (asm.js->asm.js) callsites to call the profiling // prologues: diff --git a/js/src/asmjs/AsmJSSignalHandlers.cpp b/js/src/asmjs/AsmJSSignalHandlers.cpp index 74e4353a55..8a9cc21a5d 100644 --- a/js/src/asmjs/AsmJSSignalHandlers.cpp +++ b/js/src/asmjs/AsmJSSignalHandlers.cpp @@ -1165,7 +1165,7 @@ RedirectJitCodeToInterruptCheck(JSRuntime* rt, CONTEXT* context) if (AsmJSActivation* activation = rt->asmJSActivationStack()) { const AsmJSModule& module = activation->module(); -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR if (module.containsFunctionPC((void*)rt->simulator()->get_pc())) rt->simulator()->set_resume_pc(int32_t(module.interruptExit())); #endif diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 5655c7dd4f..5eb098b365 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -104,7 +104,7 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, jsval* vp) if (!JS_SetProperty(cx, info, "x64", value)) return false; -#ifdef JS_ARM_SIMULATOR +#ifdef JS_SIMULATOR_ARM value = BooleanValue(true); #else value = BooleanValue(false); diff --git a/js/src/configure.in b/js/src/configure.in index ce5014e967..50fdd1638c 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -3084,39 +3084,53 @@ fi AC_SUBST(MOZ_VALGRIND) dnl ======================================================== -dnl = Use ARM JIT code simulator. Requires an x86 build. +dnl = Use a JIT code simulator for a foreign architecture. dnl ======================================================== -dnl Also define JS_CODEGEN_ARM in this case. If the simulator is not used, -dnl JS_CODEGEN_foo is defined if JS_CPU_foo is defined. -MOZ_ARG_ENABLE_BOOL(arm-simulator, -[ --enable-arm-simulator Enable ARM simulator for JIT code], - JS_ARM_SIMULATOR=1, - JS_ARM_SIMULATOR= ) -MOZ_ARG_ENABLE_BOOL(mips-simulator, -[ --enable-mips-simulator Enable MIPS simulator for JIT code], - JS_MIPS_SIMULATOR=1, - JS_MIPS_SIMULATOR= ) +MOZ_ARG_ENABLE_STRING(simulator, +[ --enable-simulator=ARCH + Enable a JIT code simulator for the specified arch. + (arm, arm64, mips).], + JS_SIMULATOR="$enableval") -if test -n "$JS_ARM_SIMULATOR" && test -n "$JS_MIPS_SIMULATOR"; then - AC_MSG_ERROR([Flags --enable-arm-simulator and --enable-mips-simulator cannot be used together.]) +if test -n "$JS_SIMULATOR"; then + case "$JS_SIMULATOR" in + arm|arm64|mips) ;; + no) + JS_SIMULATOR= + ;; + *) AC_MSG_ERROR([Invalid simulator. Valid simulators are: arm, arm64, mips.]) ;; + esac fi if test -z "$ENABLE_ION"; then AC_DEFINE(JS_CODEGEN_NONE) JS_CODEGEN_NONE=1 -elif test -n "$JS_ARM_SIMULATOR"; then +elif test "$JS_SIMULATOR" = arm; then if test "$CPU_ARCH" != "x86"; then AC_MSG_ERROR([The ARM simulator only works on x86.]) fi - AC_DEFINE(JS_ARM_SIMULATOR) + AC_DEFINE(JS_SIMULATOR) + AC_DEFINE(JS_SIMULATOR_ARM) AC_DEFINE(JS_CODEGEN_ARM) + JS_SIMULATOR_ARM=1 JS_CODEGEN_ARM=1 -elif test -n "$JS_MIPS_SIMULATOR"; then +elif test "$JS_SIMULATOR" = arm64; then + if test "$CPU_ARCH" != "x86_64"; then + AC_MSG_ERROR([The ARM64 simulator only works on x86_64.]) + fi + AC_DEFINE(JS_SIMULATOR) + AC_DEFINE(JS_SIMULATOR_ARM64) + AC_DEFINE(JS_CODEGEN_ARM64) + JS_SIMULATOR_ARM64=1 + JS_CODEGEN_ARM64=1 +elif test "$JS_SIMULATOR" = mips; then if test "$CPU_ARCH" != "x86"; then AC_MSG_ERROR([The MIPS simulator only works on x86.]) fi - AC_DEFINE(JS_MIPS_SIMULATOR) + AC_DEFINE(JS_SIMULATOR) + AC_DEFINE(JS_SIMULATOR_MIPS) AC_DEFINE(JS_CODEGEN_MIPS) + JS_SIMULATOR_MIPS=1 JS_CODEGEN_MIPS=1 elif test "$CPU_ARCH" = "x86"; then AC_DEFINE(JS_CODEGEN_X86) @@ -3137,9 +3151,12 @@ elif test "$CPU_ARCH" = "mips"; then JS_CODEGEN_MIPS=1 fi -AC_SUBST(JS_ARM_SIMULATOR) -AC_SUBST(JS_MIPS_SIMULATOR) +AC_SUBST(JS_SIMULATOR) +AC_SUBST(JS_SIMULATOR_ARM) +AC_SUBST(JS_SIMULATOR_ARM64) +AC_SUBST(JS_SIMULATOR_MIPS) AC_SUBST(JS_CODEGEN_ARM) +AC_SUBST(JS_CODEGEN_ARM64) AC_SUBST(JS_CODEGEN_MIPS) AC_SUBST(JS_CODEGEN_X86) AC_SUBST(JS_CODEGEN_X64) diff --git a/js/src/devtools/automation/variants/arm-sim b/js/src/devtools/automation/variants/arm-sim index 77642e5f88..42e7915504 100644 --- a/js/src/devtools/automation/variants/arm-sim +++ b/js/src/devtools/automation/variants/arm-sim @@ -2,6 +2,6 @@ --enable-debug --enable-stdcxx-compat --disable-shared-js ---enable-arm-simulator +--enable-simulator=arm --target=i686-pc-linux --host=i686-pc-linux diff --git a/js/src/devtools/automation/variants/arm-sim-osx b/js/src/devtools/automation/variants/arm-sim-osx index 3427650b03..3063d8bdfc 100644 --- a/js/src/devtools/automation/variants/arm-sim-osx +++ b/js/src/devtools/automation/variants/arm-sim-osx @@ -2,6 +2,6 @@ --enable-debug --enable-stdcxx-compat --disable-shared-js ---enable-arm-simulator +--enable-simulator=arm --target=i686-apple-darwin10.0.0 --host=i686-apple-darwin10.0.0 diff --git a/js/src/devtools/rootAnalysis/annotations.js b/js/src/devtools/rootAnalysis/annotations.js index 8f7c3b9b54..c010077fbf 100644 --- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -13,7 +13,7 @@ var ignoreIndirectCalls = { "__conv" : true, "__convf" : true, "prerrortable.c:callback_newtable" : true, - "mozalloc_oom.cpp:void (* gAbortHandler)(size_t)" : true + "mozalloc_oom.cpp:void (* gAbortHandler)(size_t)" : true, }; function indirectCallCannotGC(fullCaller, fullVariable) @@ -180,8 +180,34 @@ var ignoreFunctions = { // analysis think maybe they can. "nsGlobalNameStruct* nsScriptNameSpaceManager::LookupNavigatorName(nsAString_internal*)": true, "nsGlobalNameStruct* nsScriptNameSpaceManager::LookupName(nsAString_internal*, uint16**)": true, + + // Similar to heap snapshot mock classes, and GTests below. This posts a + // synchronous runnable when a GTest fails, and we are pretty sure that the + // particular runnable it posts can't even GC, but the analysis isn't + // currently smart enough to determine that. In either case, this is (a) + // only in GTests, and (b) only when the Gtest has already failed. We have + // static and dynamic checks for no GC in the non-test code, and in the test + // code we fall back to only the dynamic checks. + "void test::RingbufferDumper::OnTestPartResult(testing::TestPartResult*)" : true, }; +function isProtobuf(name) +{ + return name.match(/\bgoogle::protobuf\b/) || + name.match(/\bmozilla::devtools::protobuf\b/); +} + +function isHeapSnapshotMockClass(name) +{ + return name.match(/\bMockWriter\b/) || + name.match(/\bMockDeserializedNode\b/); +} + +function isGTest(name) +{ + return name.match(/\btesting::/); +} + function ignoreGCFunction(mangled) { assert(mangled in readableNames); @@ -190,6 +216,23 @@ function ignoreGCFunction(mangled) if (fun in ignoreFunctions) return true; + // The protobuf library, and [de]serialization code generated by the + // protobuf compiler, uses a _ton_ of function pointers but they are all + // internal. Easiest to just ignore that mess here. + if (isProtobuf(fun)) + return true; + + // Ignore anything that goes through heap snapshot GTests or mocked classes + // used in heap snapshot GTests. GTest and GMock expose a lot of virtual + // methods and function pointers that could potentially GC after an + // assertion has already failed (depending on user-provided code), but don't + // exhibit that behavior currently. For non-test code, we have dynamic and + // static checks that ensure we don't GC. However, for test code we opt out + // of static checks here, because of the above stated GMock/GTest issues, + // and rely on only the dynamic checks provided by AutoAssertCannotGC. + if (isHeapSnapshotMockClass(fun) || isGTest(fun)) + return true; + // Templatized function if (fun.indexOf("void nsCOMPtr::Assert_NoQueryNeeded()") >= 0) return true; diff --git a/js/src/gc/Barrier.cpp b/js/src/gc/Barrier.cpp index d5a785e2ff..6b518ea2a4 100644 --- a/js/src/gc/Barrier.cpp +++ b/js/src/gc/Barrier.cpp @@ -44,6 +44,12 @@ js::CurrentThreadIsIonCompiling() return TlsPerThreadData.get()->ionCompiling; } +bool +js::CurrentThreadIsIonCompilingSafeForMinorGC() +{ + return TlsPerThreadData.get()->ionCompilingSafeForMinorGC; +} + bool js::CurrentThreadIsGCSweeping() { diff --git a/js/src/gc/Barrier.h b/js/src/gc/Barrier.h index d78eadbdf3..c2a517f383 100644 --- a/js/src/gc/Barrier.h +++ b/js/src/gc/Barrier.h @@ -193,6 +193,9 @@ class JitCode; bool CurrentThreadIsIonCompiling(); +bool +CurrentThreadIsIonCompilingSafeForMinorGC(); + bool CurrentThreadIsGCSweeping(); @@ -819,20 +822,6 @@ class HeapSlotArray } }; -/* - * Operations on a Heap thing inside the GC need to strip the barriers from - * pointer operations. This template helps do that in contexts where the type - * is templatized. - */ -template struct Unbarriered {}; -template struct Unbarriered< PreBarriered > { typedef S* type; }; -template struct Unbarriered< RelocatablePtr > { typedef S* type; }; -template <> struct Unbarriered { typedef Value type; }; -template <> struct Unbarriered { typedef Value type; }; -template struct Unbarriered< DefaultHasher< PreBarriered > > { - typedef DefaultHasher type; -}; - } /* namespace js */ #endif /* gc_Barrier_h */ diff --git a/js/src/gc/Heap.h b/js/src/gc/Heap.h index 0758584cee..540e43053c 100644 --- a/js/src/gc/Heap.h +++ b/js/src/gc/Heap.h @@ -1430,6 +1430,9 @@ TenuredCell::readBarrier(TenuredCell* thing) { MOZ_ASSERT(!CurrentThreadIsIonCompiling()); MOZ_ASSERT(!isNullLike(thing)); + if (thing->shadowRuntimeFromAnyThread()->isHeapBusy()) + return; + JS::shadow::Zone* shadowZone = thing->shadowZoneFromAnyThread(); if (shadowZone->needsIncrementalBarrier()) { MOZ_ASSERT(!RuntimeFromMainThreadIsHeapMajorCollecting(shadowZone)); @@ -1445,7 +1448,7 @@ TenuredCell::readBarrier(TenuredCell* thing) TenuredCell::writeBarrierPre(TenuredCell* thing) { MOZ_ASSERT(!CurrentThreadIsIonCompiling()); - if (isNullLike(thing) || !thing->shadowRuntimeFromAnyThread()->needsIncrementalBarrier()) + if (isNullLike(thing) || thing->shadowRuntimeFromAnyThread()->isHeapBusy()) return; JS::shadow::Zone* shadowZone = thing->shadowZoneFromAnyThread(); diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index 8577bf843e..6285493245 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -1820,8 +1820,12 @@ js::gc::StoreBuffer::WholeCellEdges::trace(TenuringTracer& mover) const return; } - MOZ_ASSERT(kind == JS::TraceKind::JitCode); - static_cast(edge)->traceChildren(&mover); + if (kind == JS::TraceKind::Script) + static_cast(edge)->traceChildren(&mover); + else if (kind == JS::TraceKind::JitCode) + static_cast(edge)->traceChildren(&mover); + else + MOZ_CRASH(); } void @@ -1883,11 +1887,11 @@ js::Nursery::collectToFixedPoint(TenuringTracer& mover, TenureCountCache& tenure JSObject* obj = static_cast(p->forwardingAddress()); mover.traceObject(obj); - TenureCount& entry = tenureCounts.findEntry(obj->group()); - if (entry.group == obj->group()) { + TenureCount& entry = tenureCounts.findEntry(obj->groupRaw()); + if (entry.group == obj->groupRaw()) { entry.count++; } else if (!entry.group) { - entry.group = obj->group(); + entry.group = obj->groupRaw(); entry.count = 1; } } @@ -2420,11 +2424,7 @@ js::UnmarkGrayCellRecursively(gc::Cell* cell, JS::TraceKind kind) MOZ_ASSERT(cell); JSRuntime* rt = cell->runtimeFromMainThread(); - - // When the ReadBarriered type is used in a HashTable, it is difficult or - // impossible to suppress the implicit cast operator while iterating for GC. - if (rt->isHeapBusy()) - return false; + MOZ_ASSERT(!rt->isHeapBusy()); bool unmarkedArg = false; if (cell->isTenured()) { diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index 8284426dfd..389854f236 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -423,6 +423,14 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList TenuringTracer mover(rt, this); // Mark the store buffer. This must happen first. + + TIME_START(cancelIonCompilations); + if (sb.cancelIonCompilations()) { + for (CompartmentsIter c(rt, SkipAtoms); !c.done(); c.next()) + jit::StopAllOffThreadCompilations(c); + } + TIME_END(cancelIonCompilations); + TIME_START(traceValues); sb.traceValues(mover); TIME_END(traceValues); @@ -553,11 +561,12 @@ js::Nursery::collect(JSRuntime* rt, JS::gcreason::Reason reason, ObjectGroupList #define FMT " %6" PRIu64 fprintf(stderr, - "MinorGC: %20s %5.1f%% %4d" FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT "\n", + "MinorGC: %20s %5.1f%% %4d" FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT FMT "\n", js::gcstats::ExplainReason(reason), promotionRate * 100, numActiveChunks_, totalTime, + TIME_TOTAL(cancelIonCompilations), TIME_TOTAL(traceValues), TIME_TOTAL(traceCells), TIME_TOTAL(traceSlots), diff --git a/js/src/gc/StoreBuffer.cpp b/js/src/gc/StoreBuffer.cpp index eac72a9e32..0a44108f9a 100644 --- a/js/src/gc/StoreBuffer.cpp +++ b/js/src/gc/StoreBuffer.cpp @@ -73,6 +73,7 @@ StoreBuffer::clear() return true; aboutToOverflow_ = false; + cancelIonCompilations_ = false; bufferVal.clear(); bufferCell.clear(); diff --git a/js/src/gc/StoreBuffer.h b/js/src/gc/StoreBuffer.h index cee5949d11..9f2b5fe06b 100644 --- a/js/src/gc/StoreBuffer.h +++ b/js/src/gc/StoreBuffer.h @@ -332,6 +332,8 @@ class StoreBuffer }; bool isOkayToUseBuffer() const { + MOZ_ASSERT(!JS::shadow::Runtime::asShadowRuntime(runtime_)->isHeapBusy()); + /* * Disabled store buffers may not have a valid state; e.g. when stored * inline in the ChunkTrailer. @@ -383,6 +385,7 @@ class StoreBuffer MonoTypeBuffer bufferRelocVal; MonoTypeBuffer bufferRelocCell; GenericBuffer bufferGeneric; + bool cancelIonCompilations_; JSRuntime* runtime_; const Nursery& nursery_; @@ -394,7 +397,7 @@ class StoreBuffer public: explicit StoreBuffer(JSRuntime* rt, const Nursery& nursery) : bufferVal(), bufferCell(), bufferSlot(), bufferWholeCell(), - bufferRelocVal(), bufferRelocCell(), bufferGeneric(), + bufferRelocVal(), bufferRelocCell(), bufferGeneric(), cancelIonCompilations_(false), runtime_(rt), nursery_(nursery), aboutToOverflow_(false), enabled_(false), mEntered(false) { @@ -409,6 +412,8 @@ class StoreBuffer /* Get the overflowed status. */ bool isAboutToOverflow() const { return aboutToOverflow_; } + bool cancelIonCompilations() const { return cancelIonCompilations_; } + /* Insert a single edge into the buffer/remembered set. */ void putValueFromAnyThread(JS::Value* valuep) { putFromAnyThread(bufferVal, ValueEdge(valuep)); } void putCellFromAnyThread(Cell** cellp) { putFromAnyThread(bufferCell, CellPtrEdge(cellp)); } @@ -444,6 +449,10 @@ class StoreBuffer putFromAnyThread(bufferGeneric, CallbackRef(callback, key, data)); } + void setShouldCancelIonCompilations() { + cancelIonCompilations_ = true; + } + /* Methods to trace the source of all edges in the store buffer. */ void traceValues(TenuringTracer& mover) { bufferVal.trace(this, mover); } void traceCells(TenuringTracer& mover) { bufferCell.trace(this, mover); } diff --git a/js/src/irregexp/NativeRegExpMacroAssembler.cpp b/js/src/irregexp/NativeRegExpMacroAssembler.cpp index 0dac67511c..aae64c56bd 100644 --- a/js/src/irregexp/NativeRegExpMacroAssembler.cpp +++ b/js/src/irregexp/NativeRegExpMacroAssembler.cpp @@ -442,6 +442,8 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only) writePerfSpewerJitCodeProfile(code, "RegExp"); #endif + AutoWritableJitCode awjc(code); + for (size_t i = 0; i < labelPatches.length(); i++) { LabelPatch& v = labelPatches[i]; MOZ_ASSERT(!v.label); diff --git a/js/src/jit-test/tests/baseline/classConstructor-AnyScripted.js b/js/src/jit-test/tests/baseline/classConstructor-AnyScripted.js new file mode 100644 index 0000000000..976dc7f9f4 --- /dev/null +++ b/js/src/jit-test/tests/baseline/classConstructor-AnyScripted.js @@ -0,0 +1,30 @@ +load(libdir + "class.js"); + +var test = ` + +function test(fun) { + fun(); +} + +// Generate a CallAnyScripted stub in test() +for (let i = 0; i < 20; i++) { + test(function() { /* wheeee */ }); +} + +class foo { + constructor() { } +} + +// Compile foo() +for (let i = 0; i < 11; i++) + new foo(); + +try { + test(foo); + throw new Error("Invoking a class constructor without new must throw"); +} catch (e if e instanceof TypeError) { } + +`; + +if (classesEnabled()) + eval(test); diff --git a/js/src/jit-test/tests/ion/bug1151323.js b/js/src/jit-test/tests/ion/bug1151323.js new file mode 100644 index 0000000000..f4c3ecf20c --- /dev/null +++ b/js/src/jit-test/tests/ion/bug1151323.js @@ -0,0 +1,8 @@ + +function map_test(cases) { + for (var i = 0; i < cases.length; i++) { + var expected = cases[i].expected; + } +} +map_test([{ input: 8, expected: 1114369}, { input: -1, expected: 0}]); +map_test([{ expected: 16777215}, { expected: 4294967241 }]); diff --git a/js/src/jit/BaselineBailouts.cpp b/js/src/jit/BaselineBailouts.cpp index 718c9c7a32..b69e880cd9 100644 --- a/js/src/jit/BaselineBailouts.cpp +++ b/js/src/jit/BaselineBailouts.cpp @@ -1572,7 +1572,7 @@ jit::BailoutIonToBaseline(JSContext* cx, JitActivation* activation, JitFrameIter bool overRecursed = false; BaselineBailoutInfo *info = builder.info(); uint8_t* newsp = info->incomingStack - (info->copyStackTop - info->copyStackBottom); -#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR if (Simulator::Current()->overRecursed(uintptr_t(newsp))) overRecursed = true; #else diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 624a36bbe3..60d58fbde0 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -226,7 +226,17 @@ BaselineCompiler::compile() // Adopt fallback stubs from the compiler into the baseline script. baselineScript->adoptFallbackStubs(&stubSpace_); - // Patch IC loads using IC entries + // All barriers are emitted off-by-default, toggle them on if needed. + if (cx->zone()->needsIncrementalBarrier()) + baselineScript->toggleBarriers(true); + + // If profiler instrumentation is enabled, toggle instrumentation on. + if (cx->runtime()->jitRuntime()->isProfilerInstrumentationEnabled(cx->runtime())) + baselineScript->toggleProfilerInstrumentation(true); + + AutoWritableJitCode awjc(code); + + // Patch IC loads using IC entries. for (size_t i = 0; i < icLoadLabels_.length(); i++) { CodeOffsetLabel label = icLoadLabels_[i].label; label.fixup(&masm); @@ -240,10 +250,6 @@ BaselineCompiler::compile() if (modifiesArguments_) baselineScript->setModifiesArguments(); - // All barriers are emitted off-by-default, toggle them on if needed. - if (cx->zone()->needsIncrementalBarrier()) - baselineScript->toggleBarriers(true); - #ifdef JS_TRACE_LOGGING // Initialize the tracelogger instrumentation. baselineScript->initTraceLogger(cx->runtime(), script); @@ -261,10 +267,6 @@ BaselineCompiler::compile() if (compileDebugInstrumentation_) baselineScript->setHasDebugInstrumentation(); - // If profiler instrumentation is enabled, toggle instrumentation on. - if (cx->runtime()->jitRuntime()->isProfilerInstrumentationEnabled(cx->runtime())) - baselineScript->toggleProfilerInstrumentation(true); - // Always register a native => bytecode mapping entry, since profiler can be // turned on with baseline jitcode on stack, and baseline jitcode cannot be invalidated. { diff --git a/js/src/jit/BaselineIC.cpp b/js/src/jit/BaselineIC.cpp index f3074e8d9b..e3ff7a024b 100644 --- a/js/src/jit/BaselineIC.cpp +++ b/js/src/jit/BaselineIC.cpp @@ -9736,6 +9736,10 @@ TryAttachCallStub(JSContext* cx, ICCall_Fallback* stub, HandleScript script, jsb if (constructing && !fun->isConstructor()) return true; + // Likewise, if the callee is a class constructor, we have to throw. + if (!constructing && fun->isClassConstructor()) + return true; + if (!fun->hasJITCode()) { // Don't treat this as an unoptimizable case, as we'll add a stub // when the callee becomes hot. @@ -10600,10 +10604,13 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler& masm) // Ensure the object is a function. masm.branchTestObjClass(Assembler::NotEqual, callee, regs.getAny(), &JSFunction::class_, &failure); - if (isConstructing_) + if (isConstructing_) { masm.branchIfNotInterpretedConstructor(callee, regs.getAny(), &failure); - else + } else { masm.branchIfFunctionHasNoScript(callee, &failure); + masm.branchFunctionKind(Assembler::Equal, JSFunction::ClassConstructor, callee, + regs.getAny(), &failure); + } } // Load the JSScript. @@ -11043,7 +11050,7 @@ ICCall_Native::Compiler::generateStubCode(MacroAssembler& masm) masm.passABIArg(argcReg); masm.passABIArg(vpReg); -#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR // The simulator requires VM calls to be redirected to a special swi // instruction to handle them, so we store the redirected pointer in the // stub and use that instead of the original one. @@ -12681,7 +12688,7 @@ ICCall_Native::ICCall_Native(JitCode* stubCode, ICStub* firstMonitorStub, templateObject_(templateObject), pcOffset_(pcOffset) { -#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR // The simulator requires VM calls to be redirected to a special swi // instruction to handle them. To make this work, we store the redirected // pointer in the stub. @@ -12707,7 +12714,7 @@ ICCall_ClassHook::ICCall_ClassHook(JitCode* stubCode, ICStub* firstMonitorStub, templateObject_(templateObject), pcOffset_(pcOffset) { -#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR // The simulator requires VM calls to be redirected to a special swi // instruction to handle them. To make this work, we store the redirected // pointer in the stub. diff --git a/js/src/jit/BaselineIC.h b/js/src/jit/BaselineIC.h index ede92e365f..d1079a5a1f 100644 --- a/js/src/jit/BaselineIC.h +++ b/js/src/jit/BaselineIC.h @@ -4721,7 +4721,7 @@ class ICCall_Native : public ICMonitoredStub HeapPtrObject templateObject_; uint32_t pcOffset_; -#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR void *native_; #endif @@ -4747,7 +4747,7 @@ class ICCall_Native : public ICMonitoredStub return offsetof(ICCall_Native, pcOffset_); } -#if defined(JS_ARM_SIMULATOR) || defined(JS_ARM64_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR static size_t offsetOfNative() { return offsetof(ICCall_Native, native_); } diff --git a/js/src/jit/BaselineJIT.cpp b/js/src/jit/BaselineJIT.cpp index 12581b1134..d9bf5f6481 100644 --- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -859,6 +859,8 @@ BaselineScript::toggleDebugTraps(JSScript* script, jsbytecode* pc) SrcNoteLineScanner scanner(script->notes(), script->lineno()); + AutoWritableJitCode awjc(method()); + for (uint32_t i = 0; i < numPCMappingIndexEntries(); i++) { PCMappingIndexEntry& entry = pcMappingIndexEntry(i); @@ -905,6 +907,7 @@ BaselineScript::initTraceLogger(JSRuntime* runtime, JSScript* script) traceLoggerScriptEvent_ = TraceLoggerEvent(logger, TraceLogger_Scripts); if (TraceLogTextIdEnabled(TraceLogger_Engine) || TraceLogTextIdEnabled(TraceLogger_Scripts)) { + AutoWritableJitCode awjc(method_); CodeLocationLabel enter(method_, CodeOffsetLabel(traceLoggerEnterToggleOffset_)); CodeLocationLabel exit(method_, CodeOffsetLabel(traceLoggerExitToggleOffset_)); Assembler::ToggleToCmp(enter); @@ -928,6 +931,8 @@ BaselineScript::toggleTraceLoggerScripts(JSRuntime* runtime, JSScript* script, b else traceLoggerScriptEvent_ = TraceLoggerEvent(logger, TraceLogger_Scripts); + AutoWritableJitCode awjc(method()); + // Enable/Disable the traceLogger prologue and epilogue. CodeLocationLabel enter(method_, CodeOffsetLabel(traceLoggerEnterToggleOffset_)); CodeLocationLabel exit(method_, CodeOffsetLabel(traceLoggerExitToggleOffset_)); @@ -954,6 +959,8 @@ BaselineScript::toggleTraceLoggerEngine(bool enable) MOZ_ASSERT(enable == !traceLoggerEngineEnabled_); MOZ_ASSERT(scriptsEnabled == traceLoggerScriptsEnabled_); + AutoWritableJitCode awjc(method()); + // Enable/Disable the traceLogger prologue and epilogue. CodeLocationLabel enter(method_, CodeOffsetLabel(traceLoggerEnterToggleOffset_)); CodeLocationLabel exit(method_, CodeOffsetLabel(traceLoggerExitToggleOffset_)); @@ -982,6 +989,8 @@ BaselineScript::toggleProfilerInstrumentation(bool enable) JitSpew(JitSpew_BaselineIC, " toggling profiling %s for BaselineScript %p", enable ? "on" : "off", this); + AutoWritableJitCode awjc(method()); + // Toggle the jump CodeLocationLabel enterToggleLocation(method_, CodeOffsetLabel(profilerEnterToggleOffset_)); CodeLocationLabel exitToggleLocation(method_, CodeOffsetLabel(profilerExitToggleOffset_)); diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp index d2d1b00809..ebf47f18bf 100644 --- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -2235,19 +2235,6 @@ CodeGenerator::visitPointer(LPointer* lir) masm.movePtr(ImmPtr(lir->ptr()), ToRegister(lir->output())); } -void -CodeGenerator::visitNurseryObject(LNurseryObject* lir) -{ - Register output = ToRegister(lir->output()); - uint32_t index = lir->mir()->index(); - - // Store a dummy JSObject pointer. We will fix it up on the main thread, - // in JitCode::fixupNurseryObjects. The low bit is set to distinguish - // it from a real JSObject pointer. - JSObject* ptr = reinterpret_cast((uintptr_t(index) << 1) | 1); - masm.movePtr(ImmGCPtr(IonNurseryPtr(ptr)), output); -} - void CodeGenerator::visitKeepAliveObject(LKeepAliveObject* lir) { @@ -3041,10 +3028,12 @@ CodeGenerator::visitCallGeneric(LCallGeneric* call) // Guard that calleereg is an interpreted function with a JSScript. // If we are constructing, also ensure the callee is a constructor. - if (call->mir()->isConstructing()) + if (call->mir()->isConstructing()) { masm.branchIfNotInterpretedConstructor(calleereg, nargsreg, &invoke); - else + } else { masm.branchIfFunctionHasNoScript(calleereg, &invoke); + masm.branchFunctionKind(Assembler::Equal, JSFunction::ClassConstructor, calleereg, objreg, &invoke); + } // Knowing that calleereg is a non-native function, load the JSScript. masm.loadPtr(Address(calleereg, JSFunction::offsetOfNativeOrScript()), objreg); @@ -3138,6 +3127,7 @@ CodeGenerator::visitCallKnown(LCallKnown* call) // Native single targets are handled by LCallNative. MOZ_ASSERT(!target->isNative()); + MOZ_ASSERT_IF(target->isClassConstructor(), call->isConstructing()); // Missing arguments must have been explicitly appended by the IonBuilder. DebugOnly numNonArgsOnStack = 1 + call->isConstructing(); MOZ_ASSERT(target->nargs() <= call->mir()->numStackArgs() - numNonArgsOnStack); @@ -3576,11 +3566,16 @@ CodeGenerator::generateArgumentsChecks(bool bailout) // Check for cases where the type set guard might have missed due to // changing object groups. for (uint32_t i = info.startArgSlot(); i < info.endArgSlot(); i++) { + MParameter* param = rp->getOperand(i)->toParameter(); + const TemporaryTypeSet* types = param->resultTypeSet(); + if (!types || types->unknown()) + continue; + Label skip; Address addr(StackPointer, ArgToStackOffset((i - info.startArgSlot()) * sizeof(Value))); masm.branchTestObject(Assembler::NotEqual, addr, &skip); Register obj = masm.extractObject(addr, temp); - masm.guardTypeSetMightBeIncomplete(obj, temp, &success); + masm.guardTypeSetMightBeIncomplete(types, obj, temp, &success); masm.bind(&skip); } @@ -3810,7 +3805,7 @@ CodeGenerator::branchIfInvalidated(Register temp, Label* invalidated) } void -CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, TemporaryTypeSet* typeset) +CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset) { MOZ_ASSERT(type == MIRType_Object || type == MIRType_ObjectOrNull || type == MIRType_String || type == MIRType_Symbol); @@ -3840,7 +3835,7 @@ CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, Temp masm.jump(&ok); masm.bind(&miss); - masm.guardTypeSetMightBeIncomplete(input, temp, &ok); + masm.guardTypeSetMightBeIncomplete(typeset, input, temp, &ok); masm.assumeUnreachable("MIR instruction returned object with unexpected type"); @@ -3880,7 +3875,7 @@ CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, Temp } void -CodeGenerator::emitAssertResultV(const ValueOperand input, TemporaryTypeSet* typeset) +CodeGenerator::emitAssertResultV(const ValueOperand input, const TemporaryTypeSet* typeset) { AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); regs.take(input); @@ -3908,7 +3903,7 @@ CodeGenerator::emitAssertResultV(const ValueOperand input, TemporaryTypeSet* typ Label realMiss; masm.branchTestObject(Assembler::NotEqual, input, &realMiss); Register payload = masm.extractObject(input, temp1); - masm.guardTypeSetMightBeIncomplete(payload, temp1, &ok); + masm.guardTypeSetMightBeIncomplete(typeset, payload, temp1, &ok); masm.bind(&realMiss); masm.assumeUnreachable("MIR instruction returned value with unexpected type"); @@ -7957,10 +7952,43 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints) script->setIonScript(cx, ionScript); - invalidateEpilogueData_.fixup(&masm); - Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, invalidateEpilogueData_), - ImmPtr(ionScript), - ImmPtr((void*)-1)); + { + AutoWritableJitCode awjc(code); + invalidateEpilogueData_.fixup(&masm); + Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, invalidateEpilogueData_), + ImmPtr(ionScript), + ImmPtr((void*)-1)); + + for (size_t i = 0; i < ionScriptLabels_.length(); i++) { + ionScriptLabels_[i].fixup(&masm); + Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, ionScriptLabels_[i]), + ImmPtr(ionScript), + ImmPtr((void*)-1)); + } + +#ifdef JS_TRACE_LOGGING + TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime()); + for (uint32_t i = 0; i < patchableTraceLoggers_.length(); i++) { + patchableTraceLoggers_[i].fixup(&masm); + Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, patchableTraceLoggers_[i]), + ImmPtr(logger), + ImmPtr(nullptr)); + } + + if (patchableTLScripts_.length() > 0) { + MOZ_ASSERT(TraceLogTextIdEnabled(TraceLogger_Scripts)); + TraceLoggerEvent event(logger, TraceLogger_Scripts, script); + ionScript->setTraceLoggerEvent(event); + uint32_t textId = event.payload()->textId(); + for (uint32_t i = 0; i < patchableTLScripts_.length(); i++) { + patchableTLScripts_[i].fixup(&masm); + Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, patchableTLScripts_[i]), + ImmPtr((void*) uintptr_t(textId)), + ImmPtr((void*)0)); + } + } +#endif + } JitSpew(JitSpew_Codegen, "Created IonScript %p (raw %p)", (void*) ionScript, (void*) code->raw()); @@ -7978,13 +8006,6 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints) perfSpewer_.writeProfile(script, code, masm); #endif - for (size_t i = 0; i < ionScriptLabels_.length(); i++) { - ionScriptLabels_[i].fixup(&masm); - Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, ionScriptLabels_[i]), - ImmPtr(ionScript), - ImmPtr((void*)-1)); - } - // for generating inline caches during the execution. if (runtimeData_.length()) ionScript->copyRuntimeData(&runtimeData_[0]); @@ -8007,36 +8028,19 @@ CodeGenerator::link(JSContext* cx, CompilerConstraintList* constraints) MOZ_ASSERT_IF(snapshots_.listSize(), recovers_.size()); if (recovers_.size()) ionScript->copyRecovers(&recovers_); - if (graph.numConstants()) - ionScript->copyConstants(graph.constantPool()); - if (patchableBackedges_.length() > 0) - ionScript->copyPatchableBackedges(cx, code, patchableBackedges_.begin(), masm); - -#ifdef JS_TRACE_LOGGING - TraceLoggerThread* logger = TraceLoggerForMainThread(cx->runtime()); - for (uint32_t i = 0; i < patchableTraceLoggers_.length(); i++) { - patchableTraceLoggers_[i].fixup(&masm); - Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, patchableTraceLoggers_[i]), - ImmPtr(logger), - ImmPtr(nullptr)); - } - - if (patchableTLScripts_.length() > 0) { - MOZ_ASSERT(TraceLogTextIdEnabled(TraceLogger_Scripts)); - TraceLoggerEvent event(logger, TraceLogger_Scripts, script); - ionScript->setTraceLoggerEvent(event); - uint32_t textId = event.payload()->textId(); - for (uint32_t i = 0; i < patchableTLScripts_.length(); i++) { - patchableTLScripts_[i].fixup(&masm); - Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, patchableTLScripts_[i]), - ImmPtr((void*) uintptr_t(textId)), - ImmPtr((void*)0)); + if (graph.numConstants()) { + const Value* vp = graph.constantPool(); + ionScript->copyConstants(vp); + for (size_t i = 0; i < graph.numConstants(); i++) { + const Value& v = vp[i]; + if (v.isObject() && IsInsideNursery(&v.toObject())) { + cx->runtime()->gc.storeBuffer.putWholeCellFromMainThread(script); + break; + } } } -#endif - - // Replace dummy JSObject pointers embedded by LNurseryObject. - code->fixupNurseryObjects(cx, gen->nurseryObjects()); + if (patchableBackedges_.length() > 0) + ionScript->copyPatchableBackedges(cx, code, patchableBackedges_.begin(), masm); // The correct state for prebarriers is unknown until the end of compilation, // since a GC can occur during code generation. All barriers are emitted diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h index 3ff1718ca8..9bf490a06e 100644 --- a/js/src/jit/CodeGenerator.h +++ b/js/src/jit/CodeGenerator.h @@ -109,7 +109,6 @@ class CodeGenerator : public CodeGeneratorSpecific void visitLambdaArrow(LLambdaArrow* lir); void visitLambdaForSingleton(LLambdaForSingleton* lir); void visitPointer(LPointer* lir); - void visitNurseryObject(LNurseryObject* lir); void visitKeepAliveObject(LKeepAliveObject* lir); void visitSlots(LSlots* lir); void visitLoadSlotT(LLoadSlotT* lir); @@ -369,8 +368,8 @@ class CodeGenerator : public CodeGeneratorSpecific void visitAssertResultV(LAssertResultV* ins); void visitAssertResultT(LAssertResultT* ins); - void emitAssertResultV(const ValueOperand output, TemporaryTypeSet* typeset); - void emitAssertObjectOrStringResult(Register input, MIRType type, TemporaryTypeSet* typeset); + void emitAssertResultV(const ValueOperand output, const TemporaryTypeSet* typeset); + void emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset); void visitInterruptCheck(LInterruptCheck* lir); void visitAsmJSInterruptCheck(LAsmJSInterruptCheck* lir); diff --git a/js/src/jit/CompileWrappers.cpp b/js/src/jit/CompileWrappers.cpp index ff8e2afce9..f0ab604347 100644 --- a/js/src/jit/CompileWrappers.cpp +++ b/js/src/jit/CompileWrappers.cpp @@ -189,6 +189,13 @@ CompileRuntime::gcNursery() return runtime()->gc.nursery; } +void +CompileRuntime::setMinorGCShouldCancelIonCompilations() +{ + MOZ_ASSERT(onMainThread()); + runtime()->gc.storeBuffer.setShouldCancelIonCompilations(); +} + Zone* CompileZone::zone() { diff --git a/js/src/jit/CompileWrappers.h b/js/src/jit/CompileWrappers.h index 3d47881d6c..9777a03fea 100644 --- a/js/src/jit/CompileWrappers.h +++ b/js/src/jit/CompileWrappers.h @@ -85,6 +85,7 @@ class CompileRuntime const MathCache* maybeGetMathCache(); const Nursery& gcNursery(); + void setMinorGCShouldCancelIonCompilations(); }; class CompileZone diff --git a/js/src/jit/ExecutableAllocator.cpp b/js/src/jit/ExecutableAllocator.cpp index 036d04472e..3de8e6b4a6 100644 --- a/js/src/jit/ExecutableAllocator.cpp +++ b/js/src/jit/ExecutableAllocator.cpp @@ -29,6 +29,10 @@ #include "js/MemoryMetrics.h" +#ifdef __APPLE__ +#include +#endif + using namespace js::jit; size_t ExecutableAllocator::pageSize = 0; @@ -62,3 +66,8 @@ ExecutableAllocator::addSizeOfCode(JS::CodeSizes* sizes) const } } +#if TARGET_OS_IPHONE +bool ExecutableAllocator::nonWritableJitCode = true; +#else +bool ExecutableAllocator::nonWritableJitCode = false; +#endif diff --git a/js/src/jit/ExecutableAllocator.h b/js/src/jit/ExecutableAllocator.h index 167de49382..75ff7809d9 100644 --- a/js/src/jit/ExecutableAllocator.h +++ b/js/src/jit/ExecutableAllocator.h @@ -1,4 +1,6 @@ -/* +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * * Copyright (C) 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,18 +55,10 @@ extern "C" void sync_instruction_memory(caddr_t v, u_int len); #endif #endif -#if defined(JS_CODEGEN_MIPS) && defined(__linux__) && !defined(JS_MIPS_SIMULATOR) +#if defined(JS_CODEGEN_MIPS) && defined(__linux__) && !defined(JS_SIMULATOR_MIPS) #include #endif -#if ENABLE_ASSEMBLER_WX_EXCLUSIVE -#define PROTECTION_FLAGS_RW (PROT_READ | PROT_WRITE) -#define PROTECTION_FLAGS_RX (PROT_READ | PROT_EXEC) -#define INITIAL_PROTECTION_FLAGS PROTECTION_FLAGS_RX -#else -#define INITIAL_PROTECTION_FLAGS (PROT_READ | PROT_WRITE | PROT_EXEC) -#endif - namespace JS { struct CodeSizes; } // namespace JS @@ -177,12 +171,14 @@ namespace jit { } }; -class ExecutableAllocator { +class ExecutableAllocator +{ typedef void (*DestroyCallback)(void* addr, size_t size); - enum ProtectionSetting { Writable, Executable }; DestroyCallback destroyCallback; public: + enum ProtectionSetting { Writable, Executable }; + ExecutableAllocator() : destroyCallback(nullptr) { @@ -267,6 +263,8 @@ class ExecutableAllocator { this->destroyCallback = destroyCallback; } + static bool nonWritableJitCode; + private: static size_t pageSize; static size_t largeAllocSize; @@ -380,27 +378,25 @@ class ExecutableAllocator { return pool; } -#if ENABLE_ASSEMBLER_WX_EXCLUSIVE static void makeWritable(void* start, size_t size) { - reprotectRegion(start, size, Writable); + if (nonWritableJitCode) + reprotectRegion(start, size, Writable); } static void makeExecutable(void* start, size_t size) { - reprotectRegion(start, size, Executable); + if (nonWritableJitCode) + reprotectRegion(start, size, Executable); } -#else - static void makeWritable(void*, size_t) {} - static void makeExecutable(void*, size_t) {} -#endif + static unsigned initialProtectionFlags(ProtectionSetting protection); #if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) static void cacheFlush(void*, size_t) { } -#elif defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#elif defined(JS_SIMULATOR_ARM) || defined(JS_SIMULATOR_MIPS) static void cacheFlush(void* code, size_t size) { js::jit::Simulator::FlushICache(code, size); @@ -447,9 +443,7 @@ class ExecutableAllocator { ExecutableAllocator(const ExecutableAllocator&) = delete; void operator=(const ExecutableAllocator&) = delete; -#if ENABLE_ASSEMBLER_WX_EXCLUSIVE static void reprotectRegion(void*, size_t, ProtectionSetting); -#endif // These are strong references; they keep pools alive. static const size_t maxSmallPools = 4; diff --git a/js/src/jit/ExecutableAllocatorPosix.cpp b/js/src/jit/ExecutableAllocatorPosix.cpp index 56c7915948..d6d791174d 100644 --- a/js/src/jit/ExecutableAllocatorPosix.cpp +++ b/js/src/jit/ExecutableAllocatorPosix.cpp @@ -1,4 +1,6 @@ -/* +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * * Copyright (C) 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,7 +37,8 @@ using namespace js::jit; -size_t ExecutableAllocator::determinePageSize() +size_t +ExecutableAllocator::determinePageSize() { return getpagesize(); } @@ -57,24 +60,29 @@ js::jit::DeallocateExecutableMemory(void* addr, size_t bytes, size_t pageSize) MOZ_ASSERT(!result || errno == ENOMEM); } -ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n) +ExecutablePool::Allocation +ExecutableAllocator::systemAlloc(size_t n) { - void* allocation = AllocateExecutableMemory(nullptr, n, INITIAL_PROTECTION_FLAGS, + void* allocation = AllocateExecutableMemory(nullptr, n, initialProtectionFlags(Executable), "js-jit-code", pageSize); ExecutablePool::Allocation alloc = { reinterpret_cast(allocation), n }; return alloc; } -void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) +void +ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) { DeallocateExecutableMemory(alloc.pages, alloc.size, pageSize); } -#if WTF_ENABLE_ASSEMBLER_WX_EXCLUSIVE -void ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting setting) +static const unsigned FLAGS_RW = PROT_READ | PROT_WRITE; +static const unsigned FLAGS_RX = PROT_READ | PROT_EXEC; + +void +ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting setting) { - if (!pageSize) - intializePageSize(); + MOZ_ASSERT(nonWritableJitCode); + MOZ_ASSERT(pageSize); // Calculate the start of the page containing this region, // and account for this extra memory within size. @@ -87,7 +95,14 @@ void ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSe size += (pageSize - 1); size &= ~(pageSize - 1); - mprotect(pageStart, size, (setting == Writable) ? PROTECTION_FLAGS_RW : PROTECTION_FLAGS_RX); + mprotect(pageStart, size, (setting == Writable) ? FLAGS_RW : FLAGS_RX); } -#endif +/* static */ unsigned +ExecutableAllocator::initialProtectionFlags(ProtectionSetting protection) +{ + if (!nonWritableJitCode) + return FLAGS_RW | FLAGS_RX; + + return (protection == Writable) ? FLAGS_RW : FLAGS_RX; +} diff --git a/js/src/jit/ExecutableAllocatorWin.cpp b/js/src/jit/ExecutableAllocatorWin.cpp index a36b754047..a6eb6fff4c 100644 --- a/js/src/jit/ExecutableAllocatorWin.cpp +++ b/js/src/jit/ExecutableAllocatorWin.cpp @@ -1,4 +1,6 @@ -/* +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * * Copyright (C) 2008 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,14 +37,16 @@ using namespace js::jit; uint64_t ExecutableAllocator::rngSeed; -size_t ExecutableAllocator::determinePageSize() +size_t +ExecutableAllocator::determinePageSize() { SYSTEM_INFO system_info; GetSystemInfo(&system_info); return system_info.dwPageSize; } -void* ExecutableAllocator::computeRandomAllocationAddress() +void* +ExecutableAllocator::computeRandomAllocationAddress() { /* * Inspiration is V8's OS::Allocate in platform-win32.cc. @@ -186,7 +190,6 @@ js::jit::AllocateExecutableMemory(void* addr, size_t bytes, unsigned permissions size_t pageSize) { MOZ_ASSERT(bytes % pageSize == 0); - MOZ_ASSERT(permissions == PAGE_EXECUTE_READWRITE); #ifdef JS_CPU_X64 if (sJitExceptionHandler) @@ -226,31 +229,57 @@ js::jit::DeallocateExecutableMemory(void* addr, size_t bytes, size_t pageSize) VirtualFree(addr, 0, MEM_RELEASE); } -ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n) +ExecutablePool::Allocation +ExecutableAllocator::systemAlloc(size_t n) { void* allocation = nullptr; - // Randomization disabled to avoid a performance fault on x64 builds. - // See bug 728623. -#ifndef JS_CPU_X64 if (!RandomizeIsBroken()) { void* randomAddress = computeRandomAllocationAddress(); - allocation = AllocateExecutableMemory(randomAddress, n, PAGE_EXECUTE_READWRITE, + allocation = AllocateExecutableMemory(randomAddress, n, initialProtectionFlags(Executable), "js-jit-code", pageSize); } -#endif if (!allocation) { - allocation = AllocateExecutableMemory(nullptr, n, PAGE_EXECUTE_READWRITE, + allocation = AllocateExecutableMemory(nullptr, n, initialProtectionFlags(Executable), "js-jit-code", pageSize); } ExecutablePool::Allocation alloc = { reinterpret_cast(allocation), n }; return alloc; } -void ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) +void +ExecutableAllocator::systemRelease(const ExecutablePool::Allocation& alloc) { DeallocateExecutableMemory(alloc.pages, alloc.size, pageSize); } -#if ENABLE_ASSEMBLER_WX_EXCLUSIVE -#error "ASSEMBLER_WX_EXCLUSIVE not yet suported on this platform." -#endif +void +ExecutableAllocator::reprotectRegion(void* start, size_t size, ProtectionSetting setting) +{ + MOZ_ASSERT(nonWritableJitCode); + MOZ_ASSERT(pageSize); + + // Calculate the start of the page containing this region, + // and account for this extra memory within size. + intptr_t startPtr = reinterpret_cast(start); + intptr_t pageStartPtr = startPtr & ~(pageSize - 1); + void* pageStart = reinterpret_cast(pageStartPtr); + size += (startPtr - pageStartPtr); + + // Round size up + size += (pageSize - 1); + size &= ~(pageSize - 1); + + DWORD oldProtect; + int flags = (setting == Writable) ? PAGE_READWRITE : PAGE_EXECUTE_READ; + if (!VirtualProtect(pageStart, size, flags, &oldProtect)) + MOZ_CRASH(); +} + +/* static */ unsigned +ExecutableAllocator::initialProtectionFlags(ProtectionSetting protection) +{ + if (!nonWritableJitCode) + return PAGE_EXECUTE_READWRITE; + + return (protection == Writable) ? PAGE_READWRITE : PAGE_EXECUTE_READ; +} diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index a807b8055f..2bac48e841 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -168,8 +168,7 @@ JitRuntime::JitRuntime() osrTempData_(nullptr), mutatingBackedgeList_(false), ionReturnOverride_(MagicValue(JS_ARG_POISON)), - jitcodeGlobalTable_(nullptr), - hasIonNurseryObjects_(false) + jitcodeGlobalTable_(nullptr) { } @@ -642,9 +641,10 @@ JitCompartment::mark(JSTracer* trc, JSCompartment* compartment) void JitCompartment::sweep(FreeOp* fop, JSCompartment* compartment) { - // Cancel any active or pending off thread compilations. Note that the - // MIR graph does not hold any nursery pointers, so there's no need to - // do this for minor GCs. + // Cancel any active or pending off thread compilations. The MIR graph only + // contains nursery pointers if cancelIonCompilations() is set on the store + // buffer, in which case store buffer marking will take care of this during + // minor GCs. MOZ_ASSERT(!fop->runtime()->isHeapMinorCollecting()); CancelOffThreadIonCompile(compartment, nullptr); FinishAllOffThreadCompilations(compartment); @@ -767,6 +767,12 @@ JitCode::traceChildren(JSTracer* trc) if (invalidated()) return; + // If we're moving objects, we need writable JIT code. + ReprotectCode reprotect = (trc->runtime()->isHeapMinorCollecting() || zone()->isGCCompacting()) + ? Reprotect + : DontReprotect; + MaybeAutoWritableJitCode awjc(this, reprotect); + if (jumpRelocTableBytes_) { uint8_t* start = code_ + jumpRelocTableOffset(); CompactBufferReader reader(start, start + jumpRelocTableBytes_); @@ -779,17 +785,6 @@ JitCode::traceChildren(JSTracer* trc) } } -void -JitCode::fixupNurseryObjects(JSContext* cx, const ObjectVector& nurseryObjects) -{ - if (nurseryObjects.empty() || !dataRelocTableBytes_) - return; - - uint8_t* start = code_ + dataRelocTableOffset(); - CompactBufferReader reader(start, start + dataRelocTableBytes_); - MacroAssembler::FixupNurseryObjects(cx, this, reader, nurseryObjects); -} - void JitCode::finalize(FreeOp* fop) { @@ -806,8 +801,11 @@ JitCode::finalize(FreeOp* fop) // Buffer can be freed at any time hereafter. Catch use-after-free bugs. // Don't do this if the Ion code is protected, as the signal handler will // deadlock trying to reacquire the interrupt lock. - memset(code_, JS_SWEPT_CODE_PATTERN, bufferSize_); - code_ = nullptr; + { + AutoWritableJitCode awjc(this); + memset(code_, JS_SWEPT_CODE_PATTERN, bufferSize_); + code_ = nullptr; + } // Code buffers are stored inside JSC pools. // Pools are refcounted. Releasing the pool may free it. @@ -823,6 +821,7 @@ JitCode::finalize(FreeOp* fop) void JitCode::togglePreBarriers(bool enabled) { + AutoWritableJitCode awjc(this); uint8_t* start = code_ + preBarrierTableOffset(); CompactBufferReader reader(start, start + preBarrierTableBytes_); @@ -1215,6 +1214,7 @@ IonScript::purgeCaches() if (invalidated()) return; + AutoWritableJitCode awjc(method()); for (size_t i = 0; i < numCaches(); i++) getCacheFromIndex(i).reset(); } @@ -1711,7 +1711,7 @@ CodeGenerator* CompileBackEnd(MIRGenerator* mir) { // Everything in CompileBackEnd can potentially run on a helper thread. - AutoEnterIonCompilation enter; + AutoEnterIonCompilation enter(mir->safeForMinorGC()); AutoSpewEndFunction spewEndFunction(mir); if (!OptimizeMIR(mir)) @@ -1840,65 +1840,6 @@ AttachFinishedCompilations(JSContext* cx) js_delete(debuggerAlloc); } -void -MIRGenerator::traceNurseryObjects(JSTracer* trc) -{ - TraceRootRange(trc, nurseryObjects_.length(), nurseryObjects_.begin(), "ion-nursery-objects"); -} - -class MarkOffThreadNurseryObjects : public gc::BufferableRef -{ - public: - void trace(JSTracer* trc) override; -}; - -void -MarkOffThreadNurseryObjects::trace(JSTracer* trc) -{ - JSRuntime* rt = trc->runtime(); - - if (trc->runtime()->isHeapMinorCollecting()) { - // Only reset hasIonNurseryObjects if we're doing an actual minor GC. - MOZ_ASSERT(rt->jitRuntime()->hasIonNurseryObjects()); - rt->jitRuntime()->setHasIonNurseryObjects(false); - } - - AutoLockHelperThreadState lock; - if (!HelperThreadState().threads) - return; - - // Trace nursery objects of any builders which haven't started yet. - GlobalHelperThreadState::IonBuilderVector& worklist = HelperThreadState().ionWorklist(); - for (size_t i = 0; i < worklist.length(); i++) { - jit::IonBuilder* builder = worklist[i]; - if (builder->script()->runtimeFromAnyThread() == rt) - builder->traceNurseryObjects(trc); - } - - // Trace nursery objects of in-progress entries. - for (size_t i = 0; i < HelperThreadState().threadCount; i++) { - HelperThread& helper = HelperThreadState().threads[i]; - if (helper.ionBuilder && helper.ionBuilder->script()->runtimeFromAnyThread() == rt) - helper.ionBuilder->traceNurseryObjects(trc); - } - - // Trace nursery objects of any completed entries. - GlobalHelperThreadState::IonBuilderVector& finished = HelperThreadState().ionFinishedList(); - for (size_t i = 0; i < finished.length(); i++) { - jit::IonBuilder* builder = finished[i]; - if (builder->script()->runtimeFromAnyThread() == rt) - builder->traceNurseryObjects(trc); - } - - // Trace nursery objects of lazy-linked builders. - jit::IonBuilder* builder = HelperThreadState().ionLazyLinkList().getFirst(); - while (builder) { - if (builder->script()->runtimeFromAnyThread() == rt) - builder->traceNurseryObjects(trc); - builder = builder->getNext(); - } -} - static void TrackAllProperties(JSContext* cx, JSObject* obj) { @@ -2032,6 +1973,9 @@ IonCompile(JSContext* cx, JSScript* script, if (!builder) return AbortReason_Alloc; + if (cx->runtime()->gc.storeBuffer.cancelIonCompilations()) + builder->setNotSafeForMinorGC(); + MOZ_ASSERT(recompile == builder->script()->hasIonScript()); MOZ_ASSERT(builder->script()->canIonCompile()); @@ -2089,15 +2033,6 @@ IonCompile(JSContext* cx, JSScript* script, ". (Compiled on background thread.)", builderScript->filename(), builderScript->lineno()); - JSRuntime* rt = cx->runtime(); - if (!builder->nurseryObjects().empty() && !rt->jitRuntime()->hasIonNurseryObjects()) { - // Ensure the builder's nursery objects are marked when a nursery - // GC happens on the main thread. - MarkOffThreadNurseryObjects mark; - rt->gc.storeBuffer.putGeneric(mark); - rt->jitRuntime()->setHasIonNurseryObjects(true); - } - if (!StartOffThreadIonCompile(cx, builder)) { JitSpew(JitSpew_IonAbort, "Unable to start off-thread ion compilation."); builder->graphSpewer().endFunction(); @@ -2816,6 +2751,7 @@ InvalidateActivation(FreeOp* fop, const JitActivationIterator& activations, bool // the call sequence causing the safepoint being >= the size of // a uint32, which is checked during safepoint index // construction. + AutoWritableJitCode awjc(ionCode); const SafepointIndex* si = ionScript->getSafepointIndex(it.returnAddressToFp()); CodeLocationLabel dataLabelToMunge(it.returnAddressToFp()); ptrdiff_t delta = ionScript->invalidateEpilogueDataOffset() - diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index e2fc053db8..cd2b17cc11 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -235,39 +235,6 @@ IonBuilder::spew(const char* message) #endif } -MInstruction* -IonBuilder::constantMaybeNursery(JSObject* obj) -{ - MOZ_ASSERT(obj); - if (!IsInsideNursery(obj)) - return constant(ObjectValue(*obj)); - - // If |obj| is in the nursery, we have to add it to the list of nursery - // objects that get traced during off-thread compilation. We use - // MNurseryObject to ensure we will patch the code with the right - // pointer after codegen is done. - - ObjectVector& nurseryObjects = outermostBuilder()->nurseryObjects_; - - size_t index = UINT32_MAX; - for (size_t i = 0, len = nurseryObjects.length(); i < len; i++) { - if (nurseryObjects[i] == obj) { - index = i; - break; - } - } - - if (index == UINT32_MAX) { - if (!nurseryObjects.append(obj)) - return nullptr; - index = nurseryObjects.length() - 1; - } - - MNurseryObject* ins = MNurseryObject::New(alloc(), obj, index, constraints()); - current->add(ins); - return ins; -} - static inline int32_t GetJumpOffset(jsbytecode* pc) { @@ -474,6 +441,11 @@ IonBuilder::canInlineTarget(JSFunction* target, CallInfo& callInfo) return DontInline(inlineScript, "Callee is not a constructor"); } + if (!callInfo.constructing() && target->isClassConstructor()) { + trackOptimizationOutcome(TrackedOutcome::CantInlineClassConstructor); + return DontInline(inlineScript, "Not constructing class constructor"); + } + AnalysisMode analysisMode = info().analysisMode(); if (!CanIonCompile(inlineScript, analysisMode)) { trackOptimizationOutcome(TrackedOutcome::CantInlineDisabledIon); @@ -979,6 +951,8 @@ IonBuilder::buildInline(IonBuilder* callerBuilder, MResumePoint* callerResumePoi if (callerBuilder->failedLexicalCheck_) failedLexicalCheck_ = true; + safeForMinorGC_ = callerBuilder->safeForMinorGC_; + // Generate single entrance block. if (!setCurrentAndSpecializePhis(newBlock(pc))) return false; @@ -4754,9 +4728,6 @@ IonBuilder::inlineScriptedCall(CallInfo& callInfo, JSFunction* target) return false; } - MOZ_ASSERT(inlineBuilder.nurseryObjects_.empty(), - "Nursery objects should be added to outer builder"); - // Create return block. jsbytecode* postCall = GetNextPc(pc); MBasicBlock* returnBlock = newBlock(nullptr, postCall); @@ -5521,7 +5492,7 @@ IonBuilder::inlineCalls(CallInfo& callInfo, const ObjectVector& targets, BoolVec // hoisting scope chain gets above the dispatch instruction. MInstruction* funcDef; if (target->isSingleton()) - funcDef = MConstant::New(alloc(), ObjectValue(*target), constraints()); + funcDef = MConstant::New(alloc(), ObjectValue(*target), constraints(), this); else funcDef = MPolyInlineGuard::New(alloc(), callInfo.fun()); @@ -5840,7 +5811,7 @@ IonBuilder::createThisScriptedSingleton(JSFunction* target, MDefinition* callee) // Generate an inline path to create a new |this| object with // the given singleton prototype. - MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject); + MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject, this); MCreateThisWithTemplate* createThis = MCreateThisWithTemplate::New(alloc(), constraints(), templateConst, templateObject->group()->initialHeap(constraints())); @@ -5871,7 +5842,7 @@ IonBuilder::createThisScriptedBaseline(MDefinition* callee) if (!protov.isObject()) return nullptr; - JSObject* proto = &protov.toObject(); + JSObject* proto = checkNurseryObject(&protov.toObject()); if (proto != templateObject->getProto()) return nullptr; @@ -5892,14 +5863,14 @@ IonBuilder::createThisScriptedBaseline(MDefinition* callee) current->add(slots); MLoadSlot* prototype = MLoadSlot::New(alloc(), slots, shape->slot()); current->add(prototype); - MDefinition* protoConst = constantMaybeNursery(proto); + MDefinition* protoConst = constant(ObjectValue(*proto)); MGuardObjectIdentity* guard = MGuardObjectIdentity::New(alloc(), prototype, protoConst, /* bailOnEquality = */ false); current->add(guard); // Generate an inline path to create a new |this| object with // the given prototype. - MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject); + MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject, this); MCreateThisWithTemplate* createThis = MCreateThisWithTemplate::New(alloc(), constraints(), templateConst, templateObject->group()->initialHeap(constraints())); @@ -6513,7 +6484,7 @@ IonBuilder::jsop_newarray(uint32_t count) if (templateObject) { heap = templateObject->group()->initialHeap(constraints()); - templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject); + templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject, this); } else { heap = gc::DefaultHeap; templateConst = MConstant::New(alloc(), NullValue()); @@ -6564,7 +6535,7 @@ IonBuilder::jsop_newobject() if (templateObject) { heap = templateObject->group()->initialHeap(constraints()); - templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject); + templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject, this); } else { heap = gc::DefaultHeap; templateConst = MConstant::New(alloc(), NullValue()); @@ -7228,7 +7199,7 @@ IonBuilder::testSingletonProperty(JSObject* obj, PropertyName* name) if (ObjectHasExtraOwnProperty(compartment, objKey, name)) return nullptr; - obj = obj->getProto(); + obj = checkNurseryObject(obj->getProto()); } return nullptr; @@ -7295,7 +7266,7 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, PropertyName* name) if (property.isOwnProperty(constraints())) return nullptr; - if (JSObject* proto = key->proto().toObjectOrNull()) { + if (JSObject* proto = checkNurseryObject(key->proto().toObjectOrNull())) { // Test this type. JSObject* thisSingleton = testSingletonProperty(proto, name); if (!thisSingleton) @@ -7644,17 +7615,13 @@ IonBuilder::jsop_getgname(PropertyName* name) if (!getStaticName(obj, name, &emitted) || emitted) return emitted; - if (MOZ_UNLIKELY(js_JitOptions.forceInlineCaches)) - goto do_InlineCache; - - { + if (!forceInlineCaches()) { TemporaryTypeSet* types = bytecodeTypes(pc); MDefinition* globalObj = constant(ObjectValue(*obj)); if (!getPropTryCommonGetter(&emitted, globalObj, name, types) || emitted) return emitted; } - do_InlineCache: return jsop_getname(name); } @@ -7778,38 +7745,37 @@ IonBuilder::jsop_getelem() obj = maybeUnboxForPropertyAccess(obj); bool emitted = false; - if (MOZ_UNLIKELY(js_JitOptions.forceInlineCaches)) - goto do_InlineCache; - trackOptimizationAttempt(TrackedStrategy::GetElem_TypedObject); - if (!getElemTryTypedObject(&emitted, obj, index) || emitted) - return emitted; + if (!forceInlineCaches()) { + trackOptimizationAttempt(TrackedStrategy::GetElem_TypedObject); + if (!getElemTryTypedObject(&emitted, obj, index) || emitted) + return emitted; - trackOptimizationAttempt(TrackedStrategy::GetElem_Dense); - if (!getElemTryDense(&emitted, obj, index) || emitted) - return emitted; + trackOptimizationAttempt(TrackedStrategy::GetElem_Dense); + if (!getElemTryDense(&emitted, obj, index) || emitted) + return emitted; - trackOptimizationAttempt(TrackedStrategy::GetElem_TypedStatic); - if (!getElemTryTypedStatic(&emitted, obj, index) || emitted) - return emitted; + trackOptimizationAttempt(TrackedStrategy::GetElem_TypedStatic); + if (!getElemTryTypedStatic(&emitted, obj, index) || emitted) + return emitted; - trackOptimizationAttempt(TrackedStrategy::GetElem_TypedArray); - if (!getElemTryTypedArray(&emitted, obj, index) || emitted) - return emitted; + trackOptimizationAttempt(TrackedStrategy::GetElem_TypedArray); + if (!getElemTryTypedArray(&emitted, obj, index) || emitted) + return emitted; - trackOptimizationAttempt(TrackedStrategy::GetElem_String); - if (!getElemTryString(&emitted, obj, index) || emitted) - return emitted; + trackOptimizationAttempt(TrackedStrategy::GetElem_String); + if (!getElemTryString(&emitted, obj, index) || emitted) + return emitted; - trackOptimizationAttempt(TrackedStrategy::GetElem_Arguments); - if (!getElemTryArguments(&emitted, obj, index) || emitted) - return emitted; + trackOptimizationAttempt(TrackedStrategy::GetElem_Arguments); + if (!getElemTryArguments(&emitted, obj, index) || emitted) + return emitted; - trackOptimizationAttempt(TrackedStrategy::GetElem_ArgumentsInlined); - if (!getElemTryArgumentsInlined(&emitted, obj, index) || emitted) - return emitted; + trackOptimizationAttempt(TrackedStrategy::GetElem_ArgumentsInlined); + if (!getElemTryArgumentsInlined(&emitted, obj, index) || emitted) + return emitted; + } - do_InlineCache: if (script()->argumentsHasVarBinding() && obj->mightBeType(MIRType_MagicOptimizedArguments)) return abort("Type is not definitely lazy arguments."); @@ -8806,34 +8772,30 @@ IonBuilder::jsop_setelem() return resumeAfter(ins); } - if (MOZ_UNLIKELY(js_JitOptions.forceInlineCaches)) - goto do_InlineCache; + if (!forceInlineCaches()) { + trackOptimizationAttempt(TrackedStrategy::SetElem_TypedObject); + if (!setElemTryTypedObject(&emitted, object, index, value) || emitted) + return emitted; - trackOptimizationAttempt(TrackedStrategy::SetElem_TypedObject); - if (!setElemTryTypedObject(&emitted, object, index, value) || emitted) - return emitted; + trackOptimizationAttempt(TrackedStrategy::SetElem_TypedStatic); + if (!setElemTryTypedStatic(&emitted, object, index, value) || emitted) + return emitted; - trackOptimizationAttempt(TrackedStrategy::SetElem_TypedStatic); - if (!setElemTryTypedStatic(&emitted, object, index, value) || emitted) - return emitted; + trackOptimizationAttempt(TrackedStrategy::SetElem_TypedArray); + if (!setElemTryTypedArray(&emitted, object, index, value) || emitted) + return emitted; - trackOptimizationAttempt(TrackedStrategy::SetElem_TypedArray); - if (!setElemTryTypedArray(&emitted, object, index, value) || emitted) - return emitted; - - { trackOptimizationAttempt(TrackedStrategy::SetElem_Dense); SetElemICInspector icInspect(inspector->setElemICInspector(pc)); bool writeHole = icInspect.sawOOBDenseWrite(); if (!setElemTryDense(&emitted, object, index, value, writeHole) || emitted) return emitted; + + trackOptimizationAttempt(TrackedStrategy::SetElem_Arguments); + if (!setElemTryArguments(&emitted, object, index, value) || emitted) + return emitted; } - trackOptimizationAttempt(TrackedStrategy::SetElem_Arguments); - if (!setElemTryArguments(&emitted, object, index, value) || emitted) - return emitted; - - do_InlineCache: if (script()->argumentsHasVarBinding() && object->mightBeType(MIRType_MagicOptimizedArguments) && info().analysisMode() != Analysis_ArgumentsUsage) @@ -9042,7 +9004,7 @@ IonBuilder::setElemTryDense(bool* emitted, MDefinition* object, } } - if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, + if (PropertyWriteNeedsTypeBarrier(this, constraints(), current, &object, nullptr, &value, /* canModify = */ true)) { trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier); @@ -9122,7 +9084,7 @@ IonBuilder::setElemTryCache(bool* emitted, MDefinition* object, return true; } - if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, + if (PropertyWriteNeedsTypeBarrier(this, constraints(), current, &object, nullptr, &value, /* canModify = */ true)) { trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier); @@ -9472,7 +9434,7 @@ IonBuilder::jsop_rest() unsigned numFormals = info().nargs() - 1; unsigned numRest = numActuals > numFormals ? numActuals - numFormals : 0; - MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject); + MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject, this); current->add(templateConst); MNewArray* array = MNewArray::New(alloc(), constraints(), numRest, templateConst, @@ -9726,7 +9688,8 @@ IonBuilder::objectsHaveCommonPrototype(TemporaryTypeSet* types, PropertyName* na } } - JSObject* proto = key->proto().toObjectOrNull(); + JSObject* proto = checkNurseryObject(key->proto().toObjectOrNull()); + if (proto == foundProto) break; if (!proto) { @@ -9821,7 +9784,7 @@ IonBuilder::testCommonGetterSetter(TemporaryTypeSet* types, PropertyName* name, } } - MInstruction* wrapper = constantMaybeNursery(foundProto); + MInstruction* wrapper = constant(ObjectValue(*foundProto)); *guard = addShapeGuard(wrapper, lastProperty, Bailout_ShapeGuard); return true; } @@ -9871,6 +9834,7 @@ IonBuilder::annotateGetPropertyCache(MDefinition* obj, MGetPropertyCache* getPro TypeSet::ObjectKey* key = TypeSet::ObjectKey::get(group); if (key->unknownProperties() || !key->proto().isObject()) continue; + JSObject* proto = checkNurseryObject(key->proto().toObject()); const Class* clasp = key->clasp(); if (!ClassHasEffectlessLookup(clasp) || ObjectHasExtraOwnProperty(compartment, key, name)) @@ -9880,7 +9844,7 @@ IonBuilder::annotateGetPropertyCache(MDefinition* obj, MGetPropertyCache* getPro if (ownTypes.isOwnProperty(constraints())) continue; - JSObject* singleton = testSingletonProperty(key->proto().toObject(), name); + JSObject* singleton = testSingletonProperty(proto, name); if (!singleton || !singleton->is()) continue; @@ -10124,45 +10088,43 @@ IonBuilder::jsop_getprop(PropertyName* name) if (!getPropTryInnerize(&emitted, obj, name, types) || emitted) return emitted; - if (MOZ_UNLIKELY(js_JitOptions.forceInlineCaches)) - goto do_InlineCache; + if (!forceInlineCaches()) { + // Try to hardcode known constants. + trackOptimizationAttempt(TrackedStrategy::GetProp_Constant); + if (!getPropTryConstant(&emitted, obj, name, types) || emitted) + return emitted; - // Try to hardcode known constants. - trackOptimizationAttempt(TrackedStrategy::GetProp_Constant); - if (!getPropTryConstant(&emitted, obj, name, types) || emitted) - return emitted; + // Try to emit SIMD getter loads + trackOptimizationAttempt(TrackedStrategy::GetProp_SimdGetter); + if (!getPropTrySimdGetter(&emitted, obj, name) || emitted) + return emitted; - // Try to emit SIMD getter loads - trackOptimizationAttempt(TrackedStrategy::GetProp_SimdGetter); - if (!getPropTrySimdGetter(&emitted, obj, name) || emitted) - return emitted; + // Try to emit loads from known binary data blocks + trackOptimizationAttempt(TrackedStrategy::GetProp_TypedObject); + if (!getPropTryTypedObject(&emitted, obj, name) || emitted) + return emitted; - // Try to emit loads from known binary data blocks - trackOptimizationAttempt(TrackedStrategy::GetProp_TypedObject); - if (!getPropTryTypedObject(&emitted, obj, name) || emitted) - return emitted; + // Try to emit loads from definite slots. + trackOptimizationAttempt(TrackedStrategy::GetProp_DefiniteSlot); + if (!getPropTryDefiniteSlot(&emitted, obj, name, barrier, types) || emitted) + return emitted; - // Try to emit loads from definite slots. - trackOptimizationAttempt(TrackedStrategy::GetProp_DefiniteSlot); - if (!getPropTryDefiniteSlot(&emitted, obj, name, barrier, types) || emitted) - return emitted; + // Try to emit loads from unboxed objects. + trackOptimizationAttempt(TrackedStrategy::GetProp_Unboxed); + if (!getPropTryUnboxed(&emitted, obj, name, barrier, types) || emitted) + return emitted; - // Try to emit loads from unboxed objects. - trackOptimizationAttempt(TrackedStrategy::GetProp_Unboxed); - if (!getPropTryUnboxed(&emitted, obj, name, barrier, types) || emitted) - return emitted; + // Try to inline a common property getter, or make a call. + trackOptimizationAttempt(TrackedStrategy::GetProp_CommonGetter); + if (!getPropTryCommonGetter(&emitted, obj, name, types) || emitted) + return emitted; - // Try to inline a common property getter, or make a call. - trackOptimizationAttempt(TrackedStrategy::GetProp_CommonGetter); - if (!getPropTryCommonGetter(&emitted, obj, name, types) || emitted) - return emitted; + // Try to emit a monomorphic/polymorphic access based on baseline caches. + trackOptimizationAttempt(TrackedStrategy::GetProp_InlineAccess); + if (!getPropTryInlineAccess(&emitted, obj, name, barrier, types) || emitted) + return emitted; + } - // Try to emit a monomorphic/polymorphic access based on baseline caches. - trackOptimizationAttempt(TrackedStrategy::GetProp_InlineAccess); - if (!getPropTryInlineAccess(&emitted, obj, name, barrier, types) || emitted) - return emitted; - - do_InlineCache: // Try to emit a polymorphic cache. trackOptimizationAttempt(TrackedStrategy::GetProp_InlineCache); if (!getPropTryCache(&emitted, obj, name, barrier, types) || emitted) @@ -10718,7 +10680,7 @@ IonBuilder::addShapeGuardsForGetterSetter(MDefinition* obj, JSObject* holder, Sh return addShapeGuard(obj, holderShape, Bailout_ShapeGuard); } - MDefinition* holderDef = constantMaybeNursery(holder); + MDefinition* holderDef = constant(ObjectValue(*holder)); addShapeGuard(holderDef, holderShape, Bailout_ShapeGuard); return addGuardReceiverPolymorphic(obj, receivers); @@ -10812,7 +10774,7 @@ IonBuilder::getPropTryCommonGetter(bool* emitted, MDefinition* obj, PropertyName // Make sure there's enough room if (!current->ensureHasSlots(2)) return false; - current->push(constantMaybeNursery(commonGetter)); + current->push(constant(ObjectValue(*commonGetter))); current->push(obj); @@ -11053,7 +11015,7 @@ IonBuilder::getPropTryCache(bool* emitted, MDefinition* obj, PropertyName* name, // reflect such possible values. if (barrier != BarrierKind::TypeSet) { BarrierKind protoBarrier = - PropertyReadOnPrototypeNeedsTypeBarrier(constraints(), obj, name, types); + PropertyReadOnPrototypeNeedsTypeBarrier(this, constraints(), obj, name, types); if (protoBarrier != BarrierKind::NoBarrier) { MOZ_ASSERT(barrier <= protoBarrier); barrier = protoBarrier; @@ -11153,31 +11115,29 @@ IonBuilder::getPropTryInnerize(bool* emitted, MDefinition* obj, PropertyName* na if (inner == obj) return true; - if (MOZ_UNLIKELY(js_JitOptions.forceInlineCaches)) - goto do_InlineCache; + if (!forceInlineCaches()) { + // Note: the Baseline ICs don't know about this optimization, so it's + // possible the global property's HeapTypeSet has not been initialized + // yet. In this case we'll fall back to getPropTryCache for now. - // Note: the Baseline ICs don't know about this optimization, so it's - // possible the global property's HeapTypeSet has not been initialized - // yet. In this case we'll fall back to getPropTryCache for now. + // Note that it's important that we do this _before_ we'd try to + // do the optimizations below on obj normally, since some of those + // optimizations have fallback paths that are slower than the path + // we'd produce here. - // Note that it's important that we do this _before_ we'd try to - // do the optimizations below on obj normally, since some of those - // optimizations have fallback paths that are slower than the path - // we'd produce here. + trackOptimizationAttempt(TrackedStrategy::GetProp_Constant); + if (!getPropTryConstant(emitted, inner, name, types) || *emitted) + return *emitted; - trackOptimizationAttempt(TrackedStrategy::GetProp_Constant); - if (!getPropTryConstant(emitted, inner, name, types) || *emitted) - return *emitted; + trackOptimizationAttempt(TrackedStrategy::GetProp_StaticName); + if (!getStaticName(&script()->global(), name, emitted) || *emitted) + return *emitted; - trackOptimizationAttempt(TrackedStrategy::GetProp_StaticName); - if (!getStaticName(&script()->global(), name, emitted) || *emitted) - return *emitted; + trackOptimizationAttempt(TrackedStrategy::GetProp_CommonGetter); + if (!getPropTryCommonGetter(emitted, inner, name, types) || *emitted) + return *emitted; + } - trackOptimizationAttempt(TrackedStrategy::GetProp_CommonGetter); - if (!getPropTryCommonGetter(emitted, inner, name, types) || *emitted) - return *emitted; - - do_InlineCache: // Passing the inner object to GetProperty IC is safe, see the // needsOuterizedThisObject check in IsCacheableGetPropCallNative. BarrierKind barrier = PropertyReadNeedsTypeBarrier(analysisContext, constraints(), @@ -11211,52 +11171,46 @@ IonBuilder::jsop_setprop(PropertyName* name) return resumeAfter(ins); } - if (MOZ_UNLIKELY(js_JitOptions.forceInlineCaches)) - goto do_InlineCache_step1; + if (!forceInlineCaches()) { + // Try to inline a common property setter, or make a call. + trackOptimizationAttempt(TrackedStrategy::SetProp_CommonSetter); + if (!setPropTryCommonSetter(&emitted, obj, name, value) || emitted) + return emitted; - // Try to inline a common property setter, or make a call. - trackOptimizationAttempt(TrackedStrategy::SetProp_CommonSetter); - if (!setPropTryCommonSetter(&emitted, obj, name, value) || emitted) - return emitted; + // Try to emit stores to known binary data blocks + trackOptimizationAttempt(TrackedStrategy::SetProp_TypedObject); + if (!setPropTryTypedObject(&emitted, obj, name, value) || emitted) + return emitted; + } - // Try to emit stores to known binary data blocks - trackOptimizationAttempt(TrackedStrategy::SetProp_TypedObject); - if (!setPropTryTypedObject(&emitted, obj, name, value) || emitted) - return emitted; - - do_InlineCache_step1: TemporaryTypeSet* objTypes = obj->resultTypeSet(); - bool barrier = PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &obj, name, &value, + bool barrier = PropertyWriteNeedsTypeBarrier(this, constraints(), current, &obj, name, &value, /* canModify = */ true); - if (MOZ_UNLIKELY(js_JitOptions.forceInlineCaches)) - goto do_InlineCache_step2; + if (!forceInlineCaches()) { + // Try to emit stores to unboxed objects. + trackOptimizationAttempt(TrackedStrategy::SetProp_Unboxed); + if (!setPropTryUnboxed(&emitted, obj, name, value, barrier, objTypes) || emitted) + return emitted; + } - // Try to emit stores to unboxed objects. - trackOptimizationAttempt(TrackedStrategy::SetProp_Unboxed); - if (!setPropTryUnboxed(&emitted, obj, name, value, barrier, objTypes) || emitted) - return emitted; - - do_InlineCache_step2: // Add post barrier if needed. The instructions above manage any post // barriers they need directly. if (NeedsPostBarrier(info(), value)) current->add(MPostWriteBarrier::New(alloc(), obj, value)); - if (MOZ_UNLIKELY(js_JitOptions.forceInlineCaches)) - goto do_InlineCache_step3; + if (!forceInlineCaches()) { + // Try to emit store from definite slots. + trackOptimizationAttempt(TrackedStrategy::SetProp_DefiniteSlot); + if (!setPropTryDefiniteSlot(&emitted, obj, name, value, barrier, objTypes) || emitted) + return emitted; - // Try to emit store from definite slots. - trackOptimizationAttempt(TrackedStrategy::SetProp_DefiniteSlot); - if (!setPropTryDefiniteSlot(&emitted, obj, name, value, barrier, objTypes) || emitted) - return emitted; + // Try to emit a monomorphic/polymorphic store based on baseline caches. + trackOptimizationAttempt(TrackedStrategy::SetProp_InlineAccess); + if (!setPropTryInlineAccess(&emitted, obj, name, value, barrier, objTypes) || emitted) + return emitted; + } - // Try to emit a monomorphic/polymorphic store based on baseline caches. - trackOptimizationAttempt(TrackedStrategy::SetProp_InlineAccess); - if (!setPropTryInlineAccess(&emitted, obj, name, value, barrier, objTypes) || emitted) - return emitted; - - do_InlineCache_step3: // Emit a polymorphic cache. trackOptimizationAttempt(TrackedStrategy::SetProp_InlineCache); return setPropTryCache(&emitted, obj, name, value, barrier, objTypes); @@ -11324,7 +11278,7 @@ IonBuilder::setPropTryCommonSetter(bool* emitted, MDefinition* obj, if (!current->ensureHasSlots(3)) return false; - current->push(constantMaybeNursery(commonSetter)); + current->push(constant(ObjectValue(*commonSetter))); current->push(obj); current->push(value); @@ -11871,7 +11825,7 @@ IonBuilder::jsop_lambda(JSFunction* fun) if (fun->isNative() && IsAsmJSModuleNative(fun->native())) return abort("asm.js module function"); - MConstant* cst = MConstant::NewConstraintlessObject(alloc(), fun); + MConstant* cst = MConstant::NewConstraintlessObject(alloc(), fun, this); current->add(cst); MLambda* ins = MLambda::New(alloc(), constraints(), current->scopeChain(), cst); current->add(ins); @@ -12580,7 +12534,7 @@ IonBuilder::jsop_instanceof() current->add(slots); MLoadSlot* prototype = MLoadSlot::New(alloc(), slots, slot); current->add(prototype); - MConstant* protoConst = MConstant::NewConstraintlessObject(alloc(), protoObject); + MConstant* protoConst = MConstant::NewConstraintlessObject(alloc(), protoObject, this); current->add(protoConst); MGuardObjectIdentity* guard = MGuardObjectIdentity::New(alloc(), prototype, protoConst, /* bailOnEquality = */ false); @@ -12991,7 +12945,7 @@ IonBuilder::storeReferenceTypedObjectValue(MDefinition* typedObj, MIRType implicitType = (type == ReferenceTypeDescr::TYPE_ANY) ? MIRType_Undefined : MIRType_Null; - if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &typedObj, name, &value, + if (PropertyWriteNeedsTypeBarrier(this, constraints(), current, &typedObj, name, &value, /* canModify = */ true, implicitType)) { trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier); @@ -13032,13 +12986,35 @@ IonBuilder::storeReferenceTypedObjectValue(MDefinition* typedObj, return true; } +JSObject* +IonBuilder::checkNurseryObject(JSObject* obj) +{ + // If we try to use any nursery pointers during compilation, make sure that + // the main thread will cancel this compilation before performing a minor + // GC. All constants used during compilation should either go through this + // function or should come from a type set (which has a similar barrier). + if (obj && IsInsideNursery(obj)) { + compartment->runtime()->setMinorGCShouldCancelIonCompilations(); + IonBuilder* builder = this; + while (builder) { + builder->setNotSafeForMinorGC(); + builder = builder->callerBuilder_; + } + } + + return obj; +} + MConstant* IonBuilder::constant(const Value& v) { MOZ_ASSERT(!v.isString() || v.toString()->isAtom(), "Handle non-atomized strings outside IonBuilder."); - MConstant* c = MConstant::New(alloc(), v, constraints()); + if (v.isObject()) + checkNurseryObject(&v.toObject()); + + MConstant* c = MConstant::New(alloc(), v, constraints(), this); current->add(c); return c; } diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h index 3de1bd09ec..516e97a962 100644 --- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -228,8 +228,6 @@ class IonBuilder void trackActionableAbort(const char* message); void spew(const char* message); - MInstruction* constantMaybeNursery(JSObject* obj); - JSFunction* getSingleCallTarget(TemporaryTypeSet* calleeTypes); bool getPolyCallTargets(TemporaryTypeSet* calleeTypes, bool constructing, ObjectVector& targets, uint32_t maxTargets); @@ -981,6 +979,7 @@ class IonBuilder public: void clearForBackEnd(); + JSObject* checkNurseryObject(JSObject* obj); JSScript* script() const { return script_; } @@ -1205,6 +1204,10 @@ class IonBuilder trackInlineSuccessUnchecked(status); } + bool forceInlineCaches() { + return MOZ_UNLIKELY(js_JitOptions.forceInlineCaches); + } + // Out-of-line variants that don't check if optimization tracking is // enabled. void trackTypeInfoUnchecked(JS::TrackedTypeSite site, MIRType mirType, diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index e792c63700..e32504077a 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -246,11 +246,13 @@ class IonCache::StubAttacher void patchRejoinJump(MacroAssembler& masm, JitCode* code) { rejoinOffset_.fixup(&masm); CodeLocationJump rejoinJump(code, rejoinOffset_); + AutoWritableJitCode awjc(code); PatchJump(rejoinJump, rejoinLabel_); } void patchStubCodePointer(MacroAssembler& masm, JitCode* code) { if (hasStubCodePatchOffset_) { + AutoWritableJitCode awjc(code); stubCodePatchOffset_.fixup(&masm); Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, stubCodePatchOffset_), ImmPtr(code), STUB_ADDR); @@ -260,11 +262,12 @@ class IonCache::StubAttacher void patchNextStubJump(MacroAssembler& masm, JitCode* code) { // Patch the previous nextStubJump of the last stub, or the jump from the // codeGen, to jump into the newly allocated code. - PatchJump(cache_.lastJump_, CodeLocationLabel(code)); + PatchJump(cache_.lastJump_, CodeLocationLabel(code), Reprotect); // If this path is not taken, we are producing an entry which can no // longer go back into the update function. if (hasNextStubOffset_) { + AutoWritableJitCode awjc(code); nextStubOffset_.fixup(&masm); CodeLocationJump nextStubJump(code, nextStubOffset_); PatchJump(nextStubJump, cache_.fallbackLabel_); @@ -371,6 +374,7 @@ IonCache::linkAndAttachStub(JSContext* cx, MacroAssembler& masm, StubAttacher& a void IonCache::updateBaseAddress(JitCode* code, MacroAssembler& masm) { + AutoWritableJitCode awjc(code); fallbackLabel_.repoint(code, &masm); initialJump_.repoint(code, &masm); lastJump_.repoint(code, &masm); @@ -410,8 +414,7 @@ GeneratePrototypeGuards(JSContext* cx, IonScript* ion, MacroAssembler& masm, JSO // use objectReg in the rest of this function. masm.loadPtr(Address(objectReg, JSObject::offsetOfGroup()), scratchReg); Address proto(scratchReg, ObjectGroup::offsetOfProto()); - masm.branchPtr(Assembler::NotEqual, proto, - ImmMaybeNurseryPtr(obj->getProto()), failures); + masm.branchPtr(Assembler::NotEqual, proto, ImmGCPtr(obj->getProto()), failures); } JSObject* pobj = IsCacheableDOMProxy(obj) @@ -422,7 +425,7 @@ GeneratePrototypeGuards(JSContext* cx, IonScript* ion, MacroAssembler& masm, JSO while (pobj != holder) { if (pobj->hasUncacheableProto()) { MOZ_ASSERT(!pobj->isSingleton()); - masm.movePtr(ImmMaybeNurseryPtr(pobj), scratchReg); + masm.movePtr(ImmGCPtr(pobj), scratchReg); Address groupAddr(scratchReg, JSObject::offsetOfGroup()); masm.branchPtr(Assembler::NotEqual, groupAddr, ImmGCPtr(pobj->group()), failures); } @@ -801,7 +804,7 @@ GenerateReadSlot(JSContext* cx, IonScript* ion, MacroAssembler& masm, if (holder) { // Guard on the holder's shape. holderReg = scratchReg; - masm.movePtr(ImmMaybeNurseryPtr(holder), holderReg); + masm.movePtr(ImmGCPtr(holder), holderReg); masm.branchPtr(Assembler::NotEqual, Address(holderReg, JSObject::offsetOfShape()), ImmGCPtr(holder->as().lastProperty()), @@ -983,7 +986,7 @@ EmitGetterCall(JSContext* cx, MacroAssembler& masm, } else { // If the holder is on the prototype chain, the prototype-guarding // only allows objects with the same holder. - masm.movePtr(ImmMaybeNurseryPtr(holder), scratchReg); + masm.movePtr(ImmGCPtr(holder), scratchReg); masm.Push(scratchReg); } masm.moveStackPtrTo(argObjReg); @@ -1036,7 +1039,7 @@ EmitGetterCall(JSContext* cx, MacroAssembler& masm, masm.Push(UndefinedValue()); masm.Push(TypedOrValueRegister(MIRType_Object, AnyRegister(object))); - masm.movePtr(ImmMaybeNurseryPtr(target), scratchReg); + masm.movePtr(ImmGCPtr(target), scratchReg); descriptor = MakeFrameDescriptor(argSize + padding, JitFrame_IonAccessorIC); masm.Push(Imm32(0)); // argc @@ -1093,7 +1096,7 @@ GenerateCallGetter(JSContext* cx, IonScript* ion, MacroAssembler& masm, // Guard on the holder's shape. Register holderReg = scratchReg; - masm.movePtr(ImmMaybeNurseryPtr(holder), holderReg); + masm.movePtr(ImmGCPtr(holder), holderReg); masm.branchPtr(Assembler::NotEqual, Address(holderReg, JSObject::offsetOfShape()), ImmGCPtr(holder->as().lastProperty()), @@ -1696,7 +1699,7 @@ GetPropertyIC::tryAttachDOMProxyUnshadowed(JSContext* cx, HandleScript outerScri Register holderReg = scratchReg; // Guard on the holder of the property - masm.movePtr(ImmMaybeNurseryPtr(holder), holderReg); + masm.movePtr(ImmGCPtr(holder), holderReg); masm.branchPtr(Assembler::NotEqual, Address(holderReg, JSObject::offsetOfShape()), ImmGCPtr(holder->lastProperty()), @@ -2006,8 +2009,9 @@ GetPropertyIC::reset() } void -IonCache::disable() +IonCache::disable(IonScript* ion) { + AutoWritableJitCode awjc(ion->method()); reset(); this->disabled_ = 1; } @@ -2419,7 +2423,7 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm, if (obj != holder) GeneratePrototypeGuards(cx, ion, masm, obj, holder, object, scratchReg, &protoFailure); - masm.movePtr(ImmMaybeNurseryPtr(holder), scratchReg); + masm.movePtr(ImmGCPtr(holder), scratchReg); masm.branchPtr(Assembler::NotEqual, Address(scratchReg, JSObject::offsetOfShape()), ImmGCPtr(holder->as().lastProperty()), @@ -2604,7 +2608,7 @@ GenerateCallSetter(JSContext* cx, IonScript* ion, MacroAssembler& masm, masm.Push(value); masm.Push(TypedOrValueRegister(MIRType_Object, AnyRegister(object))); - masm.movePtr(ImmMaybeNurseryPtr(target), scratchReg); + masm.movePtr(ImmGCPtr(target), scratchReg); descriptor = MakeFrameDescriptor(argSize + padding, JitFrame_IonAccessorIC); masm.Push(Imm32(1)); // argc @@ -3517,15 +3521,14 @@ GenerateDenseElementHole(JSContext* cx, MacroAssembler& masm, IonCache::StubAtta if (obj->hasUncacheableProto()) { masm.loadPtr(Address(object, JSObject::offsetOfGroup()), scratchReg); Address proto(scratchReg, ObjectGroup::offsetOfProto()); - masm.branchPtr(Assembler::NotEqual, proto, - ImmMaybeNurseryPtr(obj->getProto()), &failures); + masm.branchPtr(Assembler::NotEqual, proto, ImmGCPtr(obj->getProto()), &failures); } JSObject* pobj = obj->getProto(); while (pobj) { MOZ_ASSERT(pobj->as().lastProperty()); - masm.movePtr(ImmMaybeNurseryPtr(pobj), scratchReg); + masm.movePtr(ImmGCPtr(pobj), scratchReg); if (pobj->hasUncacheableProto()) { MOZ_ASSERT(!pobj->isSingleton()); Address groupAddr(scratchReg, JSObject::offsetOfGroup()); @@ -4054,7 +4057,7 @@ GetElementIC::update(JSContext* cx, HandleScript outerScript, size_t cacheIndex, cache.incFailedUpdates(); if (cache.shouldDisable()) { JitSpew(JitSpew_IonIC, "Disable inline cache"); - cache.disable(); + cache.disable(ion); } } else { cache.resetFailedUpdates(); diff --git a/js/src/jit/IonCaches.h b/js/src/jit/IonCaches.h index 86d47e88e1..72ef0819af 100644 --- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -243,7 +243,7 @@ class IonCache { } - virtual void disable(); + void disable(IonScript* ion); inline bool isDisabled() const { return disabled_; } diff --git a/js/src/jit/IonCode.h b/js/src/jit/IonCode.h index bfb69c6e37..2ae9029798 100644 --- a/js/src/jit/IonCode.h +++ b/js/src/jit/IonCode.h @@ -103,6 +103,10 @@ class JitCode : public gc::TenuredCell size_t instructionsSize() const { return insnSize_; } + size_t bufferSize() const { + return bufferSize_; + } + void traceChildren(JSTracer* trc); void finalize(FreeOp* fop); void fixupAfterMovingGC() {} @@ -110,8 +114,6 @@ class JitCode : public gc::TenuredCell invalidated_ = true; } - void fixupNurseryObjects(JSContext* cx, const ObjectVector& nurseryObjects); - void setHasBytecodeMap() { hasBytecodeMap_ = true; } diff --git a/js/src/jit/JitCommon.h b/js/src/jit/JitCommon.h index 6919a5efff..98cf78a830 100644 --- a/js/src/jit/JitCommon.h +++ b/js/src/jit/JitCommon.h @@ -9,13 +9,13 @@ // Various macros used by all JITs. -#if defined(JS_ARM_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) #include "jit/arm/Simulator-arm.h" -#elif defined(JS_MIPS_SIMULATOR) +#elif defined(JS_SIMULATOR_MIPS) #include "jit/mips/Simulator-mips.h" #endif -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) || defined(JS_SIMULATOR_MIPS) // Call into cross-jitted code by following the ABI of the simulated architecture. #define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \ (js::jit::Simulator::Current()->call( \ diff --git a/js/src/jit/JitCompartment.h b/js/src/jit/JitCompartment.h index 40f1f0c991..af5d33dcc3 100644 --- a/js/src/jit/JitCompartment.h +++ b/js/src/jit/JitCompartment.h @@ -228,8 +228,6 @@ class JitRuntime // Global table of jitcode native address => bytecode address mappings. JitcodeGlobalTable* jitcodeGlobalTable_; - bool hasIonNurseryObjects_; - private: JitCode* generateLazyLinkStub(JSContext* cx); JitCode* generateProfilerExitFrameTailStub(JSContext* cx); @@ -376,13 +374,6 @@ class JitRuntime ionReturnOverride_ = v; } - bool hasIonNurseryObjects() const { - return hasIonNurseryObjects_; - } - void setHasIonNurseryObjects(bool b) { - hasIonNurseryObjects_ = b; - } - bool hasJitcodeGlobalTable() const { return jitcodeGlobalTable_ != nullptr; } @@ -557,6 +548,51 @@ void FinishInvalidation(FreeOp* fop, JSScript* script); const unsigned WINDOWS_BIG_FRAME_TOUCH_INCREMENT = 4096 - 1; #endif +// If ExecutableAllocator::nonWritableJitCode is |true|, this class will ensure +// JIT code is writable (has RW permissions) in its scope. If nonWritableJitCode +// is |false|, it's a no-op. +class MOZ_STACK_CLASS AutoWritableJitCode +{ + JSRuntime* rt_; + void* addr_; + size_t size_; + + public: + AutoWritableJitCode(JSRuntime* rt, void* addr, size_t size) + : rt_(rt), addr_(addr), size_(size) + { + rt_->toggleAutoWritableJitCodeActive(true); + ExecutableAllocator::makeWritable(addr_, size_); + } + AutoWritableJitCode(void* addr, size_t size) + : AutoWritableJitCode(TlsPerThreadData.get()->runtimeFromMainThread(), addr, size) + {} + explicit AutoWritableJitCode(JitCode* code) + : AutoWritableJitCode(code->runtimeFromMainThread(), code->raw(), code->bufferSize()) + {} + ~AutoWritableJitCode() { + ExecutableAllocator::makeExecutable(addr_, size_); + rt_->toggleAutoWritableJitCodeActive(false); + } +}; + +enum ReprotectCode { Reprotect = true, DontReprotect = false }; + +class MOZ_STACK_CLASS MaybeAutoWritableJitCode +{ + mozilla::Maybe awjc_; + + public: + MaybeAutoWritableJitCode(void* addr, size_t size, ReprotectCode reprotect) { + if (reprotect) + awjc_.emplace(addr, size); + } + MaybeAutoWritableJitCode(JitCode* code, ReprotectCode reprotect) { + if (reprotect) + awjc_.emplace(code); + } +}; + } // namespace jit } // namespace js diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h index 70b27de3b3..9e72b0b1be 100644 --- a/js/src/jit/LIR-Common.h +++ b/js/src/jit/LIR-Common.h @@ -712,16 +712,6 @@ class LValue : public LInstructionHelper } }; -class LNurseryObject : public LInstructionHelper<1, 0, 0> -{ - public: - LIR_HEADER(NurseryObject); - - MNurseryObject* mir() const { - return mir_->toNurseryObject(); - } -}; - // Clone an object literal such as we are not modifying the object contained in // the sources. class LCloneLiteral : public LCallInstructionHelper<1, 1, 0> diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h index 5ddba67444..3ffd11bc29 100644 --- a/js/src/jit/LOpcodes.h +++ b/js/src/jit/LOpcodes.h @@ -347,7 +347,6 @@ _(AssertResultT) \ _(LexicalCheck) \ _(ThrowUninitializedLexical) \ - _(NurseryObject) \ _(Debugger) \ _(NewTarget) \ _(ArrowNewTarget) diff --git a/js/src/jit/Linker.h b/js/src/jit/Linker.h index 810ee1cecf..9d715c7474 100644 --- a/js/src/jit/Linker.h +++ b/js/src/jit/Linker.h @@ -68,6 +68,7 @@ class Linker return nullptr; if (masm.oom()) return fail(cx); + AutoWritableJitCode awjc(result, bytesNeeded); code->copyFrom(masm); masm.link(code); if (masm.embedsNurseryPointers()) diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp index 68881a3398..a633badf28 100644 --- a/js/src/jit/Lowering.cpp +++ b/js/src/jit/Lowering.cpp @@ -456,7 +456,7 @@ LIRGenerator::visitCall(MCall* call) MOZ_ASSERT(ok, "How can we not have four temp registers?"); lir = new(alloc()) LCallDOMNative(tempFixed(cxReg), tempFixed(objReg), tempFixed(privReg), tempFixed(argsReg)); - } else if (target) { + } else if (target && !(target->isClassConstructor() && !call->isConstructing())) { // Call known functions. if (target->isNative()) { Register cxReg, numReg, vpReg, tmpReg; @@ -2226,11 +2226,18 @@ void LIRGenerator::visitInterruptCheck(MInterruptCheck* ins) { // Implicit interrupt checks require asm.js signal handlers to be installed. + // They also require writable JIT code: reprotecting in patchIonBackedges + // would be expensive and using AutoWritableJitCode in the signal handler + // is complicated because there could be another AutoWritableJitCode on the + // stack. LInstructionHelper<0, 0, 0>* lir; - if (GetJitContext()->runtime->canUseSignalHandlers()) + if (GetJitContext()->runtime->canUseSignalHandlers() && + !ExecutableAllocator::nonWritableJitCode) + { lir = new(alloc()) LInterruptCheckImplicit(); - else + } else { lir = new(alloc()) LInterruptCheck(); + } add(lir, ins); assignSafepoint(lir, ins); } @@ -4176,12 +4183,6 @@ LIRGenerator::visitDebugger(MDebugger* ins) add(lir, ins); } -void -LIRGenerator::visitNurseryObject(MNurseryObject* ins) -{ - define(new(alloc()) LNurseryObject(), ins); -} - static void SpewResumePoint(MBasicBlock* block, MInstruction* ins, MResumePoint* resumePoint) { diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h index adaa2ebe78..7386e0f663 100644 --- a/js/src/jit/Lowering.h +++ b/js/src/jit/Lowering.h @@ -295,7 +295,6 @@ class LIRGenerator : public LIRGeneratorSpecific void visitLexicalCheck(MLexicalCheck* ins); void visitThrowUninitializedLexical(MThrowUninitializedLexical* ins); void visitDebugger(MDebugger* ins); - void visitNurseryObject(MNurseryObject* ins); void visitNewTarget(MNewTarget* ins); void visitArrowNewTarget(MArrowNewTarget* ins); }; diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index a3ab226313..adc557fe16 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -583,7 +583,7 @@ IonBuilder::inlineArray(CallInfo& callInfo) callInfo.setImplicitlyUsedUnchecked(); - MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject); + MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject, this); current->add(templateConst); MNewArray* ins = MNewArray::New(alloc(), constraints(), initLength, templateConst, @@ -758,7 +758,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo) MDefinition* obj = callInfo.thisArg(); MDefinition* value = callInfo.getArg(0); - if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, + if (PropertyWriteNeedsTypeBarrier(this, constraints(), current, &obj, nullptr, &value, /* canModify = */ false)) { trackOptimizationOutcome(TrackedOutcome::NeedsTypeBarrier); @@ -1009,6 +1009,16 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) if (!templateObj) return InliningStatus_NotInlined; + if (unboxedType == JSVAL_TYPE_MAGIC) { + if (!templateObj->is()) + return InliningStatus_NotInlined; + } else { + if (!templateObj->is()) + return InliningStatus_NotInlined; + if (templateObj->as().elementType() != unboxedType) + return InliningStatus_NotInlined; + } + callInfo.setImplicitlyUsedUnchecked(); MDefinition* begin; @@ -1679,7 +1689,7 @@ IonBuilder::inlineConstantStringSplit(CallInfo& callInfo) if (conversion == TemporaryTypeSet::AlwaysConvertToDoubles) return InliningStatus_NotInlined; - MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject); + MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject, this); current->add(templateConst); MNewArray* ins = MNewArray::New(alloc(), constraints(), initLength, templateConst, @@ -1749,7 +1759,8 @@ IonBuilder::inlineStringSplit(CallInfo& callInfo) } callInfo.setImplicitlyUsedUnchecked(); - MConstant* templateObjectDef = MConstant::New(alloc(), ObjectValue(*templateObject), constraints()); + MConstant* templateObjectDef = MConstant::New(alloc(), ObjectValue(*templateObject), + constraints(), this); current->add(templateObjectDef); MStringSplit* ins = MStringSplit::New(alloc(), constraints(), callInfo.thisArg(), @@ -2074,7 +2085,7 @@ IonBuilder::inlineObjectCreate(CallInfo& callInfo) callInfo.setImplicitlyUsedUnchecked(); - MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject); + MConstant* templateConst = MConstant::NewConstraintlessObject(alloc(), templateObject, this); current->add(templateConst); MNewObject* ins = MNewObject::New(alloc(), constraints(), templateConst, templateObject->group()->initialHeap(constraints()), diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index b366bd7433..9ba746f7fc 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -625,17 +625,20 @@ MDefinition::emptyResultTypeSet() const } MConstant* -MConstant::New(TempAllocator& alloc, const Value& v, CompilerConstraintList* constraints) +MConstant::New(TempAllocator& alloc, const Value& v, + CompilerConstraintList* constraints, MIRGenerator* gen) { - return new(alloc) MConstant(v, constraints); + return new(alloc) MConstant(v, constraints, gen); } MConstant* -MConstant::NewTypedValue(TempAllocator& alloc, const Value& v, MIRType type, CompilerConstraintList* constraints) +MConstant::NewTypedValue(TempAllocator& alloc, const Value& v, MIRType type, + CompilerConstraintList* constraints, MIRGenerator* gen) { MOZ_ASSERT(!IsSimdType(type)); - MOZ_ASSERT_IF(type == MIRType_Float32, IsNaN(v.toDouble()) || v.toDouble() == double(float(v.toDouble()))); - MConstant* constant = new(alloc) MConstant(v, constraints); + MOZ_ASSERT_IF(type == MIRType_Float32, + IsNaN(v.toDouble()) || v.toDouble() == double(float(v.toDouble()))); + MConstant* constant = new(alloc) MConstant(v, constraints, gen); constant->setResultType(type); return constant; } @@ -649,9 +652,9 @@ MConstant::NewAsmJS(TempAllocator& alloc, const Value& v, MIRType type) } MConstant* -MConstant::NewConstraintlessObject(TempAllocator& alloc, JSObject* v) +MConstant::NewConstraintlessObject(TempAllocator& alloc, JSObject* v, MIRGenerator* gen) { - return new(alloc) MConstant(v); + return new(alloc) MConstant(v, gen); } static TemporaryTypeSet* @@ -707,14 +710,15 @@ jit::IonCompilationCanUseNurseryPointers() #endif // DEBUG -MConstant::MConstant(const js::Value& vp, CompilerConstraintList* constraints) +MConstant::MConstant(const js::Value& vp, CompilerConstraintList* constraints, MIRGenerator* gen) : value_(vp) { setResultType(MIRTypeFromValue(vp)); if (vp.isObject()) { // Create a singleton type set for the object. This isn't necessary for // other types as the result type encodes all needed information. - MOZ_ASSERT(!IsInsideNursery(&vp.toObject())); + MOZ_ASSERT(gen); + MOZ_ASSERT_IF(IsInsideNursery(&vp.toObject()), !gen->safeForMinorGC()); setResultTypeSet(MakeSingletonTypeSet(constraints, &vp.toObject())); } if (vp.isMagic() && vp.whyMagic() == JS_UNINITIALIZED_LEXICAL) { @@ -733,10 +737,11 @@ MConstant::MConstant(const js::Value& vp, CompilerConstraintList* constraints) setMovable(); } -MConstant::MConstant(JSObject* obj) +MConstant::MConstant(JSObject* obj, MIRGenerator* gen) : value_(ObjectValue(*obj)) { - MOZ_ASSERT(!IsInsideNursery(obj)); + MOZ_ASSERT(gen); + MOZ_ASSERT_IF(IsInsideNursery(obj), !gen->safeForMinorGC()); setResultType(MIRType_Object); setMovable(); } @@ -779,12 +784,12 @@ MConstant::printOpcode(GenericPrinter& out) const out.printf("0x%x", value().toInt32()); break; case MIRType_Double: - out.printf("%f", value().toDouble()); + out.printf("%.16g", value().toDouble()); break; case MIRType_Float32: { float val = value().toDouble(); - out.printf("%f", val); + out.printf("%.16g", val); break; } case MIRType_Object: @@ -846,39 +851,6 @@ MConstant::canProduceFloat32() const return true; } -MNurseryObject::MNurseryObject(JSObject* obj, uint32_t index, CompilerConstraintList* constraints) - : index_(index) -{ - setResultType(MIRType_Object); - - MOZ_ASSERT(IsInsideNursery(obj)); - MOZ_ASSERT(!obj->isSingleton()); - setResultTypeSet(MakeSingletonTypeSet(constraints, obj)); - - setMovable(); -} - -MNurseryObject* -MNurseryObject::New(TempAllocator& alloc, JSObject* obj, uint32_t index, - CompilerConstraintList* constraints) -{ - return new(alloc) MNurseryObject(obj, index, constraints); -} - -HashNumber -MNurseryObject::valueHash() const -{ - return HashNumber(index_); -} - -bool -MNurseryObject::congruentTo(const MDefinition* ins) const -{ - if (!ins->isNurseryObject()) - return false; - return ins->toNurseryObject()->index_ == index_; -} - MDefinition* MSimdValueX4::foldsTo(TempAllocator& alloc) { @@ -5002,7 +4974,8 @@ jit::PropertyReadNeedsTypeBarrier(JSContext* propertycx, } BarrierKind -jit::PropertyReadOnPrototypeNeedsTypeBarrier(CompilerConstraintList* constraints, +jit::PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder, + CompilerConstraintList* constraints, MDefinition* obj, PropertyName* name, TemporaryTypeSet* observed) { @@ -5024,7 +4997,8 @@ jit::PropertyReadOnPrototypeNeedsTypeBarrier(CompilerConstraintList* constraints return BarrierKind::TypeSet; if (!key->proto().isObject()) break; - key = TypeSet::ObjectKey::get(key->proto().toObject()); + JSObject* proto = builder->checkNurseryObject(key->proto().toObject()); + key = TypeSet::ObjectKey::get(proto); BarrierKind kind = PropertyReadNeedsTypeBarrier(constraints, key, name, observed); if (kind == BarrierKind::TypeSet) return BarrierKind::TypeSet; @@ -5216,18 +5190,18 @@ TryAddTypeBarrierForWrite(TempAllocator& alloc, CompilerConstraintList* constrai } static MInstruction* -AddGroupGuard(TempAllocator& alloc, MBasicBlock* current, MDefinition* obj, +AddGroupGuard(MIRGenerator* gen, MBasicBlock* current, MDefinition* obj, TypeSet::ObjectKey* key, bool bailOnEquality) { MInstruction* guard; if (key->isGroup()) { - guard = MGuardObjectGroup::New(alloc, obj, key->group(), bailOnEquality, + guard = MGuardObjectGroup::New(gen->alloc(), obj, key->group(), bailOnEquality, Bailout_ObjectIdentityOrTypeGuard); } else { - MConstant* singletonConst = MConstant::NewConstraintlessObject(alloc, key->singleton()); + MConstant* singletonConst = MConstant::NewConstraintlessObject(gen->alloc(), key->singleton(), gen); current->add(singletonConst); - guard = MGuardObjectIdentity::New(alloc, obj, singletonConst, bailOnEquality); + guard = MGuardObjectIdentity::New(gen->alloc(), obj, singletonConst, bailOnEquality); } current->add(guard); @@ -5250,7 +5224,7 @@ jit::CanWriteProperty(TempAllocator& alloc, CompilerConstraintList* constraints, } bool -jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList* constraints, +jit::PropertyWriteNeedsTypeBarrier(MIRGenerator* gen, CompilerConstraintList* constraints, MBasicBlock* current, MDefinition** pobj, PropertyName* name, MDefinition** pvalue, bool canModify, MIRType implicitType) @@ -5285,14 +5259,14 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList* jsid id = name ? NameToId(name) : JSID_VOID; HeapTypeSetKey property = key->property(id); - if (!CanWriteProperty(alloc, constraints, property, *pvalue, implicitType)) { + if (!CanWriteProperty(gen->alloc(), constraints, property, *pvalue, implicitType)) { // Either pobj or pvalue needs to be modified to filter out the // types which the value could have but are not in the property, // or a VM call is required. A VM call is always required if pobj // and pvalue cannot be modified. if (!canModify) return true; - success = TryAddTypeBarrierForWrite(alloc, constraints, current, types, name, pvalue, + success = TryAddTypeBarrierForWrite(gen->alloc(), constraints, current, types, name, pvalue, implicitType); break; } @@ -5306,10 +5280,10 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList* const UnboxedLayout& layout = key->group()->unboxedLayout(); if (name) { const UnboxedLayout::Property* property = layout.lookup(name); - if (property && !CanStoreUnboxedType(alloc, property->type, *pvalue)) + if (property && !CanStoreUnboxedType(gen->alloc(), property->type, *pvalue)) return true; } else { - if (layout.isArray() && !CanStoreUnboxedType(alloc, layout.elementType(), *pvalue)) + if (layout.isArray() && !CanStoreUnboxedType(gen->alloc(), layout.elementType(), *pvalue)) return true; } } @@ -5338,7 +5312,7 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList* jsid id = name ? NameToId(name) : JSID_VOID; HeapTypeSetKey property = key->property(id); - if (CanWriteProperty(alloc, constraints, property, *pvalue, implicitType)) + if (CanWriteProperty(gen->alloc(), constraints, property, *pvalue, implicitType)) continue; if ((property.maybeTypes() && !property.maybeTypes()->empty()) || excluded) @@ -5359,6 +5333,6 @@ jit::PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList* } } - *pobj = AddGroupGuard(alloc, current, *pobj, excluded, /* bailOnEquality = */ true); + *pobj = AddGroupGuard(gen, current, *pobj, excluded, /* bailOnEquality = */ true); return false; } diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index ade2d4865c..42ba4da442 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -1304,17 +1304,20 @@ class MConstant : public MNullaryInstruction Value value_; protected: - MConstant(const Value& v, CompilerConstraintList* constraints); - explicit MConstant(JSObject* obj); + MConstant(const Value& v, CompilerConstraintList* constraints, MIRGenerator* gen); + explicit MConstant(JSObject* obj, MIRGenerator* gen); public: INSTRUCTION_HEADER(Constant) static MConstant* New(TempAllocator& alloc, const Value& v, - CompilerConstraintList* constraints = nullptr); + CompilerConstraintList* constraints = nullptr, + MIRGenerator* gen = nullptr); static MConstant* NewTypedValue(TempAllocator& alloc, const Value& v, MIRType type, - CompilerConstraintList* constraints = nullptr); + CompilerConstraintList* constraints = nullptr, + MIRGenerator* gen = nullptr); static MConstant* NewAsmJS(TempAllocator& alloc, const Value& v, MIRType type); - static MConstant* NewConstraintlessObject(TempAllocator& alloc, JSObject* v); + static MConstant* NewConstraintlessObject(TempAllocator& alloc, JSObject* v, + MIRGenerator* gen); const js::Value& value() const { return value_; @@ -1356,33 +1359,6 @@ class MConstant : public MNullaryInstruction ALLOW_CLONE(MConstant) }; -class MNurseryObject : public MNullaryInstruction -{ - // Index in MIRGenerator::nurseryObjects_. - uint32_t index_; - - protected: - MNurseryObject(JSObject* obj, uint32_t index, CompilerConstraintList* constraints); - - public: - INSTRUCTION_HEADER(NurseryObject) - static MNurseryObject* New(TempAllocator& alloc, JSObject* obj, uint32_t index, - CompilerConstraintList* constraints = nullptr); - - HashNumber valueHash() const override; - bool congruentTo(const MDefinition* ins) const override; - - uint32_t index() const { - return index_; - } - - AliasSet getAliasSet() const override { - return AliasSet::None(); - } - - ALLOW_CLONE(MNurseryObject) -}; - // Generic constructor of SIMD valuesX4. class MSimdValueX4 : public MQuaternaryInstruction, @@ -13581,7 +13557,8 @@ BarrierKind PropertyReadNeedsTypeBarrier(JSContext* propertycx, CompilerConstraintList* constraints, MDefinition* obj, PropertyName* name, TemporaryTypeSet* observed); -BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(CompilerConstraintList* constraints, +BarrierKind PropertyReadOnPrototypeNeedsTypeBarrier(IonBuilder* builder, + CompilerConstraintList* constraints, MDefinition* obj, PropertyName* name, TemporaryTypeSet* observed); bool PropertyReadIsIdempotent(CompilerConstraintList* constraints, @@ -13591,7 +13568,7 @@ void AddObjectsForPropertyRead(MDefinition* obj, PropertyName* name, bool CanWriteProperty(TempAllocator& alloc, CompilerConstraintList* constraints, HeapTypeSetKey property, MDefinition* value, MIRType implicitType = MIRType_None); -bool PropertyWriteNeedsTypeBarrier(TempAllocator& alloc, CompilerConstraintList* constraints, +bool PropertyWriteNeedsTypeBarrier(MIRGenerator* gen, CompilerConstraintList* constraints, MBasicBlock* current, MDefinition** pobj, PropertyName* name, MDefinition** pvalue, bool canModify, MIRType implicitType = MIRType_None); diff --git a/js/src/jit/MIRGenerator.h b/js/src/jit/MIRGenerator.h index 52a07b50e7..6a1cd18e1e 100644 --- a/js/src/jit/MIRGenerator.h +++ b/js/src/jit/MIRGenerator.h @@ -94,6 +94,13 @@ class MIRGenerator return isProfilerInstrumentationEnabled() && !info().isAnalysis(); } + bool safeForMinorGC() const { + return safeForMinorGC_; + } + void setNotSafeForMinorGC() { + safeForMinorGC_ = false; + } + // Whether the main thread is trying to cancel this build. bool shouldCancel(const char* why) { maybePause(); @@ -195,12 +202,7 @@ class MIRGenerator bool instrumentedProfiling_; bool instrumentedProfilingIsCached_; - - // List of nursery objects used by this compilation. Can be traced by a - // minor GC while compilation happens off-thread. This Vector should only - // be accessed on the main thread (IonBuilder, nursery GC or - // CodeGenerator::link). - ObjectVector nurseryObjects_; + bool safeForMinorGC_; void addAbortedPreliminaryGroup(ObjectGroup* group); @@ -230,12 +232,6 @@ class MIRGenerator public: const JitCompileOptions options; - void traceNurseryObjects(JSTracer* trc); - - const ObjectVector& nurseryObjects() const { - return nurseryObjects_; - } - Label* conversionErrorLabel() const { MOZ_ASSERT((conversionErrorLabel_ != nullptr) == compilingAsmJS()); return conversionErrorLabel_; diff --git a/js/src/jit/MIRGraph.cpp b/js/src/jit/MIRGraph.cpp index 705d3ac740..beeaba3f9f 100644 --- a/js/src/jit/MIRGraph.cpp +++ b/js/src/jit/MIRGraph.cpp @@ -42,7 +42,7 @@ MIRGenerator::MIRGenerator(CompileCompartment* compartment, const JitCompileOpti modifiesFrameArguments_(false), instrumentedProfiling_(false), instrumentedProfilingIsCached_(false), - nurseryObjects_(*alloc), + safeForMinorGC_(true), outOfBoundsLabel_(outOfBoundsLabel), conversionErrorLabel_(conversionErrorLabel), #if defined(ASMJS_MAY_USE_SIGNAL_HANDLERS_FOR_OOB) diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h index 0ff24b5010..89dfded123 100644 --- a/js/src/jit/MOpcodes.h +++ b/js/src/jit/MOpcodes.h @@ -12,7 +12,6 @@ namespace jit { #define MIR_OPCODE_LIST(_) \ _(Constant) \ - _(NurseryObject) \ _(SimdBox) \ _(SimdUnbox) \ _(SimdValueX4) \ diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp index 193976e23b..b752f46217 100644 --- a/js/src/jit/MacroAssembler.cpp +++ b/js/src/jit/MacroAssembler.cpp @@ -29,45 +29,8 @@ using namespace js::jit; using JS::GenericNaN; using JS::ToInt32; -namespace { - -// Emulate a TypeSet logic from a Type object to avoid duplicating the guard -// logic. -class TypeWrapper { - TypeSet::Type t_; - - public: - explicit TypeWrapper(TypeSet::Type t) : t_(t) {} - - inline bool unknown() const { - return t_.isUnknown(); - } - inline bool hasType(TypeSet::Type t) const { - if (t == TypeSet::Int32Type()) - return t == t_ || t_ == TypeSet::DoubleType(); - return t == t_; - } - inline unsigned getObjectCount() const { - if (t_.isAnyObject() || t_.isUnknown() || !t_.isObject()) - return 0; - return 1; - } - inline JSObject* getSingletonNoBarrier(unsigned) const { - if (t_.isSingleton()) - return t_.singletonNoBarrier(); - return nullptr; - } - inline ObjectGroup* getGroupNoBarrier(unsigned) const { - if (t_.isGroup()) - return t_.groupNoBarrier(); - return nullptr; - } -}; - -} /* anonymous namespace */ - -template void -MacroAssembler::guardTypeSet(const Source& address, const Set* types, BarrierKind kind, +template void +MacroAssembler::guardTypeSet(const Source& address, const TypeSet *types, BarrierKind kind, Register scratch, Label* miss) { MOZ_ASSERT(kind == BarrierKind::TypeTagOnly || kind == BarrierKind::TypeSet); @@ -139,7 +102,7 @@ MacroAssembler::guardTypeSet(const Source& address, const Set* types, BarrierKin if (obj == scratch) extractObject(address, scratch); - guardTypeSetMightBeIncomplete(obj, scratch, &matched); + guardTypeSetMightBeIncomplete(types, obj, scratch, &matched); assumeUnreachable("Unexpected object type"); #endif @@ -148,29 +111,46 @@ MacroAssembler::guardTypeSet(const Source& address, const Set* types, BarrierKin bind(&matched); } +template void -MacroAssembler::guardTypeSetMightBeIncomplete(Register obj, Register scratch, Label* label) +MacroAssembler::guardTypeSetMightBeIncomplete(TypeSet* types, Register obj, Register scratch, Label* label) { // Type set guards might miss when an object's group changes. In this case - // either its properties will become unknown, or it will change to a native - // object with an original unboxed group. Jump to label if this might have - // happened for the input object. + // either its old group's properties will become unknown, or it will change + // to a native object with an original unboxed group. Jump to label if this + // might have happened for the input object. + + if (types->unknownObject()) { + jump(label); + return; + } loadPtr(Address(obj, JSObject::offsetOfGroup()), scratch); load32(Address(scratch, ObjectGroup::offsetOfFlags()), scratch); - branchTest32(Assembler::NonZero, scratch, Imm32(OBJECT_FLAG_UNKNOWN_PROPERTIES), label); and32(Imm32(OBJECT_FLAG_ADDENDUM_MASK), scratch); branch32(Assembler::Equal, scratch, Imm32(ObjectGroup::addendumOriginalUnboxedGroupValue()), label); + + for (size_t i = 0; i < types->getObjectCount(); i++) { + if (JSObject* singleton = types->getSingletonNoBarrier(i)) { + movePtr(ImmGCPtr(singleton), scratch); + loadPtr(Address(scratch, JSObject::offsetOfGroup()), scratch); + } else if (ObjectGroup* group = types->getGroupNoBarrier(i)) { + movePtr(ImmGCPtr(group), scratch); + } else { + continue; + } + branchTest32(Assembler::NonZero, Address(scratch, ObjectGroup::offsetOfFlags()), + Imm32(OBJECT_FLAG_UNKNOWN_PROPERTIES), label); + } } -template void -MacroAssembler::guardObjectType(Register obj, const Set* types, +void +MacroAssembler::guardObjectType(Register obj, const TypeSet* types, Register scratch, Label* miss) { MOZ_ASSERT(!types->unknown()); MOZ_ASSERT(!types->hasType(TypeSet::AnyObjectType())); - MOZ_ASSERT(types->getObjectCount()); MOZ_ASSERT(scratch != InvalidReg); // Note: this method elides read barriers on values read from type sets, as @@ -236,47 +216,16 @@ MacroAssembler::guardObjectType(Register obj, const Set* types, return; } -template void -MacroAssembler::guardType(const Source& address, TypeSet::Type type, - Register scratch, Label* miss) -{ - TypeWrapper wrapper(type); - guardTypeSet(address, &wrapper, BarrierKind::TypeSet, scratch, miss); -} - -template void MacroAssembler::guardTypeSet(const Address& address, const TemporaryTypeSet* types, - BarrierKind kind, Register scratch, Label* miss); -template void MacroAssembler::guardTypeSet(const ValueOperand& value, const TemporaryTypeSet* types, - BarrierKind kind, Register scratch, Label* miss); - -template void MacroAssembler::guardTypeSet(const Address& address, const HeapTypeSet* types, - BarrierKind kind, Register scratch, Label* miss); -template void MacroAssembler::guardTypeSet(const ValueOperand& value, const HeapTypeSet* types, - BarrierKind kind, Register scratch, Label* miss); -template void MacroAssembler::guardTypeSet(const TypedOrValueRegister& reg, const HeapTypeSet* types, - BarrierKind kind, Register scratch, Label* miss); - template void MacroAssembler::guardTypeSet(const Address& address, const TypeSet* types, BarrierKind kind, Register scratch, Label* miss); template void MacroAssembler::guardTypeSet(const ValueOperand& value, const TypeSet* types, BarrierKind kind, Register scratch, Label* miss); - -template void MacroAssembler::guardTypeSet(const Address& address, const TypeWrapper* types, - BarrierKind kind, Register scratch, Label* miss); -template void MacroAssembler::guardTypeSet(const ValueOperand& value, const TypeWrapper* types, +template void MacroAssembler::guardTypeSet(const TypedOrValueRegister& value, const TypeSet* types, BarrierKind kind, Register scratch, Label* miss); -template void MacroAssembler::guardObjectType(Register obj, const TemporaryTypeSet* types, - Register scratch, Label* miss); -template void MacroAssembler::guardObjectType(Register obj, const TypeSet* types, - Register scratch, Label* miss); -template void MacroAssembler::guardObjectType(Register obj, const TypeWrapper* types, - Register scratch, Label* miss); - -template void MacroAssembler::guardType(const Address& address, TypeSet::Type type, - Register scratch, Label* miss); -template void MacroAssembler::guardType(const ValueOperand& value, TypeSet::Type type, - Register scratch, Label* miss); +template void MacroAssembler::guardTypeSetMightBeIncomplete(const TemporaryTypeSet* types, + Register obj, Register scratch, + Label* label); template static void @@ -798,8 +747,16 @@ void MacroAssembler::loadUnboxedProperty(T address, JSValueType type, TypedOrValueRegister output) { switch (type) { + case JSVAL_TYPE_INT32: { + // Handle loading an int32 into a double reg. + if (output.type() == MIRType_Double) { + convertInt32ToDouble(address, output.typedReg().fpu()); + break; + } + // Fallthrough. + } + case JSVAL_TYPE_BOOLEAN: - case JSVAL_TYPE_INT32: case JSVAL_TYPE_STRING: { Register outReg; if (output.hasValue()) { diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index ed40938fb3..d60cf9526f 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -350,14 +350,13 @@ class MacroAssembler : public MacroAssemblerSpecific // Emits a test of a value against all types in a TypeSet. A scratch // register is required. - template - void guardTypeSet(const Source& address, const TypeSet* types, BarrierKind kind, Register scratch, Label* miss); - template - void guardObjectType(Register obj, const TypeSet* types, Register scratch, Label* miss); template - void guardType(const Source& address, TypeSet::Type type, Register scratch, Label* miss); + void guardTypeSet(const Source& address, const TypeSet* types, BarrierKind kind, Register scratch, Label* miss); - void guardTypeSetMightBeIncomplete(Register obj, Register scratch, Label* label); + void guardObjectType(Register obj, const TypeSet* types, Register scratch, Label* miss); + + template + void guardTypeSetMightBeIncomplete(TypeSet* types, Register obj, Register scratch, Label* label); void loadObjShape(Register objReg, Register dest) { loadPtr(Address(objReg, JSObject::offsetOfShape()), dest); @@ -942,6 +941,15 @@ class MacroAssembler : public MacroAssemblerSpecific branchTestClassIsProxy(proxy, scratch, label); } + void branchFunctionKind(Condition cond, JSFunction::FunctionKind kind, Register fun, + Register scratch, Label* label) + { + Address flags(fun, JSFunction::offsetOfFlags()); + load32(flags, scratch); + and32(Imm32(JSFunction::FUNCTION_KIND_MASK), scratch); + branch32(cond, scratch, Imm32(kind << JSFunction::FUNCTION_KIND_SHIFT), label); + } + public: #ifndef JS_CODEGEN_ARM64 // StackPointer manipulation functions. diff --git a/js/src/jit/VMFunctions.cpp b/js/src/jit/VMFunctions.cpp index 6e5003287d..b1c84a2d8d 100644 --- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -91,7 +91,7 @@ CheckOverRecursed(JSContext* cx) // - jitStackLimit was the real stack limit and we're over-recursed // - jitStackLimit was set to UINTPTR_MAX by JSRuntime::requestInterrupt // and we need to call JSRuntime::handleInterrupt. -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR JS_CHECK_SIMULATOR_RECURSION_WITH_EXTRA(cx, 0, return false); #else JS_CHECK_RECURSION(cx, return false); @@ -121,7 +121,7 @@ CheckOverRecursedWithExtra(JSContext* cx, BaselineFrame* frame, uint8_t spDummy; uint8_t* checkSp = (&spDummy) - extra; if (earlyCheck) { -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR (void)checkSp; JS_CHECK_SIMULATOR_RECURSION_WITH_EXTRA(cx, extra, frame->setOverRecursed()); #else @@ -135,7 +135,7 @@ CheckOverRecursedWithExtra(JSContext* cx, BaselineFrame* frame, if (frame->overRecursed()) return false; -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR JS_CHECK_SIMULATOR_RECURSION_WITH_EXTRA(cx, extra, return false); #else JS_CHECK_RECURSION_WITH_SP(cx, checkSp, return false); diff --git a/js/src/jit/arm/Architecture-arm.cpp b/js/src/jit/arm/Architecture-arm.cpp index 57c7c60299..f1f4117471 100644 --- a/js/src/jit/arm/Architecture-arm.cpp +++ b/js/src/jit/arm/Architecture-arm.cpp @@ -6,7 +6,7 @@ #include "jit/arm/Architecture-arm.h" -#ifndef JS_ARM_SIMULATOR +#ifndef JS_SIMULATOR_ARM #include #endif @@ -16,7 +16,7 @@ #include "jit/arm/Assembler-arm.h" #include "jit/RegisterSets.h" -#if !defined(__linux__) || defined(ANDROID) || defined(JS_ARM_SIMULATOR) +#if !defined(__linux__) || defined(ANDROID) || defined(JS_SIMULATOR_ARM) // The Android NDK and B2G do not include the hwcap.h kernel header, and it is not // defined when building the simulator, so inline the header defines we need. # define HWCAP_VFP (1 << 6) @@ -88,7 +88,7 @@ ParseARMCpuFeatures(const char* features, bool override = false) flags |= HWCAP_ARMv7; else if (count == 5 && strncmp(features, "align", 5) == 0) flags |= HWCAP_ALIGNMENT_FAULT; -#if defined(JS_ARM_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) else if (count == 6 && strncmp(features, "hardfp", 6) == 0) flags |= HWCAP_USE_HARDFP_ABI; #endif @@ -154,7 +154,7 @@ ParseARMHwCapFlags(const char* armHwCap) " vfpd32 \n" " armv7 \n" " align \n" -#if defined(JS_ARM_SIMULATOR) +#ifdef JS_SIMULATOR_ARM " hardfp \n" #endif "\n" @@ -186,7 +186,7 @@ InitARMFlags() if (ParseARMHwCapFlags(env)) return; -#ifdef JS_ARM_SIMULATOR +#ifdef JS_SIMULATOR_ARM flags = HWCAP_ARMv7 | HWCAP_VFP | HWCAP_VFPv3 | HWCAP_VFPv4 | HWCAP_NEON; #else @@ -245,7 +245,7 @@ InitARMFlags() flags |= HWCAP_ARMv7; #endif -#endif // JS_ARM_SIMULATOR +#endif // JS_SIMULATOR_ARM armHwCapFlags = CanonicalizeARMHwCapFlags(flags); @@ -304,7 +304,7 @@ bool HasIDIV() } // This is defined in the header and inlined when not using the simulator. -#if defined(JS_ARM_SIMULATOR) +#ifdef JS_SIMULATOR_ARM bool UseHardFpABI() { MOZ_ASSERT(armHwCapFlags != HWCAP_UNINITIALIZED); diff --git a/js/src/jit/arm/Architecture-arm.h b/js/src/jit/arm/Architecture-arm.h index fd07054c68..04831e368f 100644 --- a/js/src/jit/arm/Architecture-arm.h +++ b/js/src/jit/arm/Architecture-arm.h @@ -626,7 +626,7 @@ uint32_t GetARMFlags(); // If the simulator is used then the ABI choice is dynamic. Otherwise the ABI is // static and useHardFpABI is inlined so that unused branches can be optimized // away. -#if defined(JS_ARM_SIMULATOR) +#ifdef JS_SIMULATOR_ARM bool UseHardFpABI(); #else static inline bool UseHardFpABI() diff --git a/js/src/jit/arm/Assembler-arm.cpp b/js/src/jit/arm/Assembler-arm.cpp index 85918a3b1d..f78ee23c8c 100644 --- a/js/src/jit/arm/Assembler-arm.cpp +++ b/js/src/jit/arm/Assembler-arm.cpp @@ -26,12 +26,12 @@ void dbg_break() {} // Note this is used for inter-AsmJS calls and may pass arguments and results in // floating point registers even if the system ABI does not. -ABIArgGenerator::ABIArgGenerator() : - intRegIndex_(0), +ABIArgGenerator::ABIArgGenerator() + : intRegIndex_(0), floatRegIndex_(0), stackOffset_(0), current_() -{} +{ } ABIArg ABIArgGenerator::next(MIRType type) @@ -498,15 +498,17 @@ InstMOV::IsTHIS(const Instruction& i) } Op2Reg -Operand2::toOp2Reg() { +Operand2::toOp2Reg() const { return *(Op2Reg*)this; } + O2RegImmShift -Op2Reg::toO2RegImmShift() { +Op2Reg::toO2RegImmShift() const { return *(O2RegImmShift*)this; } + O2RegRegShift -Op2Reg::toO2RegRegShift() { +Op2Reg::toO2RegRegShift() const { return *(O2RegRegShift*)this; } @@ -529,7 +531,7 @@ Imm16::Imm16() { } void -jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label) +jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, ReprotectCode reprotect) { // We need to determine if this jump can fit into the standard 24+2 bit // address or if we need a larger branch (or just need to use our pool @@ -543,11 +545,18 @@ jit::PatchJump(CodeLocationJump& jump_, CodeLocationLabel label) int jumpOffset = label.raw() - jump_.raw(); if (BOffImm::IsInRange(jumpOffset)) { // This instruction started off as a branch, and will remain one. + MaybeAutoWritableJitCode awjc(jump, sizeof(Instruction), reprotect); Assembler::RetargetNearBranch(jump, jumpOffset, c); } else { // This instruction started off as a branch, but now needs to be demoted // to an ldr. uint8_t** slot = reinterpret_cast(jump_.jumpTableEntry()); + + // Ensure both the branch and the slot are writable. + MOZ_ASSERT(uintptr_t(slot) > uintptr_t(jump)); + size_t size = uintptr_t(slot) - uintptr_t(jump) + sizeof(void*); + MaybeAutoWritableJitCode awjc(jump, size, reprotect); + Assembler::RetargetFarBranch(jump, slot, label.raw(), c); } } @@ -805,12 +814,6 @@ TraceOneDataRelocation(JSTracer* trc, Iter* iter) const void* prior = Assembler::GetPtr32Target(iter, &dest, &rs); void* ptr = const_cast(prior); - // The low bit shouldn't be set. If it is, we probably got a dummy - // pointer inserted by CodeGenerator::visitNurseryObject, but we - // shouldn't be able to trigger GC before those are patched to their - // real values. - MOZ_ASSERT(!(uintptr_t(ptr) & 0x1)); - // No barrier needed since these are constants. TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast(&ptr), "ion-masm-ptr"); @@ -853,50 +856,6 @@ Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReade ::TraceDataRelocations(trc, code->raw(), reader); } -void -Assembler::FixupNurseryObjects(JSContext* cx, JitCode* code, CompactBufferReader& reader, - const ObjectVector& nurseryObjects) -{ - MOZ_ASSERT(!nurseryObjects.empty()); - - uint8_t* buffer = code->raw(); - bool hasNurseryPointers = false; - - while (reader.more()) { - size_t offset = reader.readUnsigned(); - InstructionIterator iter((Instruction*)(buffer + offset)); - Instruction* ins = iter.cur(); - Register dest; - Assembler::RelocStyle rs; - const void* prior = Assembler::GetPtr32Target(&iter, &dest, &rs); - void* ptr = const_cast(prior); - uintptr_t word = reinterpret_cast(ptr); - - if (!(word & 0x1)) - continue; - - uint32_t index = word >> 1; - JSObject* obj = nurseryObjects[index]; - MacroAssembler::ma_mov_patch(Imm32(int32_t(obj)), dest, Assembler::Always, rs, ins); - - if (rs != Assembler::L_LDR) { - // L_LDR won't cause any instructions to be updated. - AutoFlushICache::flush(uintptr_t(ins), 4); - AutoFlushICache::flush(uintptr_t(ins->next()), 4); - } - - // Either all objects are still in the nursery, or all objects are - // tenured. - MOZ_ASSERT_IF(hasNurseryPointers, IsInsideNursery(obj)); - - if (!hasNurseryPointers && IsInsideNursery(obj)) - hasNurseryPointers = true; - } - - if (hasNurseryPointers) - cx->runtime()->gc.storeBuffer.putWholeCellFromMainThread(code); -} - void Assembler::copyJumpRelocationTable(uint8_t* dest) { @@ -1257,7 +1216,7 @@ BOffImm::BOffImm(Instruction& inst) } Instruction* -BOffImm::getDest(Instruction* src) +BOffImm::getDest(Instruction* src) const { // TODO: It is probably worthwhile to verify that src is actually a branch. // NOTE: This does not explicitly shift the offset of the destination left by 2, @@ -1425,120 +1384,119 @@ Assembler::as_nop() } static uint32_t -EncodeAlu(Register dest, Register src1, Operand2 op2, ALUOp op, SetCond_ sc, - Assembler::Condition c) +EncodeAlu(Register dest, Register src1, Operand2 op2, ALUOp op, SBit s, Assembler::Condition c) { - return (int)op | (int)sc | (int) c | op2.encode() | + return (int)op | (int)s | (int)c | op2.encode() | ((dest == InvalidReg) ? 0 : RD(dest)) | ((src1 == InvalidReg) ? 0 : RN(src1)); } BufferOffset Assembler::as_alu(Register dest, Register src1, Operand2 op2, - ALUOp op, SetCond_ sc, Condition c) + ALUOp op, SBit s, Condition c) { - return writeInst(EncodeAlu(dest, src1, op2, op, sc, c)); + return writeInst(EncodeAlu(dest, src1, op2, op, s, c)); } BufferOffset -Assembler::as_mov(Register dest, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_mov(Register dest, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, InvalidReg, op2, OpMov, sc, c); + return as_alu(dest, InvalidReg, op2, OpMov, s, c); } /* static */ void -Assembler::as_alu_patch(Register dest, Register src1, Operand2 op2, ALUOp op, SetCond_ sc, +Assembler::as_alu_patch(Register dest, Register src1, Operand2 op2, ALUOp op, SBit s, Condition c, uint32_t* pos) { - WriteInstStatic(EncodeAlu(dest, src1, op2, op, sc, c), pos); + WriteInstStatic(EncodeAlu(dest, src1, op2, op, s, c), pos); } /* static */ void -Assembler::as_mov_patch(Register dest, Operand2 op2, SetCond_ sc, Condition c, uint32_t* pos) +Assembler::as_mov_patch(Register dest, Operand2 op2, SBit s, Condition c, uint32_t* pos) { - as_alu_patch(dest, InvalidReg, op2, OpMov, sc, c, pos); + as_alu_patch(dest, InvalidReg, op2, OpMov, s, c, pos); } BufferOffset -Assembler::as_mvn(Register dest, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_mvn(Register dest, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, InvalidReg, op2, OpMvn, sc, c); + return as_alu(dest, InvalidReg, op2, OpMvn, s, c); } // Logical operations. BufferOffset -Assembler::as_and(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_and(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpAnd, sc, c); + return as_alu(dest, src1, op2, OpAnd, s, c); } BufferOffset -Assembler::as_bic(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_bic(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpBic, sc, c); + return as_alu(dest, src1, op2, OpBic, s, c); } BufferOffset -Assembler::as_eor(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_eor(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpEor, sc, c); + return as_alu(dest, src1, op2, OpEor, s, c); } BufferOffset -Assembler::as_orr(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_orr(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpOrr, sc, c); + return as_alu(dest, src1, op2, OpOrr, s, c); } // Mathematical operations. BufferOffset -Assembler::as_adc(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_adc(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpAdc, sc, c); + return as_alu(dest, src1, op2, OpAdc, s, c); } BufferOffset -Assembler::as_add(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_add(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpAdd, sc, c); + return as_alu(dest, src1, op2, OpAdd, s, c); } BufferOffset -Assembler::as_sbc(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_sbc(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpSbc, sc, c); + return as_alu(dest, src1, op2, OpSbc, s, c); } BufferOffset -Assembler::as_sub(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_sub(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpSub, sc, c); + return as_alu(dest, src1, op2, OpSub, s, c); } BufferOffset -Assembler::as_rsb(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_rsb(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpRsb, sc, c); + return as_alu(dest, src1, op2, OpRsb, s, c); } BufferOffset -Assembler::as_rsc(Register dest, Register src1, Operand2 op2, SetCond_ sc, Condition c) +Assembler::as_rsc(Register dest, Register src1, Operand2 op2, SBit s, Condition c) { - return as_alu(dest, src1, op2, OpRsc, sc, c); + return as_alu(dest, src1, op2, OpRsc, s, c); } // Test operations. BufferOffset Assembler::as_cmn(Register src1, Operand2 op2, Condition c) { - return as_alu(InvalidReg, src1, op2, OpCmn, SetCond, c); + return as_alu(InvalidReg, src1, op2, OpCmn, SetCC, c); } BufferOffset Assembler::as_cmp(Register src1, Operand2 op2, Condition c) { - return as_alu(InvalidReg, src1, op2, OpCmp, SetCond, c); + return as_alu(InvalidReg, src1, op2, OpCmp, SetCC, c); } BufferOffset Assembler::as_teq(Register src1, Operand2 op2, Condition c) { - return as_alu(InvalidReg, src1, op2, OpTeq, SetCond, c); + return as_alu(InvalidReg, src1, op2, OpTeq, SetCC, c); } BufferOffset Assembler::as_tst(Register src1, Operand2 op2, Condition c) { - return as_alu(InvalidReg, src1, op2, OpTst, SetCond, c); + return as_alu(InvalidReg, src1, op2, OpTst, SetCC, c); } static MOZ_CONSTEXPR_VAR Register NoAddend = { Registers::pc }; @@ -1619,59 +1577,59 @@ static const int mull_tag = 0x90; BufferOffset Assembler::as_genmul(Register dhi, Register dlo, Register rm, Register rn, - MULOp op, SetCond_ sc, Condition c) + MULOp op, SBit s, Condition c) { - return writeInst(RN(dhi) | maybeRD(dlo) | RM(rm) | rn.code() | op | sc | c | mull_tag); + return writeInst(RN(dhi) | maybeRD(dlo) | RM(rm) | rn.code() | op | s | c | mull_tag); } BufferOffset -Assembler::as_mul(Register dest, Register src1, Register src2, SetCond_ sc, Condition c) +Assembler::as_mul(Register dest, Register src1, Register src2, SBit s, Condition c) { - return as_genmul(dest, InvalidReg, src1, src2, OpmMul, sc, c); + return as_genmul(dest, InvalidReg, src1, src2, OpmMul, s, c); } BufferOffset Assembler::as_mla(Register dest, Register acc, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(dest, acc, src1, src2, OpmMla, sc, c); + return as_genmul(dest, acc, src1, src2, OpmMla, s, c); } BufferOffset Assembler::as_umaal(Register destHI, Register destLO, Register src1, Register src2, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmUmaal, NoSetCond, c); + return as_genmul(destHI, destLO, src1, src2, OpmUmaal, LeaveCC, c); } BufferOffset Assembler::as_mls(Register dest, Register acc, Register src1, Register src2, Condition c) { - return as_genmul(dest, acc, src1, src2, OpmMls, NoSetCond, c); + return as_genmul(dest, acc, src1, src2, OpmMls, LeaveCC, c); } BufferOffset Assembler::as_umull(Register destHI, Register destLO, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmUmull, sc, c); + return as_genmul(destHI, destLO, src1, src2, OpmUmull, s, c); } BufferOffset Assembler::as_umlal(Register destHI, Register destLO, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmUmlal, sc, c); + return as_genmul(destHI, destLO, src1, src2, OpmUmlal, s, c); } BufferOffset Assembler::as_smull(Register destHI, Register destLO, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmSmull, sc, c); + return as_genmul(destHI, destLO, src1, src2, OpmSmull, s, c); } BufferOffset Assembler::as_smlal(Register destHI, Register destLO, Register src1, Register src2, - SetCond_ sc, Condition c) + SBit s, Condition c) { - return as_genmul(destHI, destLO, src1, src2, OpmSmlal, sc, c); + return as_genmul(destHI, destLO, src1, src2, OpmSmlal, s, c); } BufferOffset @@ -1716,7 +1674,8 @@ Assembler::as_dtr_patch(LoadStore ls, int size, Index mode, Register rt, DTRAddr WriteInstStatic(EncodeDtr(ls, size, mode, rt, addr, c), dest); } -class PoolHintData { +class PoolHintData +{ public: enum LoadType { // Set 0 to bogus, since that is the value most likely to be @@ -1759,19 +1718,19 @@ class PoolHintData { destReg_ = destReg.id(); destType_ = destReg.isDouble(); } - Assembler::Condition getCond() { + Assembler::Condition getCond() const { return Assembler::Condition(cond_ << 28); } - Register getReg() { + Register getReg() const { return Register::FromCode(destReg_); } - VFPRegister getVFPReg() { + VFPRegister getVFPReg() const { VFPRegister r = VFPRegister(destReg_, destType_ ? VFPRegister::Double : VFPRegister::Single); return r; } - int32_t getIndex() { + int32_t getIndex() const { return index_; } void setIndex(uint32_t index) { @@ -1780,7 +1739,7 @@ class PoolHintData { MOZ_ASSERT(index_ == index); } - LoadType getLoadType() { + LoadType getLoadType() const { // If this *was* a PoolBranch, but the branch has already been bound // then this isn't going to look like a real poolhintdata, but we still // want to lie about it so everyone knows it *used* to be a branch. @@ -1789,7 +1748,7 @@ class PoolHintData { return loadType_; } - bool isValidPoolHint() { + bool isValidPoolHint() const { // Most instructions cannot have a condition that is 0xf. Notable // exceptions are blx and the entire NEON instruction set. For the // purposes of pool loads, and possibly patched branches, the possible @@ -1799,7 +1758,8 @@ class PoolHintData { } }; -union PoolHintPun { +union PoolHintPun +{ PoolHintData phd; uint32_t raw; }; @@ -1844,8 +1804,7 @@ BufferOffset Assembler::as_dtm(LoadStore ls, Register rn, uint32_t mask, DTMMode mode, DTMWriteBack wb, Condition c) { - return writeInst(0x08000000 | RN(rn) | ls | - mode | mask | c | wb); + return writeInst(0x08000000 | RN(rn) | ls | mode | mask | c | wb); } BufferOffset @@ -2056,12 +2015,14 @@ Assembler::as_bx(Register r, Condition c) BufferOffset ret = writeInst(((int) c) | OpBx | r.code()); return ret; } + void Assembler::WritePoolGuard(BufferOffset branch, Instruction* dest, BufferOffset afterPool) { BOffImm off = afterPool.diffB(branch); *dest = InstBImm(off, Always); } + // Branch can branch to an immediate *or* to a register. // Branches to immediates are pc relative, branches to registers are absolute. BufferOffset @@ -2106,6 +2067,7 @@ Assembler::as_b(Label* l, Condition c) MOZ_ASSERT(check == old); return ret; } + BufferOffset Assembler::as_b(BOffImm off, Condition c, BufferOffset inst) { @@ -2168,6 +2130,7 @@ Assembler::as_bl(Label* l, Condition c) MOZ_ASSERT(check == old); return ret; } + BufferOffset Assembler::as_bl(BOffImm off, Condition c, BufferOffset inst) { @@ -2195,6 +2158,7 @@ enum vfp_tags { VfpTag = 0x0C000A00, VfpArith = 0x02000000 }; + BufferOffset Assembler::writeVFPInst(vfp_size sz, uint32_t blob) { @@ -2225,43 +2189,37 @@ Assembler::as_vfp_float(VFPRegister vd, VFPRegister vn, VFPRegister vm, } BufferOffset -Assembler::as_vadd(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vadd(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvAdd, c); } BufferOffset -Assembler::as_vdiv(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vdiv(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvDiv, c); } BufferOffset -Assembler::as_vmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvMul, c); } BufferOffset -Assembler::as_vnmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vnmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvMul, c); } BufferOffset -Assembler::as_vnmla(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vnmla(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { MOZ_CRASH("Feature NYI"); } BufferOffset -Assembler::as_vnmls(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vnmls(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { MOZ_CRASH("Feature NYI"); } @@ -2285,18 +2243,17 @@ Assembler::as_vabs(VFPRegister vd, VFPRegister vm, Condition c) } BufferOffset -Assembler::as_vsub(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c) +Assembler::as_vsub(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c) { return as_vfp_float(vd, vn, vm, OpvSub, c); } BufferOffset -Assembler::as_vcmp(VFPRegister vd, VFPRegister vm, - Condition c) +Assembler::as_vcmp(VFPRegister vd, VFPRegister vm, Condition c) { return as_vfp_float(vd, NoVFPRegister, vm, OpvCmp, c); } + BufferOffset Assembler::as_vcmpz(VFPRegister vd, Condition c) { @@ -2309,6 +2266,7 @@ Assembler::as_vmov(VFPRegister vd, VFPRegister vsrc, Condition c) { return as_vfp_float(vd, NoVFPRegister, vsrc, OpvMov, c); } + // Transfer between Core and VFP. // Unlike the next function, moving between the core registers and vfp registers @@ -2339,15 +2297,13 @@ Assembler::as_vxfer(Register vt1, Register vt2, VFPRegister vm, FloatToCore_ f2c MOZ_ASSERT(idx == 0); } - if (vt2 == InvalidReg) { - return writeVFPInst(sz, WordTransfer | f2c | c | - RT(vt1) | maybeRN(vt2) | VN(vm) | idx); - } else { - // We are doing a 64 bit transfer. - return writeVFPInst(sz, DoubleTransfer | f2c | c | - RT(vt1) | maybeRN(vt2) | VM(vm) | idx); - } + if (vt2 == InvalidReg) + return writeVFPInst(sz, WordTransfer | f2c | c | RT(vt1) | maybeRN(vt2) | VN(vm) | idx); + + // We are doing a 64 bit transfer. + return writeVFPInst(sz, DoubleTransfer | f2c | c | RT(vt1) | maybeRN(vt2) | VM(vm) | idx); } + enum vcvt_destFloatness { VcvtToInteger = 1 << 18, VcvtToFloat = 0 << 18 @@ -2384,9 +2340,9 @@ Assembler::as_vcvt(VFPRegister vd, VFPRegister vm, bool useFPSCR, vcvt_Signedness opSign; vcvt_toZero doToZero = VcvtToFPSCR; MOZ_ASSERT(vd.isFloat() || vm.isFloat()); - if (vd.isSingle() || vm.isSingle()) { + if (vd.isSingle() || vm.isSingle()) sz = IsSingle; - } + if (vd.isFloat()) { destFloat = VcvtToFloat; opSign = (vm.isSInt()) ? VcvtFromSigned : VcvtFromUnsigned; @@ -2459,6 +2415,7 @@ Assembler::as_vimm(VFPRegister vd, VFPImm imm, Condition c) return writeVFPInst(sz, c | imm.encode() | VD(vd) | 0x02B00000); } + BufferOffset Assembler::as_vmrs(Register r, Condition c) { @@ -2585,7 +2542,6 @@ Assembler::retarget(Label* label, Label* target) } - static int stopBKPT = -1; void Assembler::as_bkpt() @@ -2640,6 +2596,7 @@ Assembler::GetBranchOffset(const Instruction* i_) i->extractImm(&dest); return dest.decode(); } + void Assembler::RetargetNearBranch(Instruction* i, int offset, bool final) { @@ -2675,7 +2632,8 @@ Assembler::RetargetFarBranch(Instruction* i, uint8_t** slot, uint8_t* dest, Cond } -struct PoolHeader : Instruction { +struct PoolHeader : Instruction +{ struct Header { // The size should take into account the pool header. @@ -2716,6 +2674,7 @@ struct PoolHeader : Instruction { Header tmp(this); return tmp.isNatural; } + static bool IsTHIS(const Instruction& i) { return (*i.raw() & 0xffff0000) == 0xffff0000; } @@ -2726,11 +2685,10 @@ struct PoolHeader : Instruction { } }; - void Assembler::WritePoolHeader(uint8_t* start, Pool* p, bool isNatural) { - STATIC_ASSERT(sizeof(PoolHeader) == 4); + static_assert(sizeof(PoolHeader) == 4, "PoolHandler must have the correct size."); uint8_t* pool = start + 4; // Go through the usual rigmarole to get the size of the pool. pool += p->getPoolSize(); @@ -2742,7 +2700,6 @@ Assembler::WritePoolHeader(uint8_t* start, Pool* p, bool isNatural) *(PoolHeader*)start = header; } - // The size of an arbitrary 32-bit call in the instruction stream. On ARM this // sequence is |pc = ldr pc - 4; imm32| given that we never reach the imm32. uint32_t @@ -2750,6 +2707,7 @@ Assembler::PatchWrite_NearCallSize() { return sizeof(uint32_t); } + void Assembler::PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall) { @@ -2761,8 +2719,8 @@ Assembler::PatchWrite_NearCall(CodeLocationLabel start, CodeLocationLabel toCall new (inst) InstBLImm(BOffImm(dest - (uint8_t*)inst) , Always); // Ensure everyone sees the code that was just written into memory. AutoFlushICache::flush(uintptr_t(inst), 4); - } + void Assembler::PatchDataWithValueCheck(CodeLocationLabel label, PatchedImmPtr newValue, PatchedImmPtr expectedValue) @@ -2803,7 +2761,6 @@ Assembler::PatchWrite_Imm32(CodeLocationLabel label, Imm32 imm) { *(raw - 1) = imm.value; } - uint8_t* Assembler::NextInstruction(uint8_t* inst_, uint32_t* count) { @@ -2828,7 +2785,8 @@ InstIsGuard(Instruction* inst, const PoolHeader** ph) } static bool -InstIsBNop(Instruction* inst) { +InstIsBNop(Instruction* inst) +{ // In some special situations, it is necessary to insert a NOP into the // instruction stream that nobody knows about, since nobody should know // about it, make sure it gets skipped when Instruction::next() is called. @@ -3031,13 +2989,14 @@ void Assembler::UpdateBoundsCheck(uint32_t heapSize, Instruction* inst) Imm8 imm8 = Imm8(heapSize); MOZ_ASSERT(!imm8.invalid); - *inst = InstALU(InvalidReg, index, imm8, OpCmp, SetCond, Always); + *inst = InstALU(InvalidReg, index, imm8, OpCmp, SetCC, Always); // NOTE: we don't update the Auto Flush Cache! this function is currently // only called from within AsmJSModule::patchHeapAccesses, which does that // for us. Don't call this! } -InstructionIterator::InstructionIterator(Instruction* i_) : i(i_) +InstructionIterator::InstructionIterator(Instruction* i_) + : i(i_) { // Work around pools with an artificial pool guard and around nop-fill. i = i->skipPool(); diff --git a/js/src/jit/arm/Assembler-arm.h b/js/src/jit/arm/Assembler-arm.h index 66262de825..f45613cb0d 100644 --- a/js/src/jit/arm/Assembler-arm.h +++ b/js/src/jit/arm/Assembler-arm.h @@ -74,9 +74,11 @@ class ABIArgGenerator public: ABIArgGenerator(); + ABIArg next(MIRType argType); ABIArg& current() { return current_; } uint32_t stackBytesConsumedSoFar() const { return stackOffset_; } + static const Register NonArgReturnReg0; static const Register NonArgReturnReg1; static const Register NonReturn_VolatileReg0; @@ -237,7 +239,6 @@ enum IsImmEDTR_ { IsNotImmEDTR = 0 << 22 }; - enum ShiftType { LSL = 0, // << 5 LSR = 1, // << 5 @@ -273,14 +274,17 @@ enum DTMWriteBack { NoWriteBack = 0 << 21 }; -enum SetCond_ { - SetCond = 1 << 20, - NoSetCond = 0 << 20 +// Condition code updating mode. +enum SBit { + SetCC = 1 << 20, // Set condition code. + LeaveCC = 0 << 20 // Leave condition code unchanged. }; + enum LoadStore { IsLoad = 1 << 20, IsStore = 0 << 20 }; + // You almost never want to use this directly. Instead, you wantto pass in a // signed constant, and let this bit be implicitly set for you. This is however, // necessary if we want a negative index. @@ -341,16 +345,19 @@ enum VFPOp { OpvCmp = 0xB << 20 | 0x1 << 6 | 0x4 << 16, OpvCmpz = 0xB << 20 | 0x1 << 6 | 0x5 << 16 }; + // Negate the operation, AND negate the immediate that we were passed in. ALUOp ALUNeg(ALUOp op, Register dest, Imm32* imm, Register* negDest); bool can_dbl(ALUOp op); bool condsAreSafe(ALUOp op); + // If there is a variant of op that has a dest (think cmp/sub) return that // variant of it. ALUOp getDestVariant(ALUOp op); static const ValueOperand JSReturnOperand = ValueOperand(JSReturnReg_Type, JSReturnReg_Data); static const ValueOperand softfpReturnOperand = ValueOperand(r1, r0); + // All of these classes exist solely to shuffle data into the various operands. // For example Operand2 can be an imm8, a register-shifted-by-a-constant or a // register-shifted-by-a-register. We represent this in C++ by having a base @@ -372,7 +379,9 @@ static const ValueOperand softfpReturnOperand = ValueOperand(r1, r0); class Op2Reg; class O2RegImmShift; class O2RegRegShift; + namespace datastore { + struct Reg { // The "second register". @@ -389,12 +398,13 @@ struct Reg : RM(rm), RRS(rsr), Type(type), ShiftAmount(shiftamount), pad(0) { } - uint32_t encode() { - return RM | RRS << 4 | Type << 5 | ShiftAmount << 7; - } explicit Reg(const Op2Reg& op) { memcpy(this, &op, sizeof(*this)); } + + uint32_t encode() const { + return RM | RRS << 4 | Type << 5 | ShiftAmount << 7; + } }; // Op2 has a mode labelled "", which is arm's magical immediate encoding. @@ -409,10 +419,12 @@ struct Imm8mData // if we can encode it properly, a simple "|" will still suffice to meld it // into the instruction. uint32_t buff : 19; + public: uint32_t invalid : 1; - uint32_t encode() { + public: + uint32_t encode() const { MOZ_ASSERT(!invalid); return data | rot << 8; }; @@ -438,12 +450,16 @@ struct Imm8Data uint32_t imm4H : 4; public: - uint32_t encode() { - return imm4L | (imm4H << 8); - }; - Imm8Data(uint32_t imm) : imm4L(imm & 0xf), imm4H(imm >> 4) { + Imm8Data(uint32_t imm) + : imm4L(imm & 0xf), imm4H(imm >> 4) + { MOZ_ASSERT(imm <= 0xff); } + + public: + uint32_t encode() const { + return imm4L | (imm4H << 8); + }; }; // VLDR/VSTR take an 8 bit offset, which is implicitly left shifted by 2. @@ -453,12 +469,16 @@ struct Imm8VFPOffData uint32_t data; public: - uint32_t encode() { - return data; - }; - Imm8VFPOffData(uint32_t imm) : data (imm) { + Imm8VFPOffData(uint32_t imm) + : data (imm) + { MOZ_ASSERT((imm & ~(0xff)) == 0); } + + public: + uint32_t encode() const { + return data; + }; }; // ARM can magically encode 256 very special immediates to be moved into a @@ -478,7 +498,7 @@ struct Imm8VFPImmData uint32_t imm4H : 4; int32_t isInvalid : 24; - uint32_t encode() { + uint32_t encode() const { // This assert is an attempting at ensuring that we don't create random // instances of this structure and then asking to encode() it. MOZ_ASSERT(isInvalid == 0); @@ -489,9 +509,6 @@ struct Imm8VFPImmData struct Imm12Data { uint32_t data : 12; - uint32_t encode() { - return data; - } Imm12Data(uint32_t imm) : data(imm) @@ -499,21 +516,28 @@ struct Imm12Data MOZ_ASSERT(data == imm); } + uint32_t encode() const { + return data; + } }; struct RIS { uint32_t ShiftAmount : 5; - uint32_t encode () { - return ShiftAmount; - } RIS(uint32_t imm) : ShiftAmount(imm) { MOZ_ASSERT(ShiftAmount == imm); } - explicit RIS(Reg r) : ShiftAmount(r.ShiftAmount) {} + + explicit RIS(Reg r) + : ShiftAmount(r.ShiftAmount) + { } + + uint32_t encode() const { + return ShiftAmount; + } }; struct RRS @@ -528,7 +552,7 @@ struct RRS MOZ_ASSERT(rs == RS); } - uint32_t encode () { + uint32_t encode() const { return RS << 1; } }; @@ -542,40 +566,49 @@ class Operand2 friend class Operand; friend class MacroAssemblerARM; friend class InstALU; + public: uint32_t oper : 31; uint32_t invalid : 1; - bool isO2Reg() { - return !(oper & IsImmOp2); - } - Op2Reg toOp2Reg(); - bool isImm8() { - return oper & IsImmOp2; - } protected: - Operand2(datastore::Imm8mData base) + explicit Operand2(datastore::Imm8mData base) : oper(base.invalid ? -1 : (base.encode() | (uint32_t)IsImmOp2)), invalid(base.invalid) { } - Operand2(datastore::Reg base) + explicit Operand2(datastore::Reg base) : oper(base.encode() | (uint32_t)IsNotImmOp2) { } private: - Operand2(int blob) + explicit Operand2(int blob) : oper(blob) { } public: - uint32_t encode() { + bool isO2Reg() const { + return !(oper & IsImmOp2); + } + + Op2Reg toOp2Reg() const; + + bool isImm8() const { + return oper & IsImmOp2; + } + + uint32_t encode() const { return oper; } }; class Imm8 : public Operand2 { + public: + explicit Imm8(uint32_t imm) + : Operand2(EncodeImm(imm)) + { } + public: static datastore::Imm8mData EncodeImm(uint32_t imm) { // mozilla::CountLeadingZeroes32(imm) requires imm != 0. @@ -607,6 +640,7 @@ class Imm8 : public Operand2 return datastore::Imm8mData(mask, (8 - right) >> 1); return datastore::Imm8mData(); } + // Pair template? struct TwoImm8mData { @@ -622,41 +656,41 @@ class Imm8 : public Operand2 }; static TwoImm8mData EncodeTwoImms(uint32_t); - Imm8(uint32_t imm) - : Operand2(EncodeImm(imm)) - { } }; class Op2Reg : public Operand2 { public: - Op2Reg(Register rm, ShiftType type, datastore::RIS shiftImm) + explicit Op2Reg(Register rm, ShiftType type, datastore::RIS shiftImm) : Operand2(datastore::Reg(rm.code(), type, 0, shiftImm.encode())) { } - Op2Reg(Register rm, ShiftType type, datastore::RRS shiftReg) + explicit Op2Reg(Register rm, ShiftType type, datastore::RRS shiftReg) : Operand2(datastore::Reg(rm.code(), type, 1, shiftReg.encode())) { } - bool isO2RegImmShift() { + + public: + bool isO2RegImmShift() const { datastore::Reg r(*this); return !r.RRS; } - O2RegImmShift toO2RegImmShift(); - bool isO2RegRegShift() { + O2RegImmShift toO2RegImmShift() const; + + bool isO2RegRegShift() const { datastore::Reg r(*this); return r.RRS; } - O2RegRegShift toO2RegRegShift(); + O2RegRegShift toO2RegRegShift() const; - bool checkType(ShiftType type) { + bool checkType(ShiftType type) const { datastore::Reg r(*this); return r.Type == type; } - bool checkRM(Register rm) { + bool checkRM(Register rm) const { datastore::Reg r(*this); return r.RM == rm.code(); } - bool getRM(Register* rm) { + bool getRM(Register* rm) const { datastore::Reg r(*this); *rm = Register::FromCode(r.RM); return true; @@ -666,10 +700,12 @@ class Op2Reg : public Operand2 class O2RegImmShift : public Op2Reg { public: - O2RegImmShift(Register rn, ShiftType type, uint32_t shift) + explicit O2RegImmShift(Register rn, ShiftType type, uint32_t shift) : Op2Reg(rn, type, datastore::RIS(shift)) { } - int getShift() { + + public: + int getShift() const { datastore::Reg r(*this); datastore::RIS ris(r); return ris.ShiftAmount; @@ -679,22 +715,22 @@ class O2RegImmShift : public Op2Reg class O2RegRegShift : public Op2Reg { public: - O2RegRegShift(Register rn, ShiftType type, Register rs) + explicit O2RegRegShift(Register rn, ShiftType type, Register rs) : Op2Reg(rn, type, datastore::RRS(rs.code())) { } }; O2RegImmShift O2Reg(Register r); -O2RegImmShift lsl (Register r, int amt); -O2RegImmShift lsr (Register r, int amt); -O2RegImmShift asr (Register r, int amt); -O2RegImmShift rol (Register r, int amt); -O2RegImmShift ror (Register r, int amt); +O2RegImmShift lsl(Register r, int amt); +O2RegImmShift lsr(Register r, int amt); +O2RegImmShift asr(Register r, int amt); +O2RegImmShift rol(Register r, int amt); +O2RegImmShift ror(Register r, int amt); -O2RegRegShift lsl (Register r, Register amt); -O2RegRegShift lsr (Register r, Register amt); -O2RegRegShift asr (Register r, Register amt); -O2RegRegShift ror (Register r, Register amt); +O2RegRegShift lsl(Register r, Register amt); +O2RegRegShift lsr(Register r, Register amt); +O2RegRegShift asr(Register r, Register amt); +O2RegRegShift ror(Register r, Register amt); // An offset from a register to be used for ldr/str. This should include the // sign bit, since ARM has "signed-magnitude" offsets. That is it encodes an @@ -706,22 +742,22 @@ class DtrOff uint32_t data; protected: - DtrOff(datastore::Imm12Data immdata, IsUp_ iu) + explicit DtrOff(datastore::Imm12Data immdata, IsUp_ iu) : data(immdata.encode() | (uint32_t)IsImmDTR | ((uint32_t)iu)) { } - DtrOff(datastore::Reg reg, IsUp_ iu = IsUp) + explicit DtrOff(datastore::Reg reg, IsUp_ iu = IsUp) : data(reg.encode() | (uint32_t) IsNotImmDTR | iu) { } public: - uint32_t encode() { return data; } + uint32_t encode() const { return data; } }; class DtrOffImm : public DtrOff { public: - DtrOffImm(int32_t imm) + explicit DtrOffImm(int32_t imm) : DtrOff(datastore::Imm12Data(mozilla::Abs(imm)), imm >= 0 ? IsUp : IsDown) { MOZ_ASSERT(mozilla::Abs(imm) < 4096); @@ -733,11 +769,11 @@ class DtrOffReg : public DtrOff // These are designed to be called by a constructor of a subclass. // Constructing the necessary RIS/RRS structures are annoying. protected: - DtrOffReg(Register rn, ShiftType type, datastore::RIS shiftImm, IsUp_ iu = IsUp) + explicit DtrOffReg(Register rn, ShiftType type, datastore::RIS shiftImm, IsUp_ iu = IsUp) : DtrOff(datastore::Reg(rn.code(), type, 0, shiftImm.encode()), iu) { } - DtrOffReg(Register rn, ShiftType type, datastore::RRS shiftReg, IsUp_ iu = IsUp) + explicit DtrOffReg(Register rn, ShiftType type, datastore::RRS shiftReg, IsUp_ iu = IsUp) : DtrOff(datastore::Reg(rn.code(), type, 1, shiftReg.encode()), iu) { } }; @@ -745,7 +781,7 @@ class DtrOffReg : public DtrOff class DtrRegImmShift : public DtrOffReg { public: - DtrRegImmShift(Register rn, ShiftType type, uint32_t shift, IsUp_ iu = IsUp) + explicit DtrRegImmShift(Register rn, ShiftType type, uint32_t shift, IsUp_ iu = IsUp) : DtrOffReg(rn, type, datastore::RIS(shift), iu) { } }; @@ -753,7 +789,7 @@ class DtrRegImmShift : public DtrOffReg class DtrRegRegShift : public DtrOffReg { public: - DtrRegRegShift(Register rn, ShiftType type, Register rs, IsUp_ iu = IsUp) + explicit DtrRegRegShift(Register rn, ShiftType type, Register rs, IsUp_ iu = IsUp) : DtrOffReg(rn, type, datastore::RRS(rs.code()), iu) { } }; @@ -762,24 +798,28 @@ class DtrRegRegShift : public DtrOffReg // an "operand" to a load instruction. class DTRAddr { + friend class Operand; + uint32_t data; public: - DTRAddr(Register reg, DtrOff dtr) + explicit DTRAddr(Register reg, DtrOff dtr) : data(dtr.encode() | (reg.code() << 16)) { } - uint32_t encode() { - return data; - } - Register getBase() { - return Register::FromCode((data >> 16) &0xf); - } private: - friend class Operand; - DTRAddr(uint32_t blob) + explicit DTRAddr(uint32_t blob) : data(blob) { } + + public: + uint32_t encode() const { + return data; + } + + Register getBase() const { + return Register::FromCode((data >> 16) &0xf); + } }; // Offsets for the extended data transfer instructions: @@ -789,16 +829,16 @@ class EDtrOff uint32_t data; protected: - EDtrOff(datastore::Imm8Data imm8, IsUp_ iu = IsUp) + explicit EDtrOff(datastore::Imm8Data imm8, IsUp_ iu = IsUp) : data(imm8.encode() | IsImmEDTR | (uint32_t)iu) { } - EDtrOff(Register rm, IsUp_ iu = IsUp) + explicit EDtrOff(Register rm, IsUp_ iu = IsUp) : data(rm.code() | IsNotImmEDTR | iu) { } public: - uint32_t encode() { + uint32_t encode() const { return data; } }; @@ -806,7 +846,7 @@ class EDtrOff class EDtrOffImm : public EDtrOff { public: - EDtrOffImm(int32_t imm) + explicit EDtrOffImm(int32_t imm) : EDtrOff(datastore::Imm8Data(mozilla::Abs(imm)), (imm >= 0) ? IsUp : IsDown) { MOZ_ASSERT(mozilla::Abs(imm) < 256); @@ -818,7 +858,7 @@ class EDtrOffImm : public EDtrOff class EDtrOffReg : public EDtrOff { public: - EDtrOffReg(Register rm) + explicit EDtrOffReg(Register rm) : EDtrOff(rm) { } }; @@ -828,11 +868,11 @@ class EDtrAddr uint32_t data; public: - EDtrAddr(Register r, EDtrOff off) + explicit EDtrAddr(Register r, EDtrOff off) : data(RN(r) | off.encode()) { } - uint32_t encode() { + uint32_t encode() const { return data; } }; @@ -842,12 +882,12 @@ class VFPOff uint32_t data; protected: - VFPOff(datastore::Imm8VFPOffData imm, IsUp_ isup) + explicit VFPOff(datastore::Imm8VFPOffData imm, IsUp_ isup) : data(imm.encode() | (uint32_t)isup) { } public: - uint32_t encode() { + uint32_t encode() const { return data; } }; @@ -855,45 +895,49 @@ class VFPOff class VFPOffImm : public VFPOff { public: - VFPOffImm(int32_t imm) + explicit VFPOffImm(int32_t imm) : VFPOff(datastore::Imm8VFPOffData(mozilla::Abs(imm) / 4), imm < 0 ? IsDown : IsUp) { MOZ_ASSERT(mozilla::Abs(imm) <= 255 * 4); } }; + class VFPAddr { friend class Operand; uint32_t data; + public: + explicit VFPAddr(Register base, VFPOff off) + : data(RN(base) | off.encode()) + { } + protected: VFPAddr(uint32_t blob) : data(blob) { } public: - VFPAddr(Register base, VFPOff off) - : data(RN(base) | off.encode()) - { } - - uint32_t encode() { + uint32_t encode() const { return data; } }; -class VFPImm { +class VFPImm +{ uint32_t data; + public: + explicit VFPImm(uint32_t topWordOfDouble); + public: static const VFPImm One; - VFPImm(uint32_t topWordOfDouble); - - uint32_t encode() { + uint32_t encode() const { return data; } - bool isValid() { + bool isValid() const { return data != -1U; } }; @@ -903,16 +947,11 @@ class VFPImm { // constructing a branch. class BOffImm { + friend class InstBranchImm; + uint32_t data; public: - uint32_t encode() { - return data; - } - int32_t decode() { - return ((((int32_t)data) << 8) >> 6) + 8; - } - explicit BOffImm(int offset) : data ((offset - 8) >> 2 & 0x00ffffff) { @@ -920,27 +959,36 @@ class BOffImm if (!IsInRange(offset)) CrashAtUnhandlableOOM("BOffImm"); } - static bool IsInRange(int offset) - { + + explicit BOffImm() + : data(INVALID) + { } + + private: + BOffImm(Instruction& inst); + + public: + static const int INVALID = 0x00800000; + + uint32_t encode() const { + return data; + } + int32_t decode() const { + return ((((int32_t)data) << 8) >> 6) + 8; + } + + static bool IsInRange(int offset) { if ((offset - 8) < -33554432) return false; if ((offset - 8) > 33554428) return false; return true; } - static const int INVALID = 0x00800000; - BOffImm() - : data(INVALID) - { } - bool isInvalid() { + bool isInvalid() const { return data == uint32_t(INVALID); } - Instruction* getDest(Instruction* src); - - private: - friend class InstBranchImm; - BOffImm(Instruction& inst); + Instruction* getDest(Instruction* src) const; }; class Imm16 @@ -951,18 +999,18 @@ class Imm16 uint32_t invalid : 12; public: - Imm16(); - Imm16(uint32_t imm); - Imm16(Instruction& inst); + explicit Imm16(); + explicit Imm16(uint32_t imm); + explicit Imm16(Instruction& inst); - uint32_t encode() { + uint32_t encode() const { return lower | upper << 16; } - uint32_t decode() { + uint32_t decode() const { return lower | upper << 12; } - bool isInvalid () { + bool isInvalid () const { return invalid; } }; @@ -988,26 +1036,27 @@ class Operand uint32_t data; public: - Operand (Register reg_) + explicit Operand(Register reg_) : Tag(OP2), reg(reg_.code()) { } - Operand (FloatRegister freg) + explicit Operand(FloatRegister freg) : Tag(FOP), reg(freg.code()) { } - Operand (Register base, Imm32 off) + explicit Operand(Register base, Imm32 off) : Tag(MEM), reg(base.code()), offset(off.value) { } - Operand (Register base, int32_t off) + explicit Operand(Register base, int32_t off) : Tag(MEM), reg(base.code()), offset(off) { } - Operand (const Address& addr) + explicit Operand(const Address& addr) : Tag(MEM), reg(addr.base.code()), offset(addr.offset) { } + public: Tag_ getTag() const { return Tag; } @@ -1028,6 +1077,7 @@ class Operand *dest = Imm32(offset); } Address toAddress() const { + MOZ_ASSERT(Tag == MEM); return Address(Register::FromCode(reg), offset); } int32_t disp() const { @@ -1051,7 +1101,9 @@ class Operand }; void -PatchJump(CodeLocationJump& jump_, CodeLocationLabel label); +PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, + ReprotectCode reprotect = DontReprotect); + static inline void PatchBackedge(CodeLocationJump& jump_, CodeLocationLabel label, JitRuntime::BackedgeTarget target) { @@ -1179,8 +1231,8 @@ class Assembler : public AssemblerShared static uint32_t GetNopFill(); static uint32_t AsmPoolMaxOffset; static uint32_t GetPoolMaxOffset(); - protected: + protected: // Structure for fixing up pc-relative loads/jumps when a the machine code // gets moved (executable copy, gc, etc.). struct RelativePatch @@ -1214,8 +1266,7 @@ class Assembler : public AssemblerShared isFinished(false), dtmActive(false), dtmCond(Always) - { - } + { } // We need to wait until an AutoJitContextAlloc is created by the // MacroAssembler, before allocating any space. @@ -1234,8 +1285,12 @@ class Assembler : public AssemblerShared // As opposed to x86/x64 version, the data relocation has to be executed // before to recover the pointer, and not after. void writeDataRelocation(ImmGCPtr ptr) { - if (ptr.value) - tmpDataRelocations_.append(nextOffset()); + if (ptr.value) { + if (gc::IsInsideNursery(ptr.value)) + embedsNurseryPointers_ = true; + if (ptr.value) + tmpDataRelocations_.append(nextOffset()); + } } void writePrebarrierOffset(CodeOffsetLabel label) { tmpPreBarriers_.append(BufferOffset(label.offset())); @@ -1318,48 +1373,45 @@ class Assembler : public AssemblerShared void nopAlign(int alignment); BufferOffset as_nop(); BufferOffset as_alu(Register dest, Register src1, Operand2 op2, - ALUOp op, SetCond_ sc = NoSetCond, Condition c = Always); + ALUOp op, SBit s = LeaveCC, Condition c = Always); BufferOffset as_mov(Register dest, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_mvn(Register dest, Operand2 op2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); static void as_alu_patch(Register dest, Register src1, Operand2 op2, - ALUOp op, SetCond_ sc, Condition c, uint32_t* pos); + ALUOp op, SBit s, Condition c, uint32_t* pos); static void as_mov_patch(Register dest, - Operand2 op2, SetCond_ sc, Condition c, uint32_t* pos); + Operand2 op2, SBit s, Condition c, uint32_t* pos); // Logical operations: BufferOffset as_and(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_bic(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_eor(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_orr(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); // Mathematical operations: BufferOffset as_adc(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_add(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_sbc(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_sub(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_rsb(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); BufferOffset as_rsc(Register dest, Register src1, - Operand2 op2, SetCond_ sc = NoSetCond, Condition c = Always); + Operand2 op2, SBit s = LeaveCC, Condition c = Always); // Test operations: - BufferOffset as_cmn(Register src1, Operand2 op2, - Condition c = Always); - BufferOffset as_cmp(Register src1, Operand2 op2, - Condition c = Always); - BufferOffset as_teq(Register src1, Operand2 op2, - Condition c = Always); - BufferOffset as_tst(Register src1, Operand2 op2, - Condition c = Always); + BufferOffset as_cmn(Register src1, Operand2 op2, Condition c = Always); + BufferOffset as_cmp(Register src1, Operand2 op2, Condition c = Always); + BufferOffset as_teq(Register src1, Operand2 op2, Condition c = Always); + BufferOffset as_tst(Register src1, Operand2 op2, Condition c = Always); + // Sign extension operations: BufferOffset as_sxtb(Register dest, Register src, int rotate, Condition c = Always); BufferOffset as_sxth(Register dest, Register src, int rotate, Condition c = Always); @@ -1367,8 +1419,7 @@ class Assembler : public AssemblerShared BufferOffset as_uxth(Register dest, Register src, int rotate, Condition c = Always); // Not quite ALU worthy, but useful none the less: These also have the issue - // of these being formatted completly differently from the standard ALU - // operations. + // of these being formatted completly differently from the standard ALU operations. BufferOffset as_movw(Register dest, Imm16 imm, Condition c = Always); BufferOffset as_movt(Register dest, Imm16 imm, Condition c = Always); @@ -1376,23 +1427,23 @@ class Assembler : public AssemblerShared static void as_movt_patch(Register dest, Imm16 imm, Condition c, Instruction* pos); BufferOffset as_genmul(Register d1, Register d2, Register rm, Register rn, - MULOp op, SetCond_ sc, Condition c = Always); + MULOp op, SBit s, Condition c = Always); BufferOffset as_mul(Register dest, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_mla(Register dest, Register acc, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_umaal(Register dest1, Register dest2, Register src1, Register src2, Condition c = Always); BufferOffset as_mls(Register dest, Register acc, Register src1, Register src2, Condition c = Always); BufferOffset as_umull(Register dest1, Register dest2, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_umlal(Register dest1, Register dest2, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_smull(Register dest1, Register dest2, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_smlal(Register dest1, Register dest2, Register src1, Register src2, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); BufferOffset as_sdiv(Register dest, Register num, Register div, Condition c = Always); BufferOffset as_udiv(Register dest, Register num, Register div, Condition c = Always); @@ -1420,7 +1471,8 @@ class Assembler : public AssemblerShared // Load a 32 bit immediate from a pool into a register. BufferOffset as_Imm32Pool(Register dest, uint32_t value, Condition c = Always); // Make a patchable jump that can target the entire 32 bit address space. - BufferOffset as_BranchPool(uint32_t value, RepatchLabel* label, ARMBuffer::PoolEntry* pe = nullptr, Condition c = Always); + BufferOffset as_BranchPool(uint32_t value, RepatchLabel* label, + ARMBuffer::PoolEntry* pe = nullptr, Condition c = Always); // Load a 64 bit floating point immediate from a pool into a register. BufferOffset as_FImm64Pool(VFPRegister dest, double value, Condition c = Always); @@ -1444,10 +1496,8 @@ class Assembler : public AssemblerShared BufferOffset as_strexh(Register rd, Register rt, Register rn, Condition c = Always); BufferOffset as_strexb(Register rd, Register rt, Register rn, Condition c = Always); - // Memory synchronization: dmb, dsb, isb. - // + // Memory synchronization. // These are available from ARMv7 forward. - BufferOffset as_dmb(BarrierOption option = BarrierSY); BufferOffset as_dsb(BarrierOption option = BarrierSY); BufferOffset as_isb(); @@ -1487,9 +1537,9 @@ class Assembler : public AssemblerShared BufferOffset as_mrs(Register r, Condition c = Always); BufferOffset as_msr(Register r, Condition c = Always); + // VFP instructions! private: - enum vfp_size { IsDouble = 1 << 8, IsSingle = 0 << 8 @@ -1505,39 +1555,22 @@ class Assembler : public AssemblerShared VFPOp op, Condition c = Always); public: - BufferOffset as_vadd(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vdiv(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vnmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vnmla(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vnmls(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - + BufferOffset as_vadd(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vdiv(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vnmul(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vnmla(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vnmls(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); BufferOffset as_vneg(VFPRegister vd, VFPRegister vm, Condition c = Always); - BufferOffset as_vsqrt(VFPRegister vd, VFPRegister vm, Condition c = Always); - BufferOffset as_vabs(VFPRegister vd, VFPRegister vm, Condition c = Always); - - BufferOffset as_vsub(VFPRegister vd, VFPRegister vn, VFPRegister vm, - Condition c = Always); - - BufferOffset as_vcmp(VFPRegister vd, VFPRegister vm, - Condition c = Always); + BufferOffset as_vsub(VFPRegister vd, VFPRegister vn, VFPRegister vm, Condition c = Always); + BufferOffset as_vcmp(VFPRegister vd, VFPRegister vm, Condition c = Always); BufferOffset as_vcmpz(VFPRegister vd, Condition c = Always); // Specifically, a move between two same sized-registers. BufferOffset as_vmov(VFPRegister vd, VFPRegister vsrc, Condition c = Always); + // Transfer between Core and VFP. enum FloatToCore_ { FloatToCore = 1 << 20, @@ -1564,26 +1597,29 @@ class Assembler : public AssemblerShared // to uniquely specify the encoding that we are going to use. BufferOffset as_vcvt(VFPRegister vd, VFPRegister vm, bool useFPSCR = false, Condition c = Always); + // Hard coded to a 32 bit fixed width result for now. - BufferOffset as_vcvtFixed(VFPRegister vd, bool isSigned, uint32_t fixedPoint, bool toFixed, Condition c = Always); + BufferOffset as_vcvtFixed(VFPRegister vd, bool isSigned, uint32_t fixedPoint, + bool toFixed, Condition c = Always); // Transfer between VFP and memory. BufferOffset as_vdtr(LoadStore ls, VFPRegister vd, VFPAddr addr, Condition c = Always /* vfp doesn't have a wb option*/); static void as_vdtr_patch(LoadStore ls, VFPRegister vd, VFPAddr addr, - Condition c /* vfp doesn't have a wb option*/, uint32_t* dest); + Condition c /* vfp doesn't have a wb option */, uint32_t* dest); // VFP's ldm/stm work differently from the standard arm ones. You can only // transfer a range. BufferOffset as_vdtm(LoadStore st, Register rn, VFPRegister vd, int length, - /*also has update conditions*/Condition c = Always); + /* also has update conditions */ Condition c = Always); BufferOffset as_vimm(VFPRegister vd, VFPImm imm, Condition c = Always); BufferOffset as_vmrs(Register r, Condition c = Always); BufferOffset as_vmsr(Register r, Condition c = Always); + // Label operations. bool nextLink(BufferOffset b, BufferOffset* next); void bind(Label* label, BufferOffset boff = BufferOffset()); @@ -1611,9 +1647,6 @@ class Assembler : public AssemblerShared static void TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader); static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader); - static void FixupNurseryObjects(JSContext* cx, JitCode* code, CompactBufferReader& reader, - const ObjectVector& nurseryObjects); - static bool SupportsFloatingPoint() { return HasVFP(); } @@ -1911,6 +1944,7 @@ class InstLDR : public InstDTR InstLDR(Index mode, Register rt, DTRAddr addr, Assembler::Condition c) : InstDTR(IsLoad, IsWord, mode, rt, addr, c) { } + static bool IsTHIS(const Instruction& i); static InstLDR* AsTHIS(const Instruction& i); @@ -1939,13 +1973,17 @@ class InstBranchReg : public Instruction IsBX = 0x012fff10, IsBLX = 0x012fff30 }; + static const uint32_t IsBRegMask = 0x0ffffff0; + InstBranchReg(BranchTag tag, Register rm, Assembler::Condition c) : Instruction(tag | rm.code(), c) { } + public: static bool IsTHIS (const Instruction& i); static InstBranchReg* AsTHIS (const Instruction& i); + // Get the register that is being branched to void extractDest(Register* dest); // Make sure we are branching to a pre-known register @@ -1961,6 +1999,7 @@ class InstBranchImm : public Instruction IsB = 0x0a000000, IsBL = 0x0b000000 }; + static const uint32_t IsBImmMask = 0x0f000000; InstBranchImm(BranchTag tag, BOffImm off, Assembler::Condition c) @@ -1970,6 +2009,7 @@ class InstBranchImm : public Instruction public: static bool IsTHIS (const Instruction& i); static InstBranchImm* AsTHIS (const Instruction& i); + void extractImm(BOffImm* dest); }; JS_STATIC_ASSERT(sizeof(InstBranchImm) == sizeof(Instruction)); @@ -1981,6 +2021,7 @@ class InstBXReg : public InstBranchReg static bool IsTHIS (const Instruction& i); static InstBXReg* AsTHIS (const Instruction& i); }; + class InstBLXReg : public InstBranchReg { public: @@ -1991,6 +2032,7 @@ class InstBLXReg : public InstBranchReg static bool IsTHIS (const Instruction& i); static InstBLXReg* AsTHIS (const Instruction& i); }; + class InstBImm : public InstBranchImm { public: @@ -2001,6 +2043,7 @@ class InstBImm : public InstBranchImm static bool IsTHIS (const Instruction& i); static InstBImm* AsTHIS (const Instruction& i); }; + class InstBLImm : public InstBranchImm { public: @@ -2056,6 +2099,7 @@ class InstMovT : public InstMovWT InstMovT (Register rd, Imm16 imm, Assembler::Condition c) : InstMovWT(rd, imm, IsT, c) { } + static bool IsTHIS (const Instruction& i); static InstMovT* AsTHIS (const Instruction& i); }; @@ -2063,12 +2107,15 @@ class InstMovT : public InstMovWT class InstALU : public Instruction { static const int32_t ALUMask = 0xc << 24; + public: - InstALU (Register rd, Register rn, Operand2 op2, ALUOp op, SetCond_ sc, Assembler::Condition c) - : Instruction(maybeRD(rd) | maybeRN(rn) | op2.encode() | op | sc, c) + InstALU (Register rd, Register rn, Operand2 op2, ALUOp op, SBit s, Assembler::Condition c) + : Instruction(maybeRD(rd) | maybeRN(rn) | op2.encode() | op | s, c) { } + static bool IsTHIS (const Instruction& i); static InstALU* AsTHIS (const Instruction& i); + void extractOp(ALUOp* ret); bool checkOp(ALUOp op); void extractDest(Register* ret); @@ -2093,11 +2140,14 @@ class InstMOV : public InstALU }; -class InstructionIterator { +class InstructionIterator +{ private: Instruction* i; + public: - InstructionIterator(Instruction* i_); + explicit InstructionIterator(Instruction* i_); + Instruction* next() { i = i->next(); return cur(); @@ -2108,6 +2158,7 @@ class InstructionIterator { }; static const uint32_t NumIntArgRegs = 4; + // There are 16 *float* registers available for arguments // If doubles are used, only half the number of registers are available. static const uint32_t NumFloatArgRegs = 16; @@ -2117,6 +2168,7 @@ GetIntArgReg(uint32_t usedIntArgs, uint32_t usedFloatArgs, Register* out) { if (usedIntArgs >= NumIntArgRegs) return false; + *out = Register::FromCode(usedIntArgs); return true; } @@ -2131,18 +2183,20 @@ GetTempRegForIntArg(uint32_t usedIntArgs, uint32_t usedFloatArgs, Register* out) { if (GetIntArgReg(usedIntArgs, usedFloatArgs, out)) return true; + // Unfortunately, we have to assume things about the point at which // GetIntArgReg returns false, because we need to know how many registers it // can allocate. usedIntArgs -= NumIntArgRegs; if (usedIntArgs >= NumCallTempNonArgRegs) return false; + *out = CallTempNonArgRegs[usedIntArgs]; return true; } -#if !defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR) +#if !defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_SIMULATOR_ARM) static inline uint32_t GetArgStackDisp(uint32_t arg) @@ -2155,7 +2209,7 @@ GetArgStackDisp(uint32_t arg) #endif -#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR) +#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_SIMULATOR_ARM) static inline bool GetFloat32ArgReg(uint32_t usedIntArgs, uint32_t usedFloatArgs, FloatRegister* out) @@ -2220,7 +2274,8 @@ GetDoubleArgStackDisp(uint32_t usedIntArgs, uint32_t usedFloatArgs, uint32_t* pa -class DoubleEncoder { +class DoubleEncoder +{ struct DoubleEntry { uint32_t dblTop; @@ -2230,7 +2285,7 @@ class DoubleEncoder { static const DoubleEntry table[256]; public: - bool lookup(uint32_t top, datastore::Imm8VFPImmData* ret) { + bool lookup(uint32_t top, datastore::Imm8VFPImmData* ret) const { for (int i = 0; i < 256; i++) { if (table[i].dblTop == top) { *ret = table[i].data; @@ -2241,8 +2296,10 @@ class DoubleEncoder { } }; -class AutoForbidPools { +class AutoForbidPools +{ Assembler* masm_; + public: // The maxInst argument is the maximum number of word sized instructions // that will be allocated within this context. It is used to determine if @@ -2251,9 +2308,12 @@ class AutoForbidPools { // // Allocation of pool entries is not supported within this content so the // code can not use large integers or float constants etc. - AutoForbidPools(Assembler* masm, size_t maxInst) : masm_(masm) { + AutoForbidPools(Assembler* masm, size_t maxInst) + : masm_(masm) + { masm_->enterNoPool(maxInst); } + ~AutoForbidPools() { masm_->leaveNoPool(); } diff --git a/js/src/jit/arm/BaselineIC-arm.cpp b/js/src/jit/arm/BaselineIC-arm.cpp index 3c1dda3316..ba31468be0 100644 --- a/js/src/jit/arm/BaselineIC-arm.cpp +++ b/js/src/jit/arm/BaselineIC-arm.cpp @@ -29,8 +29,8 @@ ICCompare_Int32::Compiler::generateStubCode(MacroAssembler& masm) // Compare payload regs of R0 and R1. Assembler::Condition cond = JSOpToCondition(op, /* signed = */true); masm.cmp32(R0.payloadReg(), R1.payloadReg()); - masm.ma_mov(Imm32(1), R0.payloadReg(), NoSetCond, cond); - masm.ma_mov(Imm32(0), R0.payloadReg(), NoSetCond, Assembler::InvertCondition(cond)); + masm.ma_mov(Imm32(1), R0.payloadReg(), LeaveCC, cond); + masm.ma_mov(Imm32(0), R0.payloadReg(), LeaveCC, Assembler::InvertCondition(cond)); // Result is implicitly boxed already. masm.tagValue(JSVAL_TYPE_BOOLEAN, R0.payloadReg(), R0); @@ -57,7 +57,7 @@ ICCompare_Double::Compiler::generateStubCode(MacroAssembler& masm) masm.compareDouble(FloatReg0, FloatReg1); masm.ma_mov(Imm32(0), dest); - masm.ma_mov(Imm32(1), dest, NoSetCond, cond); + masm.ma_mov(Imm32(1), dest, LeaveCC, cond); masm.tagValue(JSVAL_TYPE_BOOLEAN, dest, R0); EmitReturnFromIC(masm); @@ -93,7 +93,7 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm) Label maybeNegZero, revertRegister; switch(op_) { case JSOP_ADD: - masm.ma_add(R0.payloadReg(), R1.payloadReg(), scratchReg, SetCond); + masm.ma_add(R0.payloadReg(), R1.payloadReg(), scratchReg, SetCC); // Just jump to failure on overflow. R0 and R1 are preserved, so we can // just jump to the next stub. @@ -104,7 +104,7 @@ ICBinaryArith_Int32::Compiler::generateStubCode(MacroAssembler& masm) masm.mov(scratchReg, R0.payloadReg()); break; case JSOP_SUB: - masm.ma_sub(R0.payloadReg(), R1.payloadReg(), scratchReg, SetCond); + masm.ma_sub(R0.payloadReg(), R1.payloadReg(), scratchReg, SetCC); masm.j(Assembler::Overflow, &failure); masm.mov(scratchReg, R0.payloadReg()); break; diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp index ec52b3eaa6..db052a031c 100644 --- a/js/src/jit/arm/CodeGenerator-arm.cpp +++ b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -137,7 +137,7 @@ CodeGeneratorARM::visitCompare(LCompare* comp) else masm.ma_cmp(ToRegister(left), ToOperand(right)); masm.ma_mov(Imm32(0), ToRegister(def)); - masm.ma_mov(Imm32(1), ToRegister(def), NoSetCond, cond); + masm.ma_mov(Imm32(1), ToRegister(def), LeaveCC, cond); } void @@ -382,9 +382,9 @@ CodeGeneratorARM::visitAddI(LAddI* ins) const LDefinition* dest = ins->getDef(0); if (rhs->isConstant()) - masm.ma_add(ToRegister(lhs), Imm32(ToInt32(rhs)), ToRegister(dest), SetCond); + masm.ma_add(ToRegister(lhs), Imm32(ToInt32(rhs)), ToRegister(dest), SetCC); else - masm.ma_add(ToRegister(lhs), ToOperand(rhs), ToRegister(dest), SetCond); + masm.ma_add(ToRegister(lhs), ToOperand(rhs), ToRegister(dest), SetCC); if (ins->snapshot()) bailoutIf(Assembler::Overflow, ins->snapshot()); @@ -398,9 +398,9 @@ CodeGeneratorARM::visitSubI(LSubI* ins) const LDefinition* dest = ins->getDef(0); if (rhs->isConstant()) - masm.ma_sub(ToRegister(lhs), Imm32(ToInt32(rhs)), ToRegister(dest), SetCond); + masm.ma_sub(ToRegister(lhs), Imm32(ToInt32(rhs)), ToRegister(dest), SetCC); else - masm.ma_sub(ToRegister(lhs), ToOperand(rhs), ToRegister(dest), SetCond); + masm.ma_sub(ToRegister(lhs), ToOperand(rhs), ToRegister(dest), SetCC); if (ins->snapshot()) bailoutIf(Assembler::Overflow, ins->snapshot()); @@ -428,7 +428,7 @@ CodeGeneratorARM::visitMulI(LMulI* ins) // TODO: move these to ma_mul. switch (constant) { case -1: - masm.ma_rsb(ToRegister(lhs), Imm32(0), ToRegister(dest), SetCond); + masm.ma_rsb(ToRegister(lhs), Imm32(0), ToRegister(dest), SetCC); break; case 0: masm.ma_mov(Imm32(0), ToRegister(dest)); @@ -438,7 +438,7 @@ CodeGeneratorARM::visitMulI(LMulI* ins) masm.ma_mov(ToRegister(lhs), ToRegister(dest)); return; // Escape overflow check; case 2: - masm.ma_add(ToRegister(lhs), ToRegister(lhs), ToRegister(dest), SetCond); + masm.ma_add(ToRegister(lhs), ToRegister(lhs), ToRegister(dest), SetCC); // Overflow is handled later. break; default: { @@ -648,7 +648,7 @@ CodeGeneratorARM::visitDivPowTwoI(LDivPowTwoI* ins) MDiv* mir = ins->mir(); if (!mir->isTruncated()) { // If the remainder is != 0, bailout since this must be a double. - masm.as_mov(ScratchRegister, lsl(lhs, 32 - shift), SetCond); + masm.as_mov(ScratchRegister, lsl(lhs, 32 - shift), SetCC); bailoutIf(Assembler::NonZero, ins->snapshot()); } @@ -813,11 +813,11 @@ CodeGeneratorARM::visitModPowTwoI(LModPowTwoI* ins) Label fin; // bug 739870, jbramley has a different sequence that may help with speed // here. - masm.ma_mov(in, out, SetCond); + masm.ma_mov(in, out, SetCC); masm.ma_b(&fin, Assembler::Zero); - masm.ma_rsb(Imm32(0), out, NoSetCond, Assembler::Signed); + masm.ma_rsb(Imm32(0), out, LeaveCC, Assembler::Signed); masm.ma_and(Imm32((1 << ins->shift()) - 1), out); - masm.ma_rsb(Imm32(0), out, SetCond, Assembler::Signed); + masm.ma_rsb(Imm32(0), out, SetCC, Assembler::Signed); if (mir->canBeNegativeDividend()) { if (!mir->isTruncated()) { MOZ_ASSERT(mir->fallible()); @@ -1102,8 +1102,8 @@ CodeGeneratorARM::emitTableSwitchDispatch(MTableSwitch* mir, Register index, Reg int32_t cases = mir->numCases(); // Lower value with low value. - masm.ma_sub(index, Imm32(mir->low()), index, SetCond); - masm.ma_rsb(index, Imm32(cases - 1), index, SetCond, Assembler::NotSigned); + masm.ma_sub(index, Imm32(mir->low()), index, SetCC); + masm.ma_rsb(index, Imm32(cases - 1), index, SetCC, Assembler::NotSigned); // Inhibit pools within the following sequence because we are indexing into // a pc relative table. The region will have one instruction for ma_ldr, one // for ma_b, and each table case takes one word. @@ -1614,8 +1614,8 @@ CodeGeneratorARM::visitNotD(LNotD* ins) } else { masm.as_vmrs(pc); masm.ma_mov(Imm32(0), dest); - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal); - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow); + masm.ma_mov(Imm32(1), dest, LeaveCC, Assembler::Equal); + masm.ma_mov(Imm32(1), dest, LeaveCC, Assembler::Overflow); } } @@ -1642,8 +1642,8 @@ CodeGeneratorARM::visitNotF(LNotF* ins) } else { masm.as_vmrs(pc); masm.ma_mov(Imm32(0), dest); - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Equal); - masm.ma_mov(Imm32(1), dest, NoSetCond, Assembler::Overflow); + masm.ma_mov(Imm32(1), dest, LeaveCC, Assembler::Equal); + masm.ma_mov(Imm32(1), dest, LeaveCC, Assembler::Overflow); } } @@ -1795,9 +1795,9 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap* ins) if (isFloat) { VFPRegister vd(ToFloatRegister(ins->output())); if (size == 32) - masm.ma_vldr(Operand(HeapReg, ptrImm), vd.singleOverlay(), Assembler::Always); + masm.ma_vldr(Address(HeapReg, ptrImm), vd.singleOverlay(), Assembler::Always); else - masm.ma_vldr(Operand(HeapReg, ptrImm), vd, Assembler::Always); + masm.ma_vldr(Address(HeapReg, ptrImm), vd, Assembler::Always); } else { masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, Imm32(ptrImm), ToRegister(ins->output()), Offset, Assembler::Always); @@ -1828,17 +1828,17 @@ CodeGeneratorARM::visitAsmJSLoadHeap(LAsmJSLoadHeap* ins) FloatRegister dst = ToFloatRegister(ins->output()); VFPRegister vd(dst); if (size == 32) { - masm.ma_vldr(Operand(GlobalReg, AsmJSNaN32GlobalDataOffset - AsmJSGlobalRegBias), + masm.ma_vldr(Address(GlobalReg, AsmJSNaN32GlobalDataOffset - AsmJSGlobalRegBias), vd.singleOverlay(), Assembler::AboveOrEqual); masm.ma_vldr(vd.singleOverlay(), HeapReg, ptrReg, 0, Assembler::Below); } else { - masm.ma_vldr(Operand(GlobalReg, AsmJSNaN64GlobalDataOffset - AsmJSGlobalRegBias), + masm.ma_vldr(Address(GlobalReg, AsmJSNaN64GlobalDataOffset - AsmJSGlobalRegBias), vd, Assembler::AboveOrEqual); masm.ma_vldr(vd, HeapReg, ptrReg, 0, Assembler::Below); } } else { Register d = ToRegister(ins->output()); - masm.ma_mov(Imm32(0), d, NoSetCond, Assembler::AboveOrEqual); + masm.ma_mov(Imm32(0), d, LeaveCC, Assembler::AboveOrEqual); masm.ma_dataTransferN(IsLoad, size, isSigned, HeapReg, ptrReg, d, Offset, Assembler::Below); } memoryBarrier(mir->barrierAfter()); @@ -1872,9 +1872,9 @@ CodeGeneratorARM::visitAsmJSStoreHeap(LAsmJSStoreHeap* ins) if (isFloat) { VFPRegister vd(ToFloatRegister(ins->value())); if (size == 32) - masm.ma_vstr(vd.singleOverlay(), Operand(HeapReg, ptrImm), Assembler::Always); + masm.ma_vstr(vd.singleOverlay(), Address(HeapReg, ptrImm), Assembler::Always); else - masm.ma_vstr(vd, Operand(HeapReg, ptrImm), Assembler::Always); + masm.ma_vstr(vd, Address(HeapReg, ptrImm), Assembler::Always); } else { masm.ma_dataTransferN(IsStore, size, isSigned, HeapReg, Imm32(ptrImm), ToRegister(ins->value()), Offset, Assembler::Always); @@ -2091,7 +2091,7 @@ void CodeGeneratorARM::visitAsmJSPassStackArg(LAsmJSPassStackArg* ins) { const MAsmJSPassStackArg* mir = ins->mir(); - Operand dst(StackPointer, mir->spOffset()); + Address dst(StackPointer, mir->spOffset()); if (ins->arg()->isConstant()) { //masm.as_bkpt(); masm.ma_storeImm(Imm32(ToInt32(ins->arg())), dst); @@ -2233,9 +2233,9 @@ CodeGeneratorARM::visitAsmJSLoadGlobalVar(LAsmJSLoadGlobalVar* ins) masm.ma_dtr(IsLoad, GlobalReg, Imm32(addr), ToRegister(ins->output())); } else if (mir->type() == MIRType_Float32) { VFPRegister vd(ToFloatRegister(ins->output())); - masm.ma_vldr(Operand(GlobalReg, addr), vd.singleOverlay()); + masm.ma_vldr(Address(GlobalReg, addr), vd.singleOverlay()); } else { - masm.ma_vldr(Operand(GlobalReg, addr), ToFloatRegister(ins->output())); + masm.ma_vldr(Address(GlobalReg, addr), ToFloatRegister(ins->output())); } } @@ -2252,9 +2252,9 @@ CodeGeneratorARM::visitAsmJSStoreGlobalVar(LAsmJSStoreGlobalVar* ins) masm.ma_dtr(IsStore, GlobalReg, Imm32(addr), ToRegister(ins->value())); } else if (type == MIRType_Float32) { VFPRegister vd(ToFloatRegister(ins->value())); - masm.ma_vstr(vd.singleOverlay(), Operand(GlobalReg, addr)); + masm.ma_vstr(vd.singleOverlay(), Address(GlobalReg, addr)); } else { - masm.ma_vstr(ToFloatRegister(ins->value()), Operand(GlobalReg, addr)); + masm.ma_vstr(ToFloatRegister(ins->value()), Address(GlobalReg, addr)); } } @@ -2277,7 +2277,7 @@ CodeGeneratorARM::visitAsmJSLoadFFIFunc(LAsmJSLoadFFIFunc* ins) { const MAsmJSLoadFFIFunc* mir = ins->mir(); - masm.ma_ldr(Operand(GlobalReg, mir->globalDataOffset() - AsmJSGlobalRegBias), + masm.ma_ldr(Address(GlobalReg, mir->globalDataOffset() - AsmJSGlobalRegBias), ToRegister(ins->output())); } diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp index 05d9324f28..f3c11258bd 100644 --- a/js/src/jit/arm/MacroAssembler-arm.cpp +++ b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -59,10 +59,25 @@ MacroAssemblerARM::convertInt32ToDouble(Register src, FloatRegister dest_) void MacroAssemblerARM::convertInt32ToDouble(const Address& src, FloatRegister dest) { - ma_vldr(Operand(src), ScratchDoubleReg); + ma_vldr(src, ScratchDoubleReg); as_vcvt(dest, VFPRegister(ScratchDoubleReg).sintOverlay()); } +void +MacroAssemblerARM::convertInt32ToDouble(const BaseIndex& src, FloatRegister dest) +{ + Register base = src.base; + uint32_t scale = Imm32::ShiftOf(src.scale).value; + + if (src.offset != 0) { + ma_mov(base, ScratchRegister); + base = ScratchRegister; + ma_add(Imm32(src.offset), base); + } + ma_ldr(DTRAddr(base, DtrRegImmShift(src.index, LSL, scale)), ScratchRegister); + convertInt32ToDouble(ScratchRegister, dest); +} + void MacroAssemblerARM::convertUInt32ToDouble(Register src, FloatRegister dest_) { @@ -201,7 +216,7 @@ MacroAssemblerARM::convertInt32ToFloat32(Register src, FloatRegister dest) { void MacroAssemblerARM::convertInt32ToFloat32(const Address& src, FloatRegister dest) { - ma_vldr(Operand(src), ScratchFloat32Reg); + ma_vldr(src, ScratchFloat32Reg); as_vcvt(dest, VFPRegister(ScratchFloat32Reg).sintOverlay()); } @@ -245,8 +260,8 @@ MacroAssemblerARM::inc64(AbsoluteAddress dest) ma_ldrd(EDtrAddr(ScratchRegister, EDtrOffImm(0)), r0, r1); - ma_add(Imm32(1), r0, SetCond); - ma_adc(Imm32(0), r1, NoSetCond); + ma_add(Imm32(1), r0, SetCC); + ma_adc(Imm32(0), r1, LeaveCC); ma_strd(r0, r1, EDtrAddr(ScratchRegister, EDtrOffImm(0))); @@ -256,9 +271,9 @@ MacroAssemblerARM::inc64(AbsoluteAddress dest) bool MacroAssemblerARM::alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, - SetCond_ sc, Condition c) + SBit s, Condition c) { - if ((sc == SetCond && ! condsAreSafe(op)) || !can_dbl(op)) + if ((s == SetCC && ! condsAreSafe(op)) || !can_dbl(op)) return false; ALUOp interop = getDestVariant(op); Imm8::TwoImm8mData both = Imm8::EncodeTwoImms(imm.value); @@ -269,8 +284,8 @@ MacroAssemblerARM::alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, // doesn't have a dest, such as check for overflow by doing first operation // don't do second operation if first operation overflowed. This preserves // the overflow condition code. Unfortunately, it is horribly brittle. - as_alu(ScratchRegister, src1, both.fst, interop, NoSetCond, c); - as_alu(dest, ScratchRegister, both.snd, op, sc, c); + as_alu(ScratchRegister, src1, Operand2(both.fst), interop, LeaveCC, c); + as_alu(dest, ScratchRegister, Operand2(both.snd), op, s, c); return true; } @@ -278,18 +293,18 @@ MacroAssemblerARM::alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, void MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, ALUOp op, - SetCond_ sc, Condition c) + SBit s, Condition c) { // As it turns out, if you ask for a compare-like instruction you *probably* // want it to set condition codes. if (dest == InvalidReg) - MOZ_ASSERT(sc == SetCond); + MOZ_ASSERT(s == SetCC); // The operator gives us the ability to determine how this can be used. Imm8 imm8 = Imm8(imm.value); // One instruction: If we can encode it using an imm8m, then do so. if (!imm8.invalid) { - as_alu(dest, src1, imm8, op, sc, c); + as_alu(dest, src1, imm8, op, s, c); return; } // One instruction, negated: @@ -304,7 +319,7 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // but it will need to clobber *something*, and the scratch register isn't // being used, so... if (negOp != OpInvalid && !negImm8.invalid) { - as_alu(negDest, src1, negImm8, negOp, sc, c); + as_alu(negDest, src1, negImm8, negOp, s, c); return; } @@ -313,13 +328,13 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // the bits into the destination. Otherwise, we'll need to fall back on // a multi-instruction format :( // movw/movt does not set condition codes, so don't hold your breath. - if (sc == NoSetCond && (op == OpMov || op == OpMvn)) { + if (s == LeaveCC && (op == OpMov || op == OpMvn)) { // ARMv7 supports movw/movt. movw zero-extends its 16 bit argument, // so we can set the register this way. movt leaves the bottom 16 // bits in tact, so it is unsuitable to move a constant that if (op == OpMov && ((imm.value & ~ 0xffff) == 0)) { MOZ_ASSERT(src1 == InvalidReg); - as_movw(dest, (uint16_t)imm.value, c); + as_movw(dest, Imm16((uint16_t)imm.value), c); return; } @@ -327,7 +342,7 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // then do it. if (op == OpMvn && (((~imm.value) & ~ 0xffff) == 0)) { MOZ_ASSERT(src1 == InvalidReg); - as_movw(dest, (uint16_t)~imm.value, c); + as_movw(dest, Imm16((uint16_t)~imm.value), c); return; } @@ -341,8 +356,8 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // src1. if (op == OpMvn) imm.value = ~imm.value; - as_movw(dest, imm.value & 0xffff, c); - as_movt(dest, (imm.value >> 16) & 0xffff, c); + as_movw(dest, Imm16(imm.value & 0xffff), c); + as_movt(dest, Imm16((imm.value >> 16) & 0xffff), c); return; } // If we weren't doing a movalike, a 16 bit immediate will require 2 @@ -367,21 +382,21 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, // assume that the overflow flag will be checked and add{,s} dest, src, // 0xff00; add{,s} dest, dest, 0xff is not guaranteed to set the overflow // flag the same as the (theoretical) one instruction variant. - if (alu_dbl(src1, imm, dest, op, sc, c)) + if (alu_dbl(src1, imm, dest, op, s, c)) return; // And try with its negative. if (negOp != OpInvalid && - alu_dbl(src1, negImm, negDest, negOp, sc, c)) + alu_dbl(src1, negImm, negDest, negOp, s, c)) return; // Well, damn. We can use two 16 bit mov's, then do the op or we can do a // single load from a pool then op. if (HasMOVWT()) { // Try to load the immediate into a scratch register then use that - as_movw(ScratchRegister, imm.value & 0xffff, c); + as_movw(ScratchRegister, Imm16(imm.value & 0xffff), c); if ((imm.value >> 16) != 0) - as_movt(ScratchRegister, (imm.value >> 16) & 0xffff, c); + as_movt(ScratchRegister, Imm16((imm.value >> 16) & 0xffff), c); } else { // Going to have to use a load. If the operation is a move, then just // move it into the destination register @@ -394,21 +409,21 @@ MacroAssemblerARM::ma_alu(Register src1, Imm32 imm, Register dest, as_Imm32Pool(ScratchRegister, imm.value, c); } } - as_alu(dest, src1, O2Reg(ScratchRegister), op, sc, c); + as_alu(dest, src1, O2Reg(ScratchRegister), op, s, c); } void MacroAssemblerARM::ma_alu(Register src1, Operand op2, Register dest, ALUOp op, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { MOZ_ASSERT(op2.getTag() == Operand::OP2); - as_alu(dest, src1, op2.toOp2(), op, sc, c); + as_alu(dest, src1, op2.toOp2(), op, s, c); } void -MacroAssemblerARM::ma_alu(Register src1, Operand2 op2, Register dest, ALUOp op, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_alu(Register src1, Operand2 op2, Register dest, ALUOp op, SBit s, Condition c) { - as_alu(dest, src1, op2, op, sc, c); + as_alu(dest, src1, op2, op, s, c); } void @@ -471,24 +486,24 @@ MacroAssemblerARM::ma_mov_patch(ImmPtr imm, Register dest, Assembler::Condition } void -MacroAssemblerARM::ma_mov(Register src, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_mov(Register src, Register dest, SBit s, Assembler::Condition c) { - if (sc == SetCond || dest != src) - as_mov(dest, O2Reg(src), sc, c); + if (s == SetCC || dest != src) + as_mov(dest, O2Reg(src), s, c); } void MacroAssemblerARM::ma_mov(Imm32 imm, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(InvalidReg, imm, dest, OpMov, sc, c); + ma_alu(InvalidReg, imm, dest, OpMov, s, c); } void MacroAssemblerARM::ma_mov(ImmWord imm, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(InvalidReg, Imm32(imm.value), dest, OpMov, sc, c); + ma_alu(InvalidReg, Imm32(imm.value), dest, OpMov, s, c); } void @@ -563,230 +578,230 @@ MacroAssemblerARM::ma_rol(Register shift, Register src, Register dst) // Move not (dest <- ~src) void -MacroAssemblerARM::ma_mvn(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_mvn(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(InvalidReg, imm, dest, OpMvn, sc, c); + ma_alu(InvalidReg, imm, dest, OpMvn, s, c); } void -MacroAssemblerARM::ma_mvn(Register src1, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_mvn(Register src1, Register dest, SBit s, Assembler::Condition c) { - as_alu(dest, InvalidReg, O2Reg(src1), OpMvn, sc, c); + as_alu(dest, InvalidReg, O2Reg(src1), OpMvn, s, c); } // Negate (dest <- -src), src is a register, rather than a general op2. void -MacroAssemblerARM::ma_neg(Register src1, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_neg(Register src1, Register dest, SBit s, Assembler::Condition c) { - as_rsb(dest, src1, Imm8(0), sc, c); + as_rsb(dest, src1, Imm8(0), s, c); } // And. void -MacroAssemblerARM::ma_and(Register src, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_and(Register src, Register dest, SBit s, Assembler::Condition c) { ma_and(dest, src, dest); } void MacroAssemblerARM::ma_and(Register src1, Register src2, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - as_and(dest, src1, O2Reg(src2), sc, c); + as_and(dest, src1, O2Reg(src2), s, c); } void -MacroAssemblerARM::ma_and(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_and(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(dest, imm, dest, OpAnd, sc, c); + ma_alu(dest, imm, dest, OpAnd, s, c); } void MacroAssemblerARM::ma_and(Imm32 imm, Register src1, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(src1, imm, dest, OpAnd, sc, c); + ma_alu(src1, imm, dest, OpAnd, s, c); } // Bit clear (dest <- dest & ~imm) or (dest <- src1 & ~src2). void -MacroAssemblerARM::ma_bic(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_bic(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(dest, imm, dest, OpBic, sc, c); + ma_alu(dest, imm, dest, OpBic, s, c); } // Exclusive or. void -MacroAssemblerARM::ma_eor(Register src, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_eor(Register src, Register dest, SBit s, Assembler::Condition c) { - ma_eor(dest, src, dest, sc, c); + ma_eor(dest, src, dest, s, c); } void MacroAssemblerARM::ma_eor(Register src1, Register src2, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - as_eor(dest, src1, O2Reg(src2), sc, c); + as_eor(dest, src1, O2Reg(src2), s, c); } void -MacroAssemblerARM::ma_eor(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_eor(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(dest, imm, dest, OpEor, sc, c); + ma_alu(dest, imm, dest, OpEor, s, c); } void MacroAssemblerARM::ma_eor(Imm32 imm, Register src1, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(src1, imm, dest, OpEor, sc, c); + ma_alu(src1, imm, dest, OpEor, s, c); } // Or. void -MacroAssemblerARM::ma_orr(Register src, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_orr(Register src, Register dest, SBit s, Assembler::Condition c) { - ma_orr(dest, src, dest, sc, c); + ma_orr(dest, src, dest, s, c); } void MacroAssemblerARM::ma_orr(Register src1, Register src2, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - as_orr(dest, src1, O2Reg(src2), sc, c); + as_orr(dest, src1, O2Reg(src2), s, c); } void -MacroAssemblerARM::ma_orr(Imm32 imm, Register dest, SetCond_ sc, Assembler::Condition c) +MacroAssemblerARM::ma_orr(Imm32 imm, Register dest, SBit s, Assembler::Condition c) { - ma_alu(dest, imm, dest, OpOrr, sc, c); + ma_alu(dest, imm, dest, OpOrr, s, c); } void MacroAssemblerARM::ma_orr(Imm32 imm, Register src1, Register dest, - SetCond_ sc, Assembler::Condition c) + SBit s, Assembler::Condition c) { - ma_alu(src1, imm, dest, OpOrr, sc, c); + ma_alu(src1, imm, dest, OpOrr, s, c); } // Arithmetic-based ops. // Add with carry. void -MacroAssemblerARM::ma_adc(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_adc(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpAdc, sc, c); + ma_alu(dest, imm, dest, OpAdc, s, c); } void -MacroAssemblerARM::ma_adc(Register src, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_adc(Register src, Register dest, SBit s, Condition c) { - as_alu(dest, dest, O2Reg(src), OpAdc, sc, c); + as_alu(dest, dest, O2Reg(src), OpAdc, s, c); } void -MacroAssemblerARM::ma_adc(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_adc(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpAdc, sc, c); + as_alu(dest, src1, O2Reg(src2), OpAdc, s, c); } // Add. void -MacroAssemblerARM::ma_add(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpAdd, sc, c); + ma_alu(dest, imm, dest, OpAdd, s, c); } void -MacroAssemblerARM::ma_add(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Register src1, Register dest, SBit s, Condition c) { - ma_alu(dest, O2Reg(src1), dest, OpAdd, sc, c); + ma_alu(dest, O2Reg(src1), dest, OpAdd, s, c); } void -MacroAssemblerARM::ma_add(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpAdd, sc, c); + as_alu(dest, src1, O2Reg(src2), OpAdd, s, c); } void -MacroAssemblerARM::ma_add(Register src1, Operand op, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Register src1, Operand op, Register dest, SBit s, Condition c) { - ma_alu(src1, op, dest, OpAdd, sc, c); + ma_alu(src1, op, dest, OpAdd, s, c); } void -MacroAssemblerARM::ma_add(Register src1, Imm32 op, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_add(Register src1, Imm32 op, Register dest, SBit s, Condition c) { - ma_alu(src1, op, dest, OpAdd, sc, c); + ma_alu(src1, op, dest, OpAdd, s, c); } // Subtract with carry. void -MacroAssemblerARM::ma_sbc(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sbc(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpSbc, sc, c); + ma_alu(dest, imm, dest, OpSbc, s, c); } void -MacroAssemblerARM::ma_sbc(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sbc(Register src1, Register dest, SBit s, Condition c) { - as_alu(dest, dest, O2Reg(src1), OpSbc, sc, c); + as_alu(dest, dest, O2Reg(src1), OpSbc, s, c); } void -MacroAssemblerARM::ma_sbc(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sbc(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpSbc, sc, c); + as_alu(dest, src1, O2Reg(src2), OpSbc, s, c); } // Subtract. void -MacroAssemblerARM::ma_sub(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpSub, sc, c); + ma_alu(dest, imm, dest, OpSub, s, c); } void -MacroAssemblerARM::ma_sub(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Register src1, Register dest, SBit s, Condition c) { - ma_alu(dest, Operand(src1), dest, OpSub, sc, c); + ma_alu(dest, Operand(src1), dest, OpSub, s, c); } void -MacroAssemblerARM::ma_sub(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Register src1, Register src2, Register dest, SBit s, Condition c) { - ma_alu(src1, Operand(src2), dest, OpSub, sc, c); + ma_alu(src1, Operand(src2), dest, OpSub, s, c); } void -MacroAssemblerARM::ma_sub(Register src1, Operand op, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Register src1, Operand op, Register dest, SBit s, Condition c) { - ma_alu(src1, op, dest, OpSub, sc, c); + ma_alu(src1, op, dest, OpSub, s, c); } void -MacroAssemblerARM::ma_sub(Register src1, Imm32 op, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_sub(Register src1, Imm32 op, Register dest, SBit s, Condition c) { - ma_alu(src1, op, dest, OpSub, sc, c); + ma_alu(src1, op, dest, OpSub, s, c); } // Severse subtract. void -MacroAssemblerARM::ma_rsb(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsb(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpRsb, sc, c); + ma_alu(dest, imm, dest, OpRsb, s, c); } void -MacroAssemblerARM::ma_rsb(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsb(Register src1, Register dest, SBit s, Condition c) { - as_alu(dest, dest, O2Reg(src1), OpAdd, sc, c); + as_alu(dest, dest, O2Reg(src1), OpAdd, s, c); } void -MacroAssemblerARM::ma_rsb(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsb(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpRsb, sc, c); + as_alu(dest, src1, O2Reg(src2), OpRsb, s, c); } void -MacroAssemblerARM::ma_rsb(Register src1, Imm32 op2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsb(Register src1, Imm32 op2, Register dest, SBit s, Condition c) { - ma_alu(src1, op2, dest, OpRsb, sc, c); + ma_alu(src1, op2, dest, OpRsb, s, c); } // Reverse subtract with carry. void -MacroAssemblerARM::ma_rsc(Imm32 imm, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsc(Imm32 imm, Register dest, SBit s, Condition c) { - ma_alu(dest, imm, dest, OpRsc, sc, c); + ma_alu(dest, imm, dest, OpRsc, s, c); } void -MacroAssemblerARM::ma_rsc(Register src1, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsc(Register src1, Register dest, SBit s, Condition c) { - as_alu(dest, dest, O2Reg(src1), OpRsc, sc, c); + as_alu(dest, dest, O2Reg(src1), OpRsc, s, c); } void -MacroAssemblerARM::ma_rsc(Register src1, Register src2, Register dest, SetCond_ sc, Condition c) +MacroAssemblerARM::ma_rsc(Register src1, Register src2, Register dest, SBit s, Condition c) { - as_alu(dest, src1, O2Reg(src2), OpRsc, sc, c); + as_alu(dest, src1, O2Reg(src2), OpRsc, s, c); } // Compares/tests. @@ -794,12 +809,12 @@ MacroAssemblerARM::ma_rsc(Register src1, Register src2, Register dest, SetCond_ void MacroAssemblerARM::ma_cmn(Register src1, Imm32 imm, Condition c) { - ma_alu(src1, imm, InvalidReg, OpCmn, SetCond, c); + ma_alu(src1, imm, InvalidReg, OpCmn, SetCC, c); } void MacroAssemblerARM::ma_cmn(Register src1, Register src2, Condition c) { - as_alu(InvalidReg, src2, O2Reg(src1), OpCmn, SetCond, c); + as_alu(InvalidReg, src2, O2Reg(src1), OpCmn, SetCC, c); } void MacroAssemblerARM::ma_cmn(Register src1, Operand op, Condition c) @@ -811,7 +826,7 @@ MacroAssemblerARM::ma_cmn(Register src1, Operand op, Condition c) void MacroAssemblerARM::ma_cmp(Register src1, Imm32 imm, Condition c) { - ma_alu(src1, imm, InvalidReg, OpCmp, SetCond, c); + ma_alu(src1, imm, InvalidReg, OpCmp, SetCC, c); } void @@ -834,7 +849,7 @@ MacroAssemblerARM::ma_cmp(Register src1, Operand op, Condition c) as_cmp(src1, op.toOp2(), c); break; case Operand::MEM: - ma_ldr(op, ScratchRegister); + ma_ldr(op.toAddress(), ScratchRegister); as_cmp(src1, O2Reg(ScratchRegister), c); break; default: @@ -851,7 +866,7 @@ MacroAssemblerARM::ma_cmp(Register src1, Register src2, Condition c) void MacroAssemblerARM::ma_teq(Register src1, Imm32 imm, Condition c) { - ma_alu(src1, imm, InvalidReg, OpTeq, SetCond, c); + ma_alu(src1, imm, InvalidReg, OpTeq, SetCC, c); } void MacroAssemblerARM::ma_teq(Register src1, Register src2, Condition c) @@ -869,7 +884,7 @@ MacroAssemblerARM::ma_teq(Register src1, Operand op, Condition c) void MacroAssemblerARM::ma_tst(Register src1, Imm32 imm, Condition c) { - ma_alu(src1, imm, InvalidReg, OpTst, SetCond, c); + ma_alu(src1, imm, InvalidReg, OpTst, SetCC, c); } void MacroAssemblerARM::ma_tst(Register src1, Register src2, Condition c) @@ -901,7 +916,7 @@ MacroAssemblerARM::ma_check_mul(Register src1, Register src2, Register dest, Con // TODO: this operation is illegal on armv6 and earlier if src2 == // ScratchRegister or src2 == dest. if (cond == Equal || cond == NotEqual) { - as_smull(ScratchRegister, dest, src1, src2, SetCond); + as_smull(ScratchRegister, dest, src1, src2, SetCC); return cond; } @@ -919,7 +934,7 @@ MacroAssemblerARM::ma_check_mul(Register src1, Imm32 imm, Register dest, Conditi { ma_mov(imm, ScratchRegister); if (cond == Equal || cond == NotEqual) { - as_smull(ScratchRegister, dest, ScratchRegister, src1, SetCond); + as_smull(ScratchRegister, dest, ScratchRegister, src1, SetCC); return cond; } @@ -966,13 +981,13 @@ MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, Regis // Note that we cannot use ScratchRegister in place of tmp here, as ma_and // below on certain architectures move the mask into ScratchRegister before // performing the bitwise and. - as_mov(tmp, O2Reg(src), SetCond); + as_mov(tmp, O2Reg(src), SetCC); // Zero out the dest. ma_mov(Imm32(0), dest); // Set the hold appropriately. ma_mov(Imm32(1), hold); - ma_mov(Imm32(-1), hold, NoSetCond, Signed); - ma_rsb(Imm32(0), tmp, SetCond, Signed); + ma_mov(Imm32(-1), hold, LeaveCC, Signed); + ma_rsb(Imm32(0), tmp, SetCC, Signed); // Begin the main loop. bind(&head); @@ -982,11 +997,11 @@ MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, Regis ma_add(secondScratchReg_, dest, dest); // Do a trial subtraction, this is the same operation as cmp, but we store // the dest. - ma_sub(dest, Imm32(mask), secondScratchReg_, SetCond); + ma_sub(dest, Imm32(mask), secondScratchReg_, SetCC); // If (sum - C) > 0, store sum - C back into sum, thus performing a modulus. - ma_mov(secondScratchReg_, dest, NoSetCond, NotSigned); + ma_mov(secondScratchReg_, dest, LeaveCC, NotSigned); // Get rid of the bits that we extracted before, and set the condition codes. - as_mov(tmp, lsr(tmp, shift), SetCond); + as_mov(tmp, lsr(tmp, shift), SetCC); // If the shift produced zero, finish, otherwise, continue in the loop. ma_b(&head, NonZero); // Check the hold to see if we need to negate the result. Hold can only be @@ -994,7 +1009,7 @@ MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, Regis ma_cmp(hold, Imm32(0)); // If the hold was non-zero, negate the result to be in line with what JS // wants this will set the condition codes if we try to negate. - ma_rsb(Imm32(0), dest, SetCond, Signed); + ma_rsb(Imm32(0), dest, SetCC, Signed); // Since the Zero flag is not set by the compare, we can *only* set the Zero // flag in the rsb, so Zero is set iff we negated zero (e.g. the result of // the computation was -0.0). @@ -1055,15 +1070,13 @@ MacroAssemblerARM::ma_str(Register rt, DTRAddr addr, Index mode, Condition cc) } void -MacroAssemblerARM::ma_dtr(LoadStore ls, Register rt, const Operand& addr, Index mode, Condition cc) +MacroAssemblerARM::ma_dtr(LoadStore ls, Register rt, const Address& addr, Index mode, Condition cc) { - ma_dataTransferN(ls, 32, true, - Register::FromCode(addr.base()), Imm32(addr.disp()), - rt, mode, cc); + ma_dataTransferN(ls, 32, true, addr.base, Imm32(addr.offset), rt, mode, cc); } void -MacroAssemblerARM::ma_str(Register rt, const Operand& addr, Index mode, Condition cc) +MacroAssemblerARM::ma_str(Register rt, const Address& addr, Index mode, Condition cc) { ma_dtr(IsStore, rt, addr, mode, cc); } @@ -1081,7 +1094,7 @@ MacroAssemblerARM::ma_ldr(DTRAddr addr, Register rt, Index mode, Condition cc) as_dtr(IsLoad, 32, mode, rt, addr, cc); } void -MacroAssemblerARM::ma_ldr(const Operand& addr, Register rt, Index mode, Condition cc) +MacroAssemblerARM::ma_ldr(const Address& addr, Register rt, Index mode, Condition cc) { ma_dtr(IsLoad, rt, addr, mode, cc); } @@ -1221,7 +1234,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, Operand2 sub_off = Imm8(-(off - bottom)); // sub_off = bottom - off if (!sub_off.invalid) { // - sub_off = off - bottom - as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(bottom)), cc); } // sub_off = -neg_bottom - off @@ -1230,7 +1243,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x1000); // - sub_off = neg_bottom + off - as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(-neg_bottom)), cc); } } else { @@ -1238,7 +1251,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, Operand2 sub_off = Imm8(off - bottom); if (!sub_off.invalid) { // sub_off = off - bottom - as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_add(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(bottom)), cc); } // sub_off = neg_bottom + off @@ -1247,7 +1260,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x1000); // sub_off = neg_bottom + off - as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_add(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_dtr(ls, size, Offset, rt, DTRAddr(ScratchRegister, DtrOffImm(-neg_bottom)), cc); } } @@ -1273,7 +1286,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, Operand2 sub_off = Imm8(-(off - bottom)); if (!sub_off.invalid) { // - sub_off = off - bottom - as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_extdtr(ls, size, IsSigned, Offset, rt, EDtrAddr(ScratchRegister, EDtrOffImm(bottom)), cc); @@ -1284,7 +1297,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x100); // - sub_off = neg_bottom + off - as_sub(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_extdtr(ls, size, IsSigned, Offset, rt, EDtrAddr(ScratchRegister, EDtrOffImm(-neg_bottom)), cc); @@ -1294,7 +1307,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, Operand2 sub_off = Imm8(off - bottom); if (!sub_off.invalid) { // sub_off = off - bottom - as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_add(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_extdtr(ls, size, IsSigned, Offset, rt, EDtrAddr(ScratchRegister, EDtrOffImm(bottom)), cc); @@ -1305,7 +1318,7 @@ MacroAssemblerARM::ma_dataTransferN(LoadStore ls, int size, bool IsSigned, // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x100); // sub_off = neg_bottom + off - as_add(ScratchRegister, rn, sub_off, NoSetCond, cc); + as_add(ScratchRegister, rn, sub_off, LeaveCC, cc); return as_extdtr(ls, size, IsSigned, Offset, rt, EDtrAddr(ScratchRegister, EDtrOffImm(-neg_bottom)), cc); @@ -1696,13 +1709,13 @@ MacroAssemblerARM::ma_vxfer(Register src1, Register src2, FloatRegister dest, Co } BufferOffset -MacroAssemblerARM::ma_vdtr(LoadStore ls, const Operand& addr, VFPRegister rt, Condition cc) +MacroAssemblerARM::ma_vdtr(LoadStore ls, const Address& addr, VFPRegister rt, Condition cc) { - int off = addr.disp(); + int off = addr.offset; MOZ_ASSERT((off & 3) == 0); - Register base = Register::FromCode(addr.base()); + Register base = addr.base; if (off > -1024 && off < 1024) - return as_vdtr(ls, rt, addr.toVFPAddr(), cc); + return as_vdtr(ls, rt, Operand(addr).toVFPAddr(), cc); // We cannot encode this offset in a a single ldr. Try to encode it as an // add scratch, base, imm; ldr dest, [scratch, +offset]. @@ -1719,7 +1732,7 @@ MacroAssemblerARM::ma_vdtr(LoadStore ls, const Operand& addr, VFPRegister rt, Co Operand2 sub_off = Imm8(-(off - bottom)); if (!sub_off.invalid) { // - sub_off = off - bottom - as_sub(ScratchRegister, base, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, base, sub_off, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(bottom)), cc); } // sub_off = -neg_bottom - off @@ -1728,7 +1741,7 @@ MacroAssemblerARM::ma_vdtr(LoadStore ls, const Operand& addr, VFPRegister rt, Co // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x400); // - sub_off = neg_bottom + off - as_sub(ScratchRegister, base, sub_off, NoSetCond, cc); + as_sub(ScratchRegister, base, sub_off, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(-neg_bottom)), cc); } } else { @@ -1736,7 +1749,7 @@ MacroAssemblerARM::ma_vdtr(LoadStore ls, const Operand& addr, VFPRegister rt, Co Operand2 sub_off = Imm8(off - bottom); if (!sub_off.invalid) { // sub_off = off - bottom - as_add(ScratchRegister, base, sub_off, NoSetCond, cc); + as_add(ScratchRegister, base, sub_off, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(bottom)), cc); } // sub_off = neg_bottom + off @@ -1745,11 +1758,11 @@ MacroAssemblerARM::ma_vdtr(LoadStore ls, const Operand& addr, VFPRegister rt, Co // Guarded against by: bottom != 0 MOZ_ASSERT(neg_bottom < 0x400); // sub_off = neg_bottom + off - as_add(ScratchRegister, base, sub_off, NoSetCond, cc); + as_add(ScratchRegister, base, sub_off, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(-neg_bottom)), cc); } } - ma_add(base, Imm32(off), ScratchRegister, NoSetCond, cc); + ma_add(base, Imm32(off), ScratchRegister, LeaveCC, cc); return as_vdtr(ls, rt, VFPAddr(ScratchRegister, VFPOffImm(0)), cc); } @@ -1759,15 +1772,15 @@ MacroAssemblerARM::ma_vldr(VFPAddr addr, VFPRegister dest, Condition cc) return as_vdtr(IsLoad, dest, addr, cc); } BufferOffset -MacroAssemblerARM::ma_vldr(const Operand& addr, VFPRegister dest, Condition cc) +MacroAssemblerARM::ma_vldr(const Address& addr, VFPRegister dest, Condition cc) { return ma_vdtr(IsLoad, addr, dest, cc); } BufferOffset MacroAssemblerARM::ma_vldr(VFPRegister src, Register base, Register index, int32_t shift, Condition cc) { - as_add(ScratchRegister, base, lsl(index, shift), NoSetCond, cc); - return ma_vldr(Operand(ScratchRegister, 0), src, cc); + as_add(ScratchRegister, base, lsl(index, shift), LeaveCC, cc); + return ma_vldr(Address(ScratchRegister, 0), src, cc); } BufferOffset @@ -1777,7 +1790,7 @@ MacroAssemblerARM::ma_vstr(VFPRegister src, VFPAddr addr, Condition cc) } BufferOffset -MacroAssemblerARM::ma_vstr(VFPRegister src, const Operand& addr, Condition cc) +MacroAssemblerARM::ma_vstr(VFPRegister src, const Address& addr, Condition cc) { return ma_vdtr(IsStore, addr, src, cc); } @@ -1785,8 +1798,8 @@ BufferOffset MacroAssemblerARM::ma_vstr(VFPRegister src, Register base, Register index, int32_t shift, int32_t offset, Condition cc) { - as_add(ScratchRegister, base, lsl(index, shift), NoSetCond, cc); - return ma_vstr(src, Operand(ScratchRegister, offset), cc); + as_add(ScratchRegister, base, lsl(index, shift), LeaveCC, cc); + return ma_vstr(src, Address(ScratchRegister, offset), cc); } void @@ -1897,58 +1910,58 @@ MacroAssembler::restoreFrameAlignmentForICArguments(AfterICSaveLive& aic) void MacroAssemblerARMCompat::add32(Register src, Register dest) { - ma_add(src, dest, SetCond); + ma_add(src, dest, SetCC); } void MacroAssemblerARMCompat::add32(Imm32 imm, Register dest) { - ma_add(imm, dest, SetCond); + ma_add(imm, dest, SetCC); } void MacroAssemblerARMCompat::xor32(Imm32 imm, Register dest) { - ma_eor(imm, dest, SetCond); + ma_eor(imm, dest, SetCC); } void MacroAssemblerARMCompat::add32(Imm32 imm, const Address& dest) { load32(dest, ScratchRegister); - ma_add(imm, ScratchRegister, SetCond); + ma_add(imm, ScratchRegister, SetCC); store32(ScratchRegister, dest); } void MacroAssemblerARMCompat::sub32(Imm32 imm, Register dest) { - ma_sub(imm, dest, SetCond); + ma_sub(imm, dest, SetCC); } void MacroAssemblerARMCompat::sub32(Register src, Register dest) { - ma_sub(src, dest, SetCond); + ma_sub(src, dest, SetCC); } void MacroAssemblerARMCompat::and32(Register src, Register dest) { - ma_and(src, dest, SetCond); + ma_and(src, dest, SetCC); } void MacroAssemblerARMCompat::and32(Imm32 imm, Register dest) { - ma_and(imm, dest, SetCond); + ma_and(imm, dest, SetCC); } void MacroAssemblerARMCompat::and32(const Address& src, Register dest) { load32(src, ScratchRegister); - ma_and(ScratchRegister, dest, SetCond); + ma_and(ScratchRegister, dest, SetCC); } void @@ -1961,7 +1974,7 @@ void MacroAssemblerARMCompat::addPtr(const Address& src, Register dest) { load32(src, ScratchRegister); - ma_add(ScratchRegister, dest, SetCond); + ma_add(ScratchRegister, dest, SetCC); } void @@ -2061,11 +2074,6 @@ MacroAssemblerARMCompat::movePtr(ImmGCPtr imm, Register dest) ma_mov(imm, dest); } void -MacroAssemblerARMCompat::movePtr(ImmMaybeNurseryPtr imm, Register dest) -{ - movePtr(noteMaybeNurseryPtr(imm), dest); -} -void MacroAssemblerARMCompat::movePtr(ImmPtr imm, Register dest) { movePtr(ImmWord(uintptr_t(imm.value)), dest); @@ -2204,7 +2212,7 @@ MacroAssemblerARMCompat::load32(AbsoluteAddress address, Register dest) void MacroAssemblerARMCompat::loadPtr(const Address& address, Register dest) { - ma_ldr(Operand(address), dest); + ma_ldr(address, dest); } void @@ -2233,23 +2241,16 @@ MacroAssemblerARMCompat::loadPtr(AsmJSAbsoluteAddress address, Register dest) loadPtr(Address(ScratchRegister, 0x0), dest); } -Operand payloadOf(const Address& address) { - return Operand(address.base, address.offset); -} -Operand tagOf(const Address& address) { - return Operand(address.base, address.offset + 4); -} - void MacroAssemblerARMCompat::loadPrivate(const Address& address, Register dest) { - ma_ldr(payloadOf(address), dest); + ma_ldr(ToPayload(address), dest); } void MacroAssemblerARMCompat::loadDouble(const Address& address, FloatRegister dest) { - ma_vldr(Operand(address), dest); + ma_vldr(address, dest); } void @@ -2263,14 +2264,14 @@ MacroAssemblerARMCompat::loadDouble(const BaseIndex& src, FloatRegister dest) int32_t offset = src.offset; as_add(ScratchRegister, base, lsl(index, scale)); - ma_vldr(Operand(ScratchRegister, offset), dest); + ma_vldr(Address(ScratchRegister, offset), dest); } void MacroAssemblerARMCompat::loadFloatAsDouble(const Address& address, FloatRegister dest) { VFPRegister rt = dest; - ma_vldr(Operand(address), rt.singleOverlay()); + ma_vldr(address, rt.singleOverlay()); as_vcvt(rt, rt.singleOverlay()); } @@ -2286,14 +2287,14 @@ MacroAssemblerARMCompat::loadFloatAsDouble(const BaseIndex& src, FloatRegister d VFPRegister rt = dest; as_add(ScratchRegister, base, lsl(index, scale)); - ma_vldr(Operand(ScratchRegister, offset), rt.singleOverlay()); + ma_vldr(Address(ScratchRegister, offset), rt.singleOverlay()); as_vcvt(rt, rt.singleOverlay()); } void MacroAssemblerARMCompat::loadFloat32(const Address& address, FloatRegister dest) { - ma_vldr(Operand(address), VFPRegister(dest).singleOverlay()); + ma_vldr(address, VFPRegister(dest).singleOverlay()); } void @@ -2307,7 +2308,7 @@ MacroAssemblerARMCompat::loadFloat32(const BaseIndex& src, FloatRegister dest) int32_t offset = src.offset; as_add(ScratchRegister, base, lsl(index, scale)); - ma_vldr(Operand(ScratchRegister, offset), VFPRegister(dest).singleOverlay()); + ma_vldr(Address(ScratchRegister, offset), VFPRegister(dest).singleOverlay()); } void @@ -2460,7 +2461,7 @@ template void MacroAssemblerARMCompat::storePtr(ImmGCPtr imm, BaseInd void MacroAssemblerARMCompat::storePtr(Register src, const Address& address) { - ma_str(src, Operand(address)); + ma_str(src, address); } void @@ -2503,7 +2504,7 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) ma_cmp(ScratchRegister, Imm32(0)); // If the lower 32 bits of the double were 0, then this was an exact number, // and it should be even. - ma_bic(Imm32(1), output, NoSetCond, Zero); + ma_bic(Imm32(1), output, LeaveCC, Zero); bind(¬Split); } else { Label outOfRange; @@ -2515,17 +2516,17 @@ MacroAssembler::clampDoubleToUint8(FloatRegister input, Register output) // Copy the converted value out. as_vxfer(output, InvalidReg, ScratchDoubleReg, FloatToCore); as_vmrs(pc); - ma_mov(Imm32(0), output, NoSetCond, Overflow); // NaN => 0 + ma_mov(Imm32(0), output, LeaveCC, Overflow); // NaN => 0 ma_b(&outOfRange, Overflow); // NaN ma_cmp(output, Imm32(0xff)); - ma_mov(Imm32(0xff), output, NoSetCond, Above); + ma_mov(Imm32(0xff), output, LeaveCC, Above); ma_b(&outOfRange, Above); // Convert it back to see if we got the same value back. as_vcvt(ScratchDoubleReg, VFPRegister(ScratchDoubleReg).uintOverlay()); // Do the check. as_vcmp(ScratchDoubleReg, input); as_vmrs(pc); - ma_bic(Imm32(1), output, NoSetCond, Zero); + ma_bic(Imm32(1), output, LeaveCC, Zero); bind(&outOfRange); } } @@ -3119,19 +3120,19 @@ MacroAssemblerARMCompat::branchTestValue(Condition cond, const Address& valaddr, // Check payload before tag, since payload is more likely to differ. if (cond == NotEqual) { - ma_ldr(payloadOf(valaddr), ScratchRegister); + ma_ldr(ToPayload(valaddr), ScratchRegister); branchPtr(NotEqual, ScratchRegister, value.payloadReg(), label); - ma_ldr(tagOf(valaddr), ScratchRegister); + ma_ldr(ToType(valaddr), ScratchRegister); branchPtr(NotEqual, ScratchRegister, value.typeReg(), label); } else { Label fallthrough; - ma_ldr(payloadOf(valaddr), ScratchRegister); + ma_ldr(ToPayload(valaddr), ScratchRegister); branchPtr(NotEqual, ScratchRegister, value.payloadReg(), &fallthrough); - ma_ldr(tagOf(valaddr), ScratchRegister); + ma_ldr(ToType(valaddr), ScratchRegister); branchPtr(Equal, ScratchRegister, value.typeReg(), label); bind(&fallthrough); @@ -3149,7 +3150,7 @@ MacroAssemblerARMCompat::unboxNonDouble(const ValueOperand& operand, Register de void MacroAssemblerARMCompat::unboxNonDouble(const Address& src, Register dest) { - ma_ldr(payloadOf(src), dest); + ma_ldr(ToPayload(src), dest); } void @@ -3171,7 +3172,7 @@ void MacroAssemblerARMCompat::unboxDouble(const Address& src, FloatRegister dest) { MOZ_ASSERT(dest.isDouble()); - ma_vldr(Operand(src), dest); + ma_vldr(src, dest); } void @@ -3258,7 +3259,7 @@ MacroAssemblerARMCompat::loadConstantFloat32(float f, FloatRegister dest) } void -MacroAssemblerARMCompat::loadInt32OrDouble(const Operand& src, FloatRegister dest) +MacroAssemblerARMCompat::loadInt32OrDouble(const Address& src, FloatRegister dest) { Label notInt32, end; // If it's an int, convert it to double. @@ -3337,21 +3338,21 @@ MacroAssemblerARMCompat::testDoubleTruthy(bool truthy, FloatRegister reg) Register MacroAssemblerARMCompat::extractObject(const Address& address, Register scratch) { - ma_ldr(payloadOf(address), scratch); + ma_ldr(ToPayload(address), scratch); return scratch; } Register MacroAssemblerARMCompat::extractTag(const Address& address, Register scratch) { - ma_ldr(tagOf(address), scratch); + ma_ldr(ToType(address), scratch); return scratch; } Register MacroAssemblerARMCompat::extractTag(const BaseIndex& address, Register scratch) { - ma_alu(address.base, lsl(address.index, address.scale), scratch, OpAdd, NoSetCond); + ma_alu(address.base, lsl(address.index, address.scale), scratch, OpAdd, LeaveCC); return extractTag(Address(scratch, address.offset), scratch); } @@ -3404,7 +3405,7 @@ MacroAssemblerARMCompat::moveValue(const Value& val, const ValueOperand& dest) // X86/X64-common (ARM too now) interface. ///////////////////////////////////////////////////////////////// void -MacroAssemblerARMCompat::storeValue(ValueOperand val, Operand dst) +MacroAssemblerARMCompat::storeValue(ValueOperand val, const Address& dst) { ma_str(val.payloadReg(), ToPayload(dst)); ma_str(val.typeReg(), ToType(dst)); @@ -3461,17 +3462,17 @@ MacroAssemblerARMCompat::loadValue(const BaseIndex& addr, ValueOperand val) void MacroAssemblerARMCompat::loadValue(Address src, ValueOperand val) { - Operand srcOp = Operand(src); - Operand payload = ToPayload(srcOp); - Operand type = ToType(srcOp); + Address payload = ToPayload(src); + Address type = ToType(src); + // TODO: copy this code into a generic function that acts on all sequences // of memory accesses if (isValueDTRDCandidate(val)) { // If the value we want is in two consecutive registers starting with an // even register, they can be combined as a single ldrd. - int offset = srcOp.disp(); + int offset = src.offset; if (offset < 256 && offset > -256) { - ma_ldrd(EDtrAddr(Register::FromCode(srcOp.base()), EDtrOffImm(srcOp.disp())), val.payloadReg(), val.typeReg()); + ma_ldrd(EDtrAddr(src.base, EDtrOffImm(src.offset)), val.payloadReg(), val.typeReg()); return; } } @@ -3479,11 +3480,11 @@ MacroAssemblerARMCompat::loadValue(Address src, ValueOperand val) // instruction. if (val.payloadReg().code() < val.typeReg().code()) { - if (srcOp.disp() <= 4 && srcOp.disp() >= -8 && (srcOp.disp() & 3) == 0) { + if (src.offset <= 4 && src.offset >= -8 && (src.offset & 3) == 0) { // Turns out each of the 4 value -8, -4, 0, 4 corresponds exactly // with one of LDM{DB, DA, IA, IB} DTMMode mode; - switch(srcOp.disp()) { + switch (src.offset) { case -8: mode = DB; break; @@ -3499,7 +3500,7 @@ MacroAssemblerARMCompat::loadValue(Address src, ValueOperand val) default: MOZ_CRASH("Bogus Offset for LoadValue as DTM"); } - startDataTransferM(IsLoad, Register::FromCode(srcOp.base()), mode); + startDataTransferM(IsLoad, src.base, mode); transferReg(val.payloadReg()); transferReg(val.typeReg()); finishDataTransfer(); @@ -3508,7 +3509,7 @@ MacroAssemblerARMCompat::loadValue(Address src, ValueOperand val) } // Ensure that loading the payload does not erase the pointer to the Value // in memory. - if (Register::FromCode(type.base()) != val.payloadReg()) { + if (type.base != val.payloadReg()) { ma_ldr(payload, val.payloadReg()); ma_ldr(type, val.typeReg()); } else { @@ -3534,14 +3535,9 @@ MacroAssemblerARMCompat::pushValue(ValueOperand val) { void MacroAssemblerARMCompat::pushValue(const Address& addr) { - MOZ_ASSERT(addr.base != StackPointer); - Operand srcOp = Operand(addr); - Operand payload = ToPayload(srcOp); - Operand type = ToType(srcOp); - - ma_ldr(type, ScratchRegister); + ma_ldr(ToType(addr), ScratchRegister); ma_push(ScratchRegister); - ma_ldr(payload, ScratchRegister); + ma_ldr(ToPayloadAfterStackPush(addr), ScratchRegister); ma_push(ScratchRegister); } @@ -3551,7 +3547,7 @@ MacroAssemblerARMCompat::popValue(ValueOperand val) { ma_pop(val.typeReg()); } void -MacroAssemblerARMCompat::storePayload(const Value& val, Operand dest) +MacroAssemblerARMCompat::storePayload(const Value& val, const Address& dest) { jsval_layout jv = JSVAL_TO_IMPL(val); if (val.isMarkable()) @@ -3560,15 +3556,11 @@ MacroAssemblerARMCompat::storePayload(const Value& val, Operand dest) ma_mov(Imm32(jv.s.payload.i32), secondScratchReg_); ma_str(secondScratchReg_, ToPayload(dest)); } -void -MacroAssemblerARMCompat::storePayload(Register src, Operand dest) -{ - if (dest.getTag() == Operand::MEM) { - ma_str(src, ToPayload(dest)); - return; - } - MOZ_CRASH("why do we do all of these things?"); +void +MacroAssemblerARMCompat::storePayload(Register src, const Address& dest) +{ + ma_str(src, ToPayload(dest)); } void @@ -3624,15 +3616,10 @@ MacroAssemblerARMCompat::storePayload(Register src, const BaseIndex& dest) } void -MacroAssemblerARMCompat::storeTypeTag(ImmTag tag, Operand dest) { - if (dest.getTag() == Operand::MEM) { - ma_mov(tag, secondScratchReg_); - ma_str(secondScratchReg_, ToType(dest)); - return; - } - - MOZ_CRASH("why do we do all of these things?"); - +MacroAssemblerARMCompat::storeTypeTag(ImmTag tag, const Address& dest) +{ + ma_mov(tag, secondScratchReg_); + ma_str(secondScratchReg_, ToType(dest)); } void @@ -3728,7 +3715,7 @@ MacroAssemblerARMCompat::breakpoint() void MacroAssemblerARMCompat::simulatorStop(const char* msg) { -#if defined(JS_ARM_SIMULATOR) +#ifdef JS_SIMULATOR_ARM MOZ_ASSERT(sizeof(char*) == 4); writeInst(0xefffffff); writeInst((int)msg); @@ -3766,7 +3753,7 @@ MacroAssemblerARMCompat::setupABICall(uint32_t args) passedArgs_ = 0; passedArgTypes_ = 0; usedIntSlots_ = 0; -#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR) +#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_SIMULATOR_ARM) usedFloatSlots_ = 0; usedFloat32_ = false; padding_ = 0; @@ -3802,7 +3789,7 @@ MacroAssemblerARMCompat::setupUnalignedABICall(uint32_t args, Register scratch) ma_push(scratch); } -#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR) +#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_SIMULATOR_ARM) void MacroAssemblerARMCompat::passHardFpABIArg(const MoveOperand& from, MoveOp::Type type) { @@ -3877,7 +3864,7 @@ MacroAssemblerARMCompat::passHardFpABIArg(const MoveOperand& from, MoveOp::Type } #endif -#if !defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR) +#if !defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_SIMULATOR_ARM) void MacroAssemblerARMCompat::passSoftFpABIArg(const MoveOperand& from, MoveOp::Type type) { @@ -3930,7 +3917,7 @@ MacroAssemblerARMCompat::passSoftFpABIArg(const MoveOperand& from, MoveOp::Type void MacroAssemblerARMCompat::passABIArg(const MoveOperand& from, MoveOp::Type type) { -#if defined(JS_ARM_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) if (UseHardFpABI()) MacroAssemblerARMCompat::passHardFpABIArg(from, type); else @@ -3968,7 +3955,7 @@ MacroAssemblerARMCompat::callWithABIPre(uint32_t* stackAdjust, bool callFromAsmJ MOZ_ASSERT(inCall_); *stackAdjust = ((usedIntSlots_ > NumIntArgRegs) ? usedIntSlots_ - NumIntArgRegs : 0) * sizeof(intptr_t); -#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR) +#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_SIMULATOR_ARM) if (UseHardFpABI()) *stackAdjust += 2*((usedFloatSlots_ > NumFloatArgRegs) ? usedFloatSlots_ - NumFloatArgRegs : 0) * sizeof(intptr_t); #endif @@ -4073,7 +4060,7 @@ MacroAssemblerARMCompat::callWithABIPost(uint32_t stackAdjust, MoveOp::Type resu inCall_ = false; } -#if defined(DEBUG) && defined(JS_ARM_SIMULATOR) +#if defined(DEBUG) && defined(JS_SIMULATOR_ARM) static void AssertValidABIFunctionType(uint32_t passedArgTypes) { @@ -4108,7 +4095,7 @@ AssertValidABIFunctionType(uint32_t passedArgTypes) void MacroAssemblerARMCompat::callWithABI(void* fun, MoveOp::Type result) { -#ifdef JS_ARM_SIMULATOR +#ifdef JS_SIMULATOR_ARM MOZ_ASSERT(passedArgs_ <= 15); passedArgTypes_ <<= ArgType_Shift; switch (result) { @@ -4183,7 +4170,7 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) Label return_; Label bailout; - ma_ldr(Operand(sp, offsetof(ResumeFromException, kind)), r0); + ma_ldr(Address(sp, offsetof(ResumeFromException, kind)), r0); branch32(Assembler::Equal, r0, Imm32(ResumeFromException::RESUME_ENTRY_FRAME), &entryFrame); branch32(Assembler::Equal, r0, Imm32(ResumeFromException::RESUME_CATCH), &catch_); branch32(Assembler::Equal, r0, Imm32(ResumeFromException::RESUME_FINALLY), &finally); @@ -4196,7 +4183,7 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) // and return from the entry frame. bind(&entryFrame); moveValue(MagicValue(JS_ION_ERROR), JSReturnOperand); - ma_ldr(Operand(sp, offsetof(ResumeFromException, stackPointer)), sp); + ma_ldr(Address(sp, offsetof(ResumeFromException, stackPointer)), sp); // We're going to be returning by the ion calling convention, which returns // by ??? (for now, I think ldr pc, [sp]!) @@ -4205,9 +4192,9 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) // If we found a catch handler, this must be a baseline frame. Restore state // and jump to the catch block. bind(&catch_); - ma_ldr(Operand(sp, offsetof(ResumeFromException, target)), r0); - ma_ldr(Operand(sp, offsetof(ResumeFromException, framePointer)), r11); - ma_ldr(Operand(sp, offsetof(ResumeFromException, stackPointer)), sp); + ma_ldr(Address(sp, offsetof(ResumeFromException, target)), r0); + ma_ldr(Address(sp, offsetof(ResumeFromException, framePointer)), r11); + ma_ldr(Address(sp, offsetof(ResumeFromException, stackPointer)), sp); jump(r0); // If we found a finally block, this must be a baseline frame. Push two @@ -4216,9 +4203,9 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) ValueOperand exception = ValueOperand(r1, r2); loadValue(Operand(sp, offsetof(ResumeFromException, exception)), exception); - ma_ldr(Operand(sp, offsetof(ResumeFromException, target)), r0); - ma_ldr(Operand(sp, offsetof(ResumeFromException, framePointer)), r11); - ma_ldr(Operand(sp, offsetof(ResumeFromException, stackPointer)), sp); + ma_ldr(Address(sp, offsetof(ResumeFromException, target)), r0); + ma_ldr(Address(sp, offsetof(ResumeFromException, framePointer)), r11); + ma_ldr(Address(sp, offsetof(ResumeFromException, stackPointer)), sp); pushValue(BooleanValue(true)); pushValue(exception); @@ -4227,8 +4214,8 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) // Only used in debug mode. Return BaselineFrame->returnValue() to the // caller. bind(&return_); - ma_ldr(Operand(sp, offsetof(ResumeFromException, framePointer)), r11); - ma_ldr(Operand(sp, offsetof(ResumeFromException, stackPointer)), sp); + ma_ldr(Address(sp, offsetof(ResumeFromException, framePointer)), r11); + ma_ldr(Address(sp, offsetof(ResumeFromException, stackPointer)), sp); loadValue(Address(r11, BaselineFrame::reverseOffsetOfReturnValue()), JSReturnOperand); ma_mov(r11, sp); pop(r11); @@ -4249,9 +4236,9 @@ MacroAssemblerARMCompat::handleFailureWithHandlerTail(void* handler) // If we are bailing out to baseline to handle an exception, jump to the // bailout tail stub. bind(&bailout); - ma_ldr(Operand(sp, offsetof(ResumeFromException, bailoutInfo)), r2); + ma_ldr(Address(sp, offsetof(ResumeFromException, bailoutInfo)), r2); ma_mov(Imm32(BAILOUT_RETURN_OK), r0); - ma_ldr(Operand(sp, offsetof(ResumeFromException, target)), r1); + ma_ldr(Address(sp, offsetof(ResumeFromException, target)), r1); jump(r1); } @@ -4282,7 +4269,7 @@ MacroAssemblerARMCompat::floor(FloatRegister input, Register output, Label* bail // that clamps to INT_MAX. ma_vcvt_F64_U32(input, ScratchDoubleReg.uintOverlay()); ma_vxfer(ScratchDoubleReg.uintOverlay(), output); - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(&fin); @@ -4301,10 +4288,10 @@ MacroAssemblerARMCompat::floor(FloatRegister input, Register output, Label* bail ma_vxfer(ScratchDoubleReg.uintOverlay(), output); ma_vcvt_U32_F64(ScratchDoubleReg.uintOverlay(), ScratchDoubleReg); compareDouble(ScratchDoubleReg, input); - ma_add(output, Imm32(1), output, NoSetCond, NotEqual); + ma_add(output, Imm32(1), output, LeaveCC, NotEqual); // Negate the output. Since INT_MIN < -INT_MAX, even after adding 1, the // result will still be a negative number. - ma_rsb(output, Imm32(0), output, SetCond); + ma_rsb(output, Imm32(0), output, SetCC); // Flip the negated input back to its original value. ma_vneg(input, input); // If the result looks non-negative, then this value didn't actually fit @@ -4333,7 +4320,7 @@ MacroAssemblerARMCompat::floorf(FloatRegister input, Register output, Label* bai // that clamps to INT_MAX. ma_vcvt_F32_U32(input, ScratchFloat32Reg.uintOverlay()); ma_vxfer(VFPRegister(ScratchFloat32Reg).uintOverlay(), output); - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(&fin); @@ -4352,10 +4339,10 @@ MacroAssemblerARMCompat::floorf(FloatRegister input, Register output, Label* bai ma_vxfer(VFPRegister(ScratchFloat32Reg).uintOverlay(), output); ma_vcvt_U32_F32(ScratchFloat32Reg.uintOverlay(), ScratchFloat32Reg); compareFloat(ScratchFloat32Reg, input); - ma_add(output, Imm32(1), output, NoSetCond, NotEqual); + ma_add(output, Imm32(1), output, LeaveCC, NotEqual); // Negate the output. Since INT_MIN < -INT_MAX, even after adding 1, the // result will still be a negative number. - ma_rsb(output, Imm32(0), output, SetCond); + ma_rsb(output, Imm32(0), output, SetCC); // Flip the negated input back to its original value. ma_vneg_f32(input, input); // If the result looks non-negative, then this value didn't actually fit @@ -4391,7 +4378,7 @@ MacroAssemblerARMCompat::ceil(FloatRegister input, Register output, Label* bail) FloatRegister ScratchUIntReg = ScratchDoubleReg.uintOverlay(); ma_vcvt_F64_U32(ScratchDoubleReg, ScratchUIntReg); ma_vxfer(ScratchUIntReg, output); - ma_neg(output, output, SetCond); + ma_neg(output, output, SetCC); ma_b(bail, NotSigned); ma_b(&fin); @@ -4410,9 +4397,9 @@ MacroAssemblerARMCompat::ceil(FloatRegister input, Register output, Label* bail) ma_vxfer(ScratchUIntReg, output); ma_vcvt_U32_F64(ScratchUIntReg, ScratchDoubleReg); compareDouble(ScratchDoubleReg, input); - ma_add(output, Imm32(1), output, NoSetCond, NotEqual); + ma_add(output, Imm32(1), output, LeaveCC, NotEqual); // Bail out if the add overflowed or the result is non positive. - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(bail, Zero); @@ -4444,7 +4431,7 @@ MacroAssemblerARMCompat::ceilf(FloatRegister input, Register output, Label* bail FloatRegister ScratchUIntReg = ScratchDoubleReg.uintOverlay(); ma_vcvt_F32_U32(ScratchFloat32Reg, ScratchUIntReg); ma_vxfer(ScratchUIntReg, output); - ma_neg(output, output, SetCond); + ma_neg(output, output, SetCC); ma_b(bail, NotSigned); ma_b(&fin); @@ -4463,9 +4450,9 @@ MacroAssemblerARMCompat::ceilf(FloatRegister input, Register output, Label* bail ma_vxfer(ScratchUIntReg, output); ma_vcvt_U32_F32(ScratchUIntReg, ScratchFloat32Reg); compareFloat(ScratchFloat32Reg, input); - ma_add(output, Imm32(1), output, NoSetCond, NotEqual); + ma_add(output, Imm32(1), output, LeaveCC, NotEqual); // Bail out if the add overflowed or the result is non positive. - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(bail, Zero); @@ -4525,7 +4512,7 @@ MacroAssemblerARMCompat::round(FloatRegister input, Register output, Label* bail ma_vcvt_F64_U32(tmp, ScratchDoubleReg.uintOverlay()); ma_vxfer(VFPRegister(ScratchDoubleReg).uintOverlay(), output); - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(&fin); @@ -4553,10 +4540,10 @@ MacroAssemblerARMCompat::round(FloatRegister input, Register output, Label* bail // away from zero, when it should be rounded towards \infty. ma_vcvt_U32_F64(ScratchDoubleReg.uintOverlay(), ScratchDoubleReg); compareDouble(ScratchDoubleReg, tmp); - ma_sub(output, Imm32(1), output, NoSetCond, Equal); + ma_sub(output, Imm32(1), output, LeaveCC, Equal); // Negate the output. Since INT_MIN < -INT_MAX, even after adding 1, the // result will still be a negative number. - ma_rsb(output, Imm32(0), output, SetCond); + ma_rsb(output, Imm32(0), output, SetCC); // If the result looks non-negative, then this value didn't actually fit // into the int range, and special handling is required, or it was zero, @@ -4599,7 +4586,7 @@ MacroAssemblerARMCompat::roundf(FloatRegister input, Register output, Label* bai // we are not applying any fixup after the operation). ma_vcvt_F32_U32(tmp, ScratchFloat32Reg.uintOverlay()); ma_vxfer(VFPRegister(ScratchFloat32Reg).uintOverlay(), output); - ma_mov(output, output, SetCond); + ma_mov(output, output, SetCC); ma_b(bail, Signed); ma_b(&fin); @@ -4639,12 +4626,12 @@ MacroAssemblerARMCompat::roundf(FloatRegister input, Register output, Label* bai // away from zero, when it should be rounded towards \infty. ma_vcvt_U32_F32(tmp.uintOverlay(), tmp); compareFloat(tmp, ScratchFloat32Reg); - ma_sub(output, Imm32(1), output, NoSetCond, Equal); + ma_sub(output, Imm32(1), output, LeaveCC, Equal); // Negate the output. Since INT_MIN < -INT_MAX, even after adding 1, the // result will still be a negative number. bind(&flipSign); - ma_rsb(output, Imm32(0), output, SetCond); + ma_rsb(output, Imm32(0), output, SetCC); // If the result looks non-negative, then this value didn't actually fit // into the int range, and special handling is required, or it was zero, diff --git a/js/src/jit/arm/MacroAssembler-arm.h b/js/src/jit/arm/MacroAssembler-arm.h index bb01421241..9ae940c721 100644 --- a/js/src/jit/arm/MacroAssembler-arm.h +++ b/js/src/jit/arm/MacroAssembler-arm.h @@ -40,21 +40,29 @@ class MacroAssemblerARM : public Assembler public: // Higher level tag testing code. - Operand ToPayload(Operand base) { + // TODO: Can probably remove the Operand versions. + Operand ToPayload(Operand base) const { return Operand(Register::FromCode(base.base()), base.disp()); } - Address ToPayload(Address base) { - return ToPayload(Operand(base)).toAddress(); + Address ToPayload(const Address& base) const { + return base; } protected: - Operand ToType(Operand base) { + Operand ToType(Operand base) const { return Operand(Register::FromCode(base.base()), base.disp() + sizeof(void*)); } - Address ToType(Address base) { + Address ToType(const Address& base) const { return ToType(Operand(base)).toAddress(); } + Address ToPayloadAfterStackPush(const Address& base) const { + // If we are based on StackPointer, pass over the type tag just pushed. + if (base.base == StackPointer) + return Address(base.base, base.offset + sizeof(void *)); + return ToPayload(base); + } + public: MacroAssemblerARM() : secondScratchReg_(lr) @@ -68,6 +76,7 @@ class MacroAssemblerARM : public Assembler void convertBoolToInt32(Register source, Register dest); void convertInt32ToDouble(Register src, FloatRegister dest); void convertInt32ToDouble(const Address& src, FloatRegister dest); + void convertInt32ToDouble(const BaseIndex& src, FloatRegister dest); void convertUInt32ToFloat32(Register src, FloatRegister dest); void convertUInt32ToDouble(Register src, FloatRegister dest); void convertDoubleToFloat32(FloatRegister src, FloatRegister dest, @@ -96,17 +105,17 @@ class MacroAssemblerARM : public Assembler // instructions. private: bool alu_dbl(Register src1, Imm32 imm, Register dest, ALUOp op, - SetCond_ sc, Condition c); + SBit s, Condition c); public: void ma_alu(Register src1, Operand2 op2, Register dest, ALUOp op, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_alu(Register src1, Imm32 imm, Register dest, ALUOp op, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_alu(Register src1, Operand op2, Register dest, ALUOp op, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_nop(); void ma_movPatchable(Imm32 imm, Register dest, Assembler::Condition c, @@ -126,12 +135,12 @@ class MacroAssemblerARM : public Assembler // ALU based ops // mov void ma_mov(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_mov(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_mov(ImmWord imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_mov(ImmGCPtr ptr, Register dest); @@ -150,98 +159,98 @@ class MacroAssemblerARM : public Assembler // Move not (dest <- ~src) void ma_mvn(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_mvn(Register src1, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Negate (dest <- -src) implemented as rsb dest, src, 0 void ma_neg(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // And void ma_and(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_and(Register src1, Register src2, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_and(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_and(Imm32 imm, Register src1, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Bit clear (dest <- dest & ~imm) or (dest <- src1 & ~src2) void ma_bic(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Exclusive or void ma_eor(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_eor(Register src1, Register src2, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_eor(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_eor(Imm32 imm, Register src1, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Or void ma_orr(Register src, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_orr(Register src1, Register src2, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_orr(Imm32 imm, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); void ma_orr(Imm32 imm, Register src1, Register dest, - SetCond_ sc = NoSetCond, Condition c = Always); + SBit s = LeaveCC, Condition c = Always); // Arithmetic based ops. // Add with carry: - void ma_adc(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_adc(Register src, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_adc(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_adc(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_adc(Register src, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_adc(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); // Add: - void ma_add(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_add(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_add(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_add(Register src1, Operand op, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_add(Register src1, Imm32 op, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_add(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_add(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_add(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_add(Register src1, Operand op, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_add(Register src1, Imm32 op, Register dest, SBit s = LeaveCC, Condition c = Always); // Subtract with carry: - void ma_sbc(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sbc(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sbc(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_sbc(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sbc(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sbc(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); // Subtract: - void ma_sub(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sub(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sub(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sub(Register src1, Operand op, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_sub(Register src1, Imm32 op, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_sub(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sub(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sub(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sub(Register src1, Operand op, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_sub(Register src1, Imm32 op, Register dest, SBit s = LeaveCC, Condition c = Always); // Reverse subtract: - void ma_rsb(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsb(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsb(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsb(Register src1, Imm32 op2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_rsb(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsb(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsb(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsb(Register src1, Imm32 op2, Register dest, SBit s = LeaveCC, Condition c = Always); // Reverse subtract with carry: - void ma_rsc(Imm32 imm, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsc(Register src1, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); - void ma_rsc(Register src1, Register src2, Register dest, SetCond_ sc = NoSetCond, Condition c = Always); + void ma_rsc(Imm32 imm, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsc(Register src1, Register dest, SBit s = LeaveCC, Condition c = Always); + void ma_rsc(Register src1, Register src2, Register dest, SBit s = LeaveCC, Condition c = Always); // Compares/tests. // Compare negative (sets condition codes as src1 + src2 would): @@ -299,11 +308,11 @@ class MacroAssemblerARM : public Assembler void ma_str(Register rt, DTRAddr addr, Index mode = Offset, Condition cc = Always); - void ma_str(Register rt, const Operand& addr, Index mode = Offset, Condition cc = Always); - void ma_dtr(LoadStore ls, Register rt, const Operand& addr, Index mode, Condition cc); + void ma_str(Register rt, const Address& addr, Index mode = Offset, Condition cc = Always); + void ma_dtr(LoadStore ls, Register rt, const Address& addr, Index mode, Condition cc); void ma_ldr(DTRAddr addr, Register rt, Index mode = Offset, Condition cc = Always); - void ma_ldr(const Operand& addr, Register rt, Index mode = Offset, Condition cc = Always); + void ma_ldr(const Address& addr, Register rt, Index mode = Offset, Condition cc = Always); void ma_ldrb(DTRAddr addr, Register rt, Index mode = Offset, Condition cc = Always); void ma_ldrh(EDtrAddr addr, Register rt, Index mode = Offset, Condition cc = Always); @@ -397,15 +406,15 @@ class MacroAssemblerARM : public Assembler void ma_vxfer(Register src1, Register src2, FloatRegister dest, Condition cc = Always); - BufferOffset ma_vdtr(LoadStore ls, const Operand& addr, VFPRegister dest, Condition cc = Always); + BufferOffset ma_vdtr(LoadStore ls, const Address& addr, VFPRegister dest, Condition cc = Always); BufferOffset ma_vldr(VFPAddr addr, VFPRegister dest, Condition cc = Always); - BufferOffset ma_vldr(const Operand& addr, VFPRegister dest, Condition cc = Always); + BufferOffset ma_vldr(const Address& addr, VFPRegister dest, Condition cc = Always); BufferOffset ma_vldr(VFPRegister src, Register base, Register index, int32_t shift = defaultShift, Condition cc = Always); BufferOffset ma_vstr(VFPRegister src, VFPAddr addr, Condition cc = Always); - BufferOffset ma_vstr(VFPRegister src, const Operand& addr, Condition cc = Always); + BufferOffset ma_vstr(VFPRegister src, const Address& addr, Condition cc = Always); BufferOffset ma_vstr(VFPRegister src, Register base, Register index, int32_t shift, int32_t offset, Condition cc = Always); @@ -501,7 +510,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM // use between one and three slots depending on its size and alignment // requirements. uint32_t usedIntSlots_; -#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_ARM_SIMULATOR) +#if defined(JS_CODEGEN_ARM_HARDFP) || defined(JS_SIMULATOR_ARM) uint32_t usedFloatSlots_; bool usedFloat32_; uint32_t padding_; @@ -634,11 +643,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_mov(imm, ScratchRegister); ma_push(ScratchRegister); } - void push(ImmMaybeNurseryPtr imm) { - push(noteMaybeNurseryPtr(imm)); - } - void push(const Address& address) { - ma_ldr(Operand(address.base, address.offset), ScratchRegister); + void push(const Address& addr) { + ma_ldr(addr, ScratchRegister); ma_push(ScratchRegister); } void push(Register reg) { @@ -701,16 +707,16 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void jump(Register reg) { ma_bx(reg); } - void jump(const Address& address) { - ma_ldr(Operand(address.base, address.offset), ScratchRegister); + void jump(const Address& addr) { + ma_ldr(addr, ScratchRegister); ma_bx(ScratchRegister); } void neg32(Register reg) { - ma_neg(reg, reg, SetCond); + ma_neg(reg, reg, SetCC); } void negl(Register reg) { - ma_neg(reg, reg, SetCond); + ma_neg(reg, reg, SetCC); } void test32(Register lhs, Register rhs) { ma_tst(lhs, rhs); @@ -718,8 +724,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void test32(Register lhs, Imm32 imm) { ma_tst(lhs, imm); } - void test32(const Address& address, Imm32 imm) { - ma_ldr(Operand(address.base, address.offset), ScratchRegister); + void test32(const Address& addr, Imm32 imm) { + ma_ldr(addr, ScratchRegister); ma_tst(ScratchRegister, imm); } void testPtr(Register lhs, Register rhs) { @@ -845,7 +851,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void boolValueToDouble(const ValueOperand& operand, FloatRegister dest); void int32ValueToDouble(const ValueOperand& operand, FloatRegister dest); - void loadInt32OrDouble(const Operand& src, FloatRegister dest); + void loadInt32OrDouble(const Address& src, FloatRegister dest); void loadInt32OrDouble(Register base, Register index, FloatRegister dest, int32_t shift = defaultShift); void loadConstantDouble(double dp, FloatRegister dest); @@ -881,7 +887,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM if (lhs.getTag() == Operand::OP2) { branch32(cond, lhs.toReg(), rhs, label); } else { - ma_ldr(lhs, ScratchRegister); + ma_ldr(lhs.toAddress(), ScratchRegister); branch32(cond, ScratchRegister, rhs, label); } } @@ -890,7 +896,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM branch32(cond, lhs.toReg(), rhs, label); } else { // branch32 will use ScratchRegister. - ma_ldr(lhs, secondScratchReg_); + ma_ldr(lhs.toAddress(), secondScratchReg_); branch32(cond, secondScratchReg_, rhs, label); } } @@ -1065,9 +1071,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_cmp(secondScratchReg_, ptr); ma_b(label, cond); } - void branchPtr(Condition cond, Address addr, ImmMaybeNurseryPtr ptr, Label* label) { - branchPtr(cond, addr, noteMaybeNurseryPtr(ptr), label); - } void branchPtr(Condition cond, Address addr, ImmWord ptr, Label* label) { ma_ldr(addr, secondScratchReg_); ma_cmp(secondScratchReg_, ptr); @@ -1109,7 +1112,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void loadUnboxedValue(Address address, MIRType type, AnyRegister dest) { if (dest.isFloat()) - loadInt32OrDouble(Operand(address), dest.fpu()); + loadInt32OrDouble(address, dest.fpu()); else ma_ldr(address, dest.gpr()); } @@ -1167,29 +1170,26 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_mov(s1, d1); } - void storeValue(ValueOperand val, Operand dst); + void storeValue(ValueOperand val, const Address& dst); void storeValue(ValueOperand val, const BaseIndex& dest); void storeValue(JSValueType type, Register reg, BaseIndex dest) { ma_alu(dest.base, lsl(dest.index, dest.scale), ScratchRegister, OpAdd); storeValue(type, reg, Address(ScratchRegister, dest.offset)); } - void storeValue(ValueOperand val, const Address& dest) { - storeValue(val, Operand(dest)); - } void storeValue(JSValueType type, Register reg, Address dest) { ma_str(reg, dest); ma_mov(ImmTag(JSVAL_TYPE_TO_TAG(type)), secondScratchReg_); ma_str(secondScratchReg_, Address(dest.base, dest.offset + 4)); } - void storeValue(const Value& val, Address dest) { + void storeValue(const Value& val, const Address& dest) { jsval_layout jv = JSVAL_TO_IMPL(val); ma_mov(Imm32(jv.s.tag), secondScratchReg_); - ma_str(secondScratchReg_, Address(dest.base, dest.offset + 4)); + ma_str(secondScratchReg_, ToType(dest)); if (val.isMarkable()) ma_mov(ImmGCPtr(reinterpret_cast(val.toGCThing())), secondScratchReg_); else ma_mov(Imm32(jv.s.payload.i32), secondScratchReg_); - ma_str(secondScratchReg_, dest); + ma_str(secondScratchReg_, ToPayload(dest)); } void storeValue(const Value& val, BaseIndex dest) { ma_alu(dest.base, lsl(dest.index, dest.scale), ScratchRegister, OpAdd); @@ -1209,7 +1209,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM jsval_layout jv = JSVAL_TO_IMPL(val); push(Imm32(jv.s.tag)); if (val.isMarkable()) - push(ImmMaybeNurseryPtr(reinterpret_cast(val.toGCThing()))); + push(ImmGCPtr(reinterpret_cast(val.toGCThing()))); else push(Imm32(jv.s.payload.i32)); } @@ -1217,13 +1217,13 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM push(ImmTag(JSVAL_TYPE_TO_TAG(type))); ma_push(reg); } - void pushValue(const Address &addr); + void pushValue(const Address& addr); - void storePayload(const Value &val, Operand dest); - void storePayload(Register src, Operand dest); - void storePayload(const Value &val, const BaseIndex &dest); + void storePayload(const Value& val, const Address& dest); + void storePayload(Register src, const Address& dest); + void storePayload(const Value& val, const BaseIndex& dest); void storePayload(Register src, const BaseIndex& dest); - void storeTypeTag(ImmTag tag, Operand dest); + void storeTypeTag(ImmTag tag, const Address& dest); void storeTypeTag(ImmTag tag, const BaseIndex& dest); void makeFrameDescriptor(Register frameSizeReg, FrameType type) { @@ -1292,7 +1292,6 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void movePtr(ImmPtr imm, Register dest); void movePtr(AsmJSImmPtr imm, Register dest); void movePtr(ImmGCPtr imm, Register dest); - void movePtr(ImmMaybeNurseryPtr imm, Register dest); void load8SignExtend(const Address& address, Register dest); void load8SignExtend(const BaseIndex& src, Register dest); @@ -1382,7 +1381,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void storePtr(Register src, const BaseIndex& address); void storePtr(Register src, AbsoluteAddress dest); void storeDouble(FloatRegister src, Address addr) { - ma_vstr(src, Operand(addr)); + ma_vstr(src, addr); } void storeDouble(FloatRegister src, BaseIndex addr) { uint32_t scale = Imm32::ShiftOf(addr.scale).value; @@ -1392,10 +1391,10 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_vmov(src, dest); } - void storeFloat32(FloatRegister src, Address addr) { - ma_vstr(VFPRegister(src).singleOverlay(), Operand(addr)); + void storeFloat32(FloatRegister src, const Address& addr) { + ma_vstr(VFPRegister(src).singleOverlay(), addr); } - void storeFloat32(FloatRegister src, BaseIndex addr) { + void storeFloat32(FloatRegister src, const BaseIndex& addr) { uint32_t scale = Imm32::ShiftOf(addr.scale).value; ma_vstr(VFPRegister(src).singleOverlay(), addr.base, addr.index, scale, addr.offset); } @@ -1641,9 +1640,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM void clampIntToUint8(Register reg) { // Look at (reg >> 8) if it is 0, then reg shouldn't be clamped if it is // <0, then we want to clamp to 0, otherwise, we wish to clamp to 255 - as_mov(ScratchRegister, asr(reg, 8), SetCond); - ma_mov(Imm32(0xff), reg, NoSetCond, NotEqual); - ma_mov(Imm32(0), reg, NoSetCond, Signed); + as_mov(ScratchRegister, asr(reg, 8), SetCC); + ma_mov(Imm32(0xff), reg, LeaveCC, NotEqual); + ma_mov(Imm32(0), reg, LeaveCC, Signed); } void incrementInt32Value(const Address& addr) { @@ -1721,7 +1720,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM emitSet(Assembler::Condition cond, Register dest) { ma_mov(Imm32(0), dest); - ma_mov(Imm32(1), dest, NoSetCond, cond); + ma_mov(Imm32(1), dest, LeaveCC, cond); } template @@ -1798,12 +1797,12 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM } void computeEffectiveAddress(const Address& address, Register dest) { - ma_add(address.base, Imm32(address.offset), dest, NoSetCond); + ma_add(address.base, Imm32(address.offset), dest, LeaveCC); } void computeEffectiveAddress(const BaseIndex& address, Register dest) { - ma_alu(address.base, lsl(address.index, address.scale), dest, OpAdd, NoSetCond); + ma_alu(address.base, lsl(address.index, address.scale), dest, OpAdd, LeaveCC); if (address.offset) - ma_add(dest, Imm32(address.offset), dest, NoSetCond); + ma_add(dest, Imm32(address.offset), dest, LeaveCC); } void floor(FloatRegister input, Register output, Label* handleNotAnInt); void floorf(FloatRegister input, Register output, Label* handleNotAnInt); @@ -1840,19 +1839,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM ma_add(addr.baseReg(), Imm32(addr.disp()), dest); } - void stackCheck(ImmWord limitAddr, Label* label) { - int* foo = 0; - *foo = 5; - movePtr(limitAddr, ScratchRegister); - ma_ldr(Address(ScratchRegister, 0), ScratchRegister); - ma_cmp(ScratchRegister, StackPointer); - ma_b(label, Assembler::AboveOrEqual); - } void abiret() { as_bx(lr); } - void ma_storeImm(Imm32 c, const Operand& dest) { + void ma_storeImm(Imm32 c, const Address& dest) { ma_mov(c, lr); ma_str(lr, dest); } diff --git a/js/src/jit/arm/MoveEmitter-arm.cpp b/js/src/jit/arm/MoveEmitter-arm.cpp index 0f8a83d612..2ff4bcfcb9 100644 --- a/js/src/jit/arm/MoveEmitter-arm.cpp +++ b/js/src/jit/arm/MoveEmitter-arm.cpp @@ -40,43 +40,36 @@ MoveEmitterARM::~MoveEmitterARM() assertDone(); } -Operand +Address MoveEmitterARM::cycleSlot(uint32_t slot, uint32_t subslot) const { int32_t offset = masm.framePushed() - pushedAtCycle_; MOZ_ASSERT(offset < 4096 && offset > -4096); - return Operand(StackPointer, offset + slot * sizeof(double) + subslot); + return Address(StackPointer, offset + slot * sizeof(double) + subslot); } -// THIS IS ALWAYS AN LDRAddr. It should not be wrapped in an operand, methinks. -Operand +Address MoveEmitterARM::spillSlot() const { int32_t offset = masm.framePushed() - pushedAtSpill_; MOZ_ASSERT(offset < 4096 && offset > -4096); - return Operand(StackPointer, offset); + return Address(StackPointer, offset); } -Operand -MoveEmitterARM::toOperand(const MoveOperand& operand, bool isFloat) const +Address +MoveEmitterARM::toAddress(const MoveOperand& operand) const { - if (operand.isMemoryOrEffectiveAddress()) { - if (operand.base() != StackPointer) { - MOZ_ASSERT(operand.disp() < 1024 && operand.disp() > -1024); - return Operand(operand.base(), operand.disp()); - } + MOZ_ASSERT(operand.isMemoryOrEffectiveAddress()); - MOZ_ASSERT(operand.disp() >= 0); - - // Otherwise, the stack offset may need to be adjusted. - return Operand(StackPointer, operand.disp() + (masm.framePushed() - pushedAtStart_)); + if (operand.base() != StackPointer) { + MOZ_ASSERT(operand.disp() < 1024 && operand.disp() > -1024); + return Operand(operand.base(), operand.disp()).toAddress(); } - if (operand.isGeneralReg()) - return Operand(operand.reg()); + MOZ_ASSERT(operand.disp() >= 0); - MOZ_ASSERT(operand.isFloatReg()); - return Operand(operand.floatReg()); + // Otherwise, the stack offset may need to be adjusted. + return Address(StackPointer, operand.disp() + (masm.framePushed() - pushedAtStart_)); } Register @@ -115,7 +108,7 @@ MoveEmitterARM::breakCycle(const MoveOperand& from, const MoveOperand& to, case MoveOp::FLOAT32: if (to.isMemory()) { VFPRegister temp = ScratchFloat32Reg; - masm.ma_vldr(toOperand(to, true), temp); + masm.ma_vldr(toAddress(to), temp); // Since it is uncertain if the load will be aligned or not // just fill both of them with the same value. masm.ma_vstr(temp, cycleSlot(slotId, 0)); @@ -130,7 +123,7 @@ MoveEmitterARM::breakCycle(const MoveOperand& from, const MoveOperand& to, case MoveOp::DOUBLE: if (to.isMemory()) { FloatRegister temp = ScratchDoubleReg; - masm.ma_vldr(toOperand(to, true), temp); + masm.ma_vldr(toAddress(to), temp); masm.ma_vstr(temp, cycleSlot(slotId, 0)); } else { masm.ma_vstr(to.floatReg().doubleOverlay(), cycleSlot(slotId, 0)); @@ -141,7 +134,7 @@ MoveEmitterARM::breakCycle(const MoveOperand& from, const MoveOperand& to, // an non-vfp value if (to.isMemory()) { Register temp = tempReg(); - masm.ma_ldr(toOperand(to, false), temp); + masm.ma_ldr(toAddress(to), temp); masm.ma_str(temp, cycleSlot(0,0)); } else { if (to.reg() == spilledReg_) { @@ -172,7 +165,7 @@ MoveEmitterARM::completeCycle(const MoveOperand& from, const MoveOperand& to, Mo if (to.isMemory()) { FloatRegister temp = ScratchDoubleReg; masm.ma_vldr(cycleSlot(slotId, 0), temp); - masm.ma_vstr(temp, toOperand(to, true)); + masm.ma_vstr(temp, toAddress(to)); } else { uint32_t offset = 0; if ((!from.isMemory()) && from.floatReg().numAlignedAliased() == 1) @@ -186,7 +179,7 @@ MoveEmitterARM::completeCycle(const MoveOperand& from, const MoveOperand& to, Mo if (to.isMemory()) { Register temp = tempReg(); masm.ma_ldr(cycleSlot(slotId, 0), temp); - masm.ma_str(temp, toOperand(to, false)); + masm.ma_str(temp, toAddress(to)); } else { if (to.reg() == spilledReg_) { // Make sure we don't re-clobber the spilled register later. @@ -216,21 +209,14 @@ MoveEmitterARM::emitMove(const MoveOperand& from, const MoveOperand& to) masm.ma_ldr(spillSlot(), spilledReg_); spilledReg_ = InvalidReg; } - switch (toOperand(to, false).getTag()) { - case Operand::OP2: - // secretly must be a register + if (to.isMemoryOrEffectiveAddress()) + masm.ma_str(from.reg(), toAddress(to)); + else masm.ma_mov(from.reg(), to.reg()); - break; - case Operand::MEM: - masm.ma_str(from.reg(), toOperand(to, false)); - break; - default: - MOZ_CRASH("strange move!"); - } } else if (to.isGeneralReg()) { MOZ_ASSERT(from.isMemoryOrEffectiveAddress()); if (from.isMemory()) - masm.ma_ldr(toOperand(from, false), to.reg()); + masm.ma_ldr(toAddress(from), to.reg()); else masm.ma_add(from.base(), Imm32(from.disp()), to.reg()); } else { @@ -239,11 +225,11 @@ MoveEmitterARM::emitMove(const MoveOperand& from, const MoveOperand& to) MOZ_ASSERT(from.isMemoryOrEffectiveAddress()); if (from.isMemory()) - masm.ma_ldr(toOperand(from, false), reg); + masm.ma_ldr(toAddress(from), reg); else masm.ma_add(from.base(), Imm32(from.disp()), reg); MOZ_ASSERT(to.base() != reg); - masm.ma_str(reg, toOperand(to, false)); + masm.ma_str(reg, toAddress(to)); } } @@ -254,19 +240,15 @@ MoveEmitterARM::emitFloat32Move(const MoveOperand& from, const MoveOperand& to) if (to.isFloatReg()) masm.ma_vmov_f32(from.floatReg(), to.floatReg()); else - masm.ma_vstr(VFPRegister(from.floatReg()).singleOverlay(), - toOperand(to, true)); + masm.ma_vstr(VFPRegister(from.floatReg()).singleOverlay(), toAddress(to)); } else if (to.isFloatReg()) { - masm.ma_vldr(toOperand(from, true), - VFPRegister(to.floatReg()).singleOverlay()); + masm.ma_vldr(toAddress(from), VFPRegister(to.floatReg()).singleOverlay()); } else { // Memory to memory move. MOZ_ASSERT(from.isMemory()); FloatRegister reg = ScratchFloat32Reg; - masm.ma_vldr(toOperand(from, true), - VFPRegister(reg).singleOverlay()); - masm.ma_vstr(VFPRegister(reg).singleOverlay(), - toOperand(to, true)); + masm.ma_vldr(toAddress(from), VFPRegister(reg).singleOverlay()); + masm.ma_vstr(VFPRegister(reg).singleOverlay(), toAddress(to)); } } @@ -277,15 +259,15 @@ MoveEmitterARM::emitDoubleMove(const MoveOperand& from, const MoveOperand& to) if (to.isFloatReg()) masm.ma_vmov(from.floatReg(), to.floatReg()); else - masm.ma_vstr(from.floatReg(), toOperand(to, true)); + masm.ma_vstr(from.floatReg(), toAddress(to)); } else if (to.isFloatReg()) { - masm.ma_vldr(toOperand(from, true), to.floatReg()); + masm.ma_vldr(toAddress(from), to.floatReg()); } else { // Memory to memory move. MOZ_ASSERT(from.isMemory()); FloatRegister reg = ScratchDoubleReg; - masm.ma_vldr(toOperand(from, true), reg); - masm.ma_vstr(reg, toOperand(to, true)); + masm.ma_vldr(toAddress(from), reg); + masm.ma_vstr(reg, toAddress(to)); } } diff --git a/js/src/jit/arm/MoveEmitter-arm.h b/js/src/jit/arm/MoveEmitter-arm.h index 770d1ef8fd..128d4689ef 100644 --- a/js/src/jit/arm/MoveEmitter-arm.h +++ b/js/src/jit/arm/MoveEmitter-arm.h @@ -36,9 +36,9 @@ class MoveEmitterARM void assertDone(); Register tempReg(); FloatRegister tempFloatReg(); - Operand cycleSlot(uint32_t slot, uint32_t subslot) const; - Operand spillSlot() const; - Operand toOperand(const MoveOperand& operand, bool isFloat) const; + Address cycleSlot(uint32_t slot, uint32_t subslot) const; + Address spillSlot() const; + Address toAddress(const MoveOperand& operand) const; void emitMove(const MoveOperand& from, const MoveOperand& to); void emitFloat32Move(const MoveOperand& from, const MoveOperand& to); diff --git a/js/src/jit/arm/Simulator-arm.cpp b/js/src/jit/arm/Simulator-arm.cpp index b391a30915..4e63a929ad 100644 --- a/js/src/jit/arm/Simulator-arm.cpp +++ b/js/src/jit/arm/Simulator-arm.cpp @@ -692,7 +692,7 @@ ArmDebugger::debug() i < 8 && (i % 2) == 0) { dvalue = getRegisterPairDoubleValue(i); - printf(" (%f)\n", dvalue); + printf(" (%.16g)\n", dvalue); } else { printf("\n"); } @@ -700,7 +700,7 @@ ArmDebugger::debug() for (uint32_t i = 0; i < FloatRegisters::TotalPhys; i++) { dvalue = getVFPDoubleRegisterValue(i); uint64_t as_words = mozilla::BitwiseCast(dvalue); - printf("%3s: %f 0x%08x %08x\n", + printf("%3s: %.16g 0x%08x %08x\n", FloatRegister::FromCode(i).name(), dvalue, static_cast(as_words >> 32), @@ -711,7 +711,7 @@ ArmDebugger::debug() printf("%s: 0x%08x %d \n", arg1, value, value); } else if (getVFPDoubleValue(arg1, &dvalue)) { uint64_t as_words = mozilla::BitwiseCast(dvalue); - printf("%s: %f 0x%08x %08x\n", + printf("%s: %.16g 0x%08x %08x\n", arg1, dvalue, static_cast(as_words >> 32), diff --git a/js/src/jit/arm/Simulator-arm.h b/js/src/jit/arm/Simulator-arm.h index 1510ad0121..fa7ed03bf4 100644 --- a/js/src/jit/arm/Simulator-arm.h +++ b/js/src/jit/arm/Simulator-arm.h @@ -29,7 +29,7 @@ #ifndef jit_arm_Simulator_arm_h #define jit_arm_Simulator_arm_h -#ifdef JS_ARM_SIMULATOR +#ifdef JS_SIMULATOR_ARM #include "jslock.h" @@ -441,6 +441,6 @@ class Simulator } // namespace jit } // namespace js -#endif /* JS_ARM_SIMULATOR */ +#endif /* JS_SIMULATOR_ARM */ #endif /* jit_arm_Simulator_arm_h */ diff --git a/js/src/jit/arm/Trampoline-arm.cpp b/js/src/jit/arm/Trampoline-arm.cpp index de64bb8bbd..0ca0ad55f5 100644 --- a/js/src/jit/arm/Trampoline-arm.cpp +++ b/js/src/jit/arm/Trampoline-arm.cpp @@ -183,7 +183,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type) // Get a copy of the number of args to use as a decrement counter, also set // the zero condition code. - aasm->as_mov(r5, O2Reg(r1), SetCond); + aasm->as_mov(r5, O2Reg(r1), SetCC); // Loop over arguments, copying them from an unknown buffer onto the Ion // stack so they can be accessed from JIT'ed code. @@ -193,7 +193,7 @@ JitRuntime::generateEnterJIT(JSContext* cx, EnterJitType type) aasm->as_b(&footer, Assembler::Zero); // Get the top of the loop. masm.bind(&header); - aasm->as_sub(r5, r5, Imm8(1), SetCond); + aasm->as_sub(r5, r5, Imm8(1), SetCC); // We could be more awesome, and unroll this, using a loadm // (particularly since the offset is effectively 0) but that seems more // error prone, and complex. @@ -502,7 +502,7 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut) Label undefLoopTop; masm.bind(&undefLoopTop); masm.ma_dataTransferN(IsStore, 64, true, sp, Imm32(-8), r4, PreIndex); - masm.ma_sub(r2, Imm32(1), r2, SetCond); + masm.ma_sub(r2, Imm32(1), r2, SetCC); masm.ma_b(&undefLoopTop, Assembler::NonZero); } @@ -514,7 +514,7 @@ JitRuntime::generateArgumentsRectifier(JSContext* cx, void** returnAddrOut) masm.ma_dataTransferN(IsLoad, 64, true, r3, Imm32(-8), r4, PostIndex); masm.ma_dataTransferN(IsStore, 64, true, sp, Imm32(-8), r4, PreIndex); - masm.ma_sub(r8, Imm32(1), r8, SetCond); + masm.ma_sub(r8, Imm32(1), r8, SetCC); masm.ma_b(©LoopTop, Assembler::NotSigned); } diff --git a/js/src/jit/arm64/BaselineIC-arm64.cpp b/js/src/jit/arm64/BaselineIC-arm64.cpp index 1689369645..3b2f5ff2c9 100644 --- a/js/src/jit/arm64/BaselineIC-arm64.cpp +++ b/js/src/jit/arm64/BaselineIC-arm64.cpp @@ -7,7 +7,7 @@ #include "jit/SharedIC.h" #include "jit/SharedICHelpers.h" -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 #include "jit/arm64/Assembler-arm64.h" #include "jit/arm64/BaselineCompiler-arm64.h" #include "jit/arm64/vixl/Debugger-vixl.h" diff --git a/js/src/jit/arm64/MacroAssembler-arm64.cpp b/js/src/jit/arm64/MacroAssembler-arm64.cpp index 7b1d7b494e..338d6dbdbe 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.cpp +++ b/js/src/jit/arm64/MacroAssembler-arm64.cpp @@ -388,7 +388,7 @@ MacroAssemblerCompat::callWithABIPost(uint32_t stackAdjust, MoveOp::Type result) // no other work needs to be done. } -#if defined(DEBUG) && defined(JS_ARM64_SIMULATOR) +#if defined(DEBUG) && defined(JS_SIMULATOR_ARM64) static void AssertValidABIFunctionType(uint32_t passedArgTypes) { @@ -418,12 +418,12 @@ AssertValidABIFunctionType(uint32_t passedArgTypes) MOZ_CRASH("Unexpected type"); } } -#endif // DEBUG && JS_ARM64_SIMULATOR +#endif // DEBUG && JS_SIMULATOR_ARM64 void MacroAssemblerCompat::callWithABI(void* fun, MoveOp::Type result) { -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 MOZ_ASSERT(passedIntArgs_ + passedFloatArgs_ <= 15); passedArgTypes_ <<= ArgType_Shift; switch (result) { @@ -437,7 +437,7 @@ MacroAssemblerCompat::callWithABI(void* fun, MoveOp::Type result) # endif ABIFunctionType type = ABIFunctionType(passedArgTypes_); fun = vixl::Simulator::RedirectNativeFunction(fun, type); -#endif // JS_ARM64_SIMULATOR +#endif // JS_SIMULATOR_ARM64 uint32_t stackAdjust; callWithABIPre(&stackAdjust); diff --git a/js/src/jit/arm64/MacroAssembler-arm64.h b/js/src/jit/arm64/MacroAssembler-arm64.h index b7f1c2301c..c2a6bd9481 100644 --- a/js/src/jit/arm64/MacroAssembler-arm64.h +++ b/js/src/jit/arm64/MacroAssembler-arm64.h @@ -3264,7 +3264,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler // Emits a simulator directive to save the current sp on an internal stack. void simulatorMarkSP() { -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 svc(vixl::kMarkStackPointer); #endif } @@ -3272,7 +3272,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler // Emits a simulator directive to pop from its internal stack // and assert that the value is equal to the current sp. void simulatorCheckSP() { -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 svc(vixl::kCheckStackPointer); #endif } diff --git a/js/src/jit/arm64/vixl/Cpu-vixl.cpp b/js/src/jit/arm64/vixl/Cpu-vixl.cpp index 595928c52b..8c2904ca35 100644 --- a/js/src/jit/arm64/vixl/Cpu-vixl.cpp +++ b/js/src/jit/arm64/vixl/Cpu-vixl.cpp @@ -63,7 +63,7 @@ CPU::SetUp() uint32_t CPU::GetCacheType() { -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 // This will lead to a cache with 1 byte long lines, which is fine since the // simulator will not need this information. return 0; @@ -80,7 +80,7 @@ CPU::GetCacheType() void CPU::EnsureIAndDCacheCoherency(void* address, size_t length) { -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 USE(address); USE(length); #else @@ -162,7 +162,7 @@ CPU::EnsureIAndDCacheCoherency(void* address, size_t length) // isb : Instruction Synchronisation Barrier " isb\n" : : : "memory"); -#endif // JS_ARM64_SIMULATOR +#endif // JS_SIMULATOR_ARM64 } } // namespace vixl diff --git a/js/src/jit/arm64/vixl/Debugger-vixl.cpp b/js/src/jit/arm64/vixl/Debugger-vixl.cpp index b4e6abd529..96844127c2 100644 --- a/js/src/jit/arm64/vixl/Debugger-vixl.cpp +++ b/js/src/jit/arm64/vixl/Debugger-vixl.cpp @@ -26,7 +26,7 @@ #include "js-config.h" -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 #include "jit/arm64/vixl/Debugger-vixl.h" @@ -1506,4 +1506,4 @@ bool InvalidCommand::Run(Debugger* debugger) { } // namespace vixl -#endif // JS_ARM64_SIMULATOR +#endif // JS_SIMULATOR_ARM64 diff --git a/js/src/jit/arm64/vixl/MacroAssembler-vixl.cpp b/js/src/jit/arm64/vixl/MacroAssembler-vixl.cpp index 81df82b124..f1cc9a1324 100644 --- a/js/src/jit/arm64/vixl/MacroAssembler-vixl.cpp +++ b/js/src/jit/arm64/vixl/MacroAssembler-vixl.cpp @@ -1222,7 +1222,7 @@ void MacroAssembler::PrintfNoPreserve(const char * format, const CPURegister& ar // Actually call printf. This part needs special handling for the simulator, // since the system printf function will use a different instruction set and // the procedure-call standard will not be compatible. -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 { InstructionAccurateScope scope(this, kPrintfLength / kInstructionSize); hlt(kPrintfOpcode); @@ -1319,7 +1319,7 @@ void MacroAssembler::Printf(const char * format, CPURegister arg0, CPURegister a void MacroAssembler::Trace(TraceParameters parameters, TraceCommand command) { -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 // The arguments to the trace pseudo instruction need to be contiguous in // memory, so make sure we don't try to emit a literal pool. InstructionAccurateScope scope(this, kTraceLength / kInstructionSize); @@ -1343,7 +1343,7 @@ void MacroAssembler::Trace(TraceParameters parameters, TraceCommand command) { void MacroAssembler::Log(TraceParameters parameters) { -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 // The arguments to the log pseudo instruction need to be contiguous in // memory, so make sure we don't try to emit a literal pool. InstructionAccurateScope scope(this, kLogLength / kInstructionSize); diff --git a/js/src/jit/arm64/vixl/MacroAssembler-vixl.h b/js/src/jit/arm64/vixl/MacroAssembler-vixl.h index d145383795..ddfe9130b4 100644 --- a/js/src/jit/arm64/vixl/MacroAssembler-vixl.h +++ b/js/src/jit/arm64/vixl/MacroAssembler-vixl.h @@ -926,7 +926,7 @@ class MacroAssembler : public js::jit::Assembler { umsubl(rd, rn, rm, ra); } void Unreachable() { -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 hlt(kUnreachableOpcode); #else // Branch to 0 to generate a segfault. diff --git a/js/src/jit/arm64/vixl/Simulator-vixl.cpp b/js/src/jit/arm64/vixl/Simulator-vixl.cpp index 77cc678342..47b2a7e63d 100644 --- a/js/src/jit/arm64/vixl/Simulator-vixl.cpp +++ b/js/src/jit/arm64/vixl/Simulator-vixl.cpp @@ -26,7 +26,7 @@ #include "js-config.h" -#ifdef JS_ARM64_SIMULATOR +#ifdef JS_SIMULATOR_ARM64 #include "jit/arm64/vixl/Simulator-vixl.h" @@ -2867,4 +2867,4 @@ void Simulator::DoPrintf(const Instruction* instr) { } // namespace vixl -#endif // JS_ARM64_SIMULATOR +#endif // JS_SIMULATOR_ARM64 diff --git a/js/src/jit/mips/Architecture-mips.cpp b/js/src/jit/mips/Architecture-mips.cpp index ec7ff204c6..dcc39b3130 100644 --- a/js/src/jit/mips/Architecture-mips.cpp +++ b/js/src/jit/mips/Architecture-mips.cpp @@ -23,7 +23,7 @@ uint32_t GetMIPSFlags() static uint32_t flags = 0; if (isSet) return flags; -#ifdef JS_MIPS_SIMULATOR +#ifdef JS_SIMULATOR_MIPS isSet = true; flags |= HWCAP_FPU; return flags; @@ -46,7 +46,7 @@ uint32_t GetMIPSFlags() #endif return false; -#endif // JS_MIPS_SIMULATOR +#endif // JS_SIMULATOR_MIPS } bool hasFPU() diff --git a/js/src/jit/mips/Assembler-mips.cpp b/js/src/jit/mips/Assembler-mips.cpp index 042e91f688..1f2ed8ac17 100644 --- a/js/src/jit/mips/Assembler-mips.cpp +++ b/js/src/jit/mips/Assembler-mips.cpp @@ -288,12 +288,6 @@ TraceOneDataRelocation(JSTracer* trc, Instruction* inst) void* ptr = (void*)Assembler::ExtractLuiOriValue(inst, inst->next()); void* prior = ptr; - // The low bit shouldn't be set. If it is, we probably got a dummy - // pointer inserted by CodeGenerator::visitNurseryObject, but we - // shouldn't be able to trigger GC before those are patched to their - // real values. - MOZ_ASSERT(!(uintptr_t(ptr) & 0x1)); - // No barrier needed since these are constants. TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast(&ptr), "ion-masm-ptr"); @@ -329,43 +323,6 @@ Assembler::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReade ::TraceDataRelocations(trc, code->raw(), reader); } -void -Assembler::FixupNurseryObjects(JSContext* cx, JitCode* code, CompactBufferReader& reader, - const ObjectVector& nurseryObjects) -{ - MOZ_ASSERT(!nurseryObjects.empty()); - - uint8_t* buffer = code->raw(); - bool hasNurseryPointers = false; - - while (reader.more()) { - size_t offset = reader.readUnsigned(); - Instruction* inst = (Instruction*)(buffer + offset); - - void* ptr = (void*)Assembler::ExtractLuiOriValue(inst, inst->next()); - uintptr_t word = uintptr_t(ptr); - - if (!(word & 0x1)) - continue; - - uint32_t index = word >> 1; - JSObject* obj = nurseryObjects[index]; - - Assembler::UpdateLuiOriValue(inst, inst->next(), uint32_t(obj)); - AutoFlushICache::flush(uintptr_t(inst), 8); - - // Either all objects are still in the nursery, or all objects are - // tenured. - MOZ_ASSERT_IF(hasNurseryPointers, IsInsideNursery(obj)); - - if (!hasNurseryPointers && IsInsideNursery(obj)) - hasNurseryPointers = true; - } - - if (hasNurseryPointers) - cx->runtime()->gc.storeBuffer.putWholeCellFromMainThread(code); -} - void Assembler::copyJumpRelocationTable(uint8_t* dest) { diff --git a/js/src/jit/mips/Assembler-mips.h b/js/src/jit/mips/Assembler-mips.h index 320df5633d..b21085aff1 100644 --- a/js/src/jit/mips/Assembler-mips.h +++ b/js/src/jit/mips/Assembler-mips.h @@ -771,8 +771,11 @@ class Assembler : public AssemblerShared // As opposed to x86/x64 version, the data relocation has to be executed // before to recover the pointer, and not after. void writeDataRelocation(ImmGCPtr ptr) { - if (ptr.value) + if (ptr.value) { + if (gc::IsInsideNursery(ptr.value)) + embedsNurseryPointers_ = true; dataRelocations_.writeUnsigned(nextOffset().getOffset()); + } } void writePrebarrierOffset(CodeOffsetLabel label) { preBarriers_.writeUnsigned(label.offset()); @@ -1020,11 +1023,8 @@ class Assembler : public AssemblerShared static void TraceJumpRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader); static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader); - static void FixupNurseryObjects(JSContext* cx, JitCode* code, CompactBufferReader& reader, - const ObjectVector& nurseryObjects); - static bool SupportsFloatingPoint() { -#if (defined(__mips_hard_float) && !defined(__mips_single_float)) || defined(JS_MIPS_SIMULATOR) +#if (defined(__mips_hard_float) && !defined(__mips_single_float)) || defined(JS_SIMULATOR_MIPS) return true; #else return false; diff --git a/js/src/jit/mips/MacroAssembler-mips.cpp b/js/src/jit/mips/MacroAssembler-mips.cpp index 767879007f..4a81e0f537 100644 --- a/js/src/jit/mips/MacroAssembler-mips.cpp +++ b/js/src/jit/mips/MacroAssembler-mips.cpp @@ -1743,11 +1743,6 @@ MacroAssemblerMIPSCompat::movePtr(ImmGCPtr imm, Register dest) ma_li(dest, imm); } -void -MacroAssemblerMIPSCompat::movePtr(ImmMaybeNurseryPtr imm, Register dest) -{ - movePtr(noteMaybeNurseryPtr(imm), dest); -} void MacroAssemblerMIPSCompat::movePtr(ImmPtr imm, Register dest) { @@ -3381,7 +3376,7 @@ MacroAssemblerMIPSCompat::callWithABIPost(uint32_t stackAdjust, MoveOp::Type res inCall_ = false; } -#if defined(DEBUG) && defined(JS_MIPS_SIMULATOR) +#if defined(DEBUG) && defined(JS_SIMULATOR_MIPS) static void AssertValidABIFunctionType(uint32_t passedArgTypes) { @@ -3416,7 +3411,7 @@ AssertValidABIFunctionType(uint32_t passedArgTypes) void MacroAssemblerMIPSCompat::callWithABI(void* fun, MoveOp::Type result) { -#ifdef JS_MIPS_SIMULATOR +#ifdef JS_SIMULATOR_MIPS MOZ_ASSERT(passedArgs_ <= 15); passedArgTypes_ <<= ArgType_Shift; switch (result) { diff --git a/js/src/jit/mips/MacroAssembler-mips.h b/js/src/jit/mips/MacroAssembler-mips.h index 47438dba63..5797e9f091 100644 --- a/js/src/jit/mips/MacroAssembler-mips.h +++ b/js/src/jit/mips/MacroAssembler-mips.h @@ -805,9 +805,6 @@ public: ma_li(ScratchRegister, ptr); ma_b(SecondScratchReg, ScratchRegister, label, cond); } - void branchPtr(Condition cond, Address addr, ImmMaybeNurseryPtr ptr, Label* label) { - branchPtr(cond, addr, noteMaybeNurseryPtr(ptr), label); - } void branchPtr(Condition cond, Address addr, ImmWord ptr, Label* label) { ma_lw(SecondScratchReg, addr); @@ -1218,7 +1215,6 @@ public: void movePtr(ImmPtr imm, Register dest); void movePtr(AsmJSImmPtr imm, Register dest); void movePtr(ImmGCPtr imm, Register dest); - void movePtr(ImmMaybeNurseryPtr imm, Register dest); void load8SignExtend(const Address& address, Register dest); void load8SignExtend(const BaseIndex& src, Register dest); diff --git a/js/src/jit/mips/Simulator-mips.h b/js/src/jit/mips/Simulator-mips.h index 2eba056fef..a17b083859 100644 --- a/js/src/jit/mips/Simulator-mips.h +++ b/js/src/jit/mips/Simulator-mips.h @@ -29,7 +29,7 @@ #ifndef jit_mips_Simulator_mips_h #define jit_mips_Simulator_mips_h -#ifdef JS_MIPS_SIMULATOR +#ifdef JS_SIMULATOR_MIPS #include "jslock.h" @@ -416,6 +416,6 @@ class Simulator { } // namespace jit } // namespace js -#endif /* JS_MIPS_SIMULATOR */ +#endif /* JS_SIMULATOR_MIPS */ #endif /* jit_mips_Simulator_mips_h */ diff --git a/js/src/jit/none/MacroAssembler-none.h b/js/src/jit/none/MacroAssembler-none.h index a80a0eea3b..bc2fd4e940 100644 --- a/js/src/jit/none/MacroAssembler-none.h +++ b/js/src/jit/none/MacroAssembler-none.h @@ -171,12 +171,6 @@ class MacroAssemblerNone : public Assembler static void TraceJumpRelocations(JSTracer*, JitCode*, CompactBufferReader&) { MOZ_CRASH(); } static void TraceDataRelocations(JSTracer*, JitCode*, CompactBufferReader&) { MOZ_CRASH(); } - static void FixupNurseryObjects(JSContext*, JitCode*, CompactBufferReader&, - const ObjectVector&) - { - MOZ_CRASH(); - } - static bool SupportsFloatingPoint() { return false; } static bool SupportsSimd() { return false; } @@ -498,8 +492,14 @@ class ABIArgGenerator static const Register NonReturn_VolatileReg1; }; -static inline void PatchJump(CodeLocationJump&, CodeLocationLabel) { MOZ_CRASH(); } +static inline void +PatchJump(CodeLocationJump&, CodeLocationLabel, ReprotectCode reprotect = DontReprotect) +{ + MOZ_CRASH(); +} + static inline bool GetTempRegForIntArg(uint32_t, uint32_t, Register*) { MOZ_CRASH(); } + static inline void PatchBackedge(CodeLocationJump& jump_, CodeLocationLabel label, JitRuntime::BackedgeTarget target) { diff --git a/js/src/jit/shared/Assembler-shared.h b/js/src/jit/shared/Assembler-shared.h index 9022b25493..746702a5e2 100644 --- a/js/src/jit/shared/Assembler-shared.h +++ b/js/src/jit/shared/Assembler-shared.h @@ -214,39 +214,6 @@ struct PatchedImmPtr { class AssemblerShared; class ImmGCPtr; -// Used for immediates which require relocation and may be traced during minor GC. -class ImmMaybeNurseryPtr -{ - friend class AssemblerShared; - friend class ImmGCPtr; - const gc::Cell* value; - - ImmMaybeNurseryPtr() : value(0) {} - - public: - explicit ImmMaybeNurseryPtr(const gc::Cell* ptr) : value(ptr) - { - // asm.js shouldn't be creating GC things - MOZ_ASSERT(!IsCompilingAsmJS()); - } -}; - -// Dummy value used for nursery pointers during Ion compilation, see -// LNurseryObject. -class IonNurseryPtr -{ - const gc::Cell* ptr; - - public: - friend class ImmGCPtr; - - explicit IonNurseryPtr(const gc::Cell* ptr) : ptr(ptr) - { - MOZ_ASSERT(ptr); - MOZ_ASSERT(uintptr_t(ptr) & 0x1); - } -}; - // Used for immediates which require relocation. class ImmGCPtr { @@ -255,15 +222,10 @@ class ImmGCPtr explicit ImmGCPtr(const gc::Cell* ptr) : value(ptr) { - MOZ_ASSERT_IF(ptr, ptr->isTenured()); - - // asm.js shouldn't be creating GC things - MOZ_ASSERT(!IsCompilingAsmJS()); - } - - explicit ImmGCPtr(IonNurseryPtr ptr) : value(ptr.ptr) - { - MOZ_ASSERT(value); + // Nursery pointers can't be used if the main thread might be currently + // performing a minor GC. + MOZ_ASSERT_IF(ptr && !ptr->isTenured(), + !CurrentThreadIsIonCompilingSafeForMinorGC()); // asm.js shouldn't be creating GC things MOZ_ASSERT(!IsCompilingAsmJS()); @@ -271,13 +233,6 @@ class ImmGCPtr private: ImmGCPtr() : value(0) {} - - friend class AssemblerShared; - explicit ImmGCPtr(ImmMaybeNurseryPtr ptr) : value(ptr.value) - { - // asm.js shouldn't be creating GC things - MOZ_ASSERT(!IsCompilingAsmJS()); - } }; // Pointer to be embedded as an immediate that is loaded/stored from by an @@ -980,18 +935,6 @@ class AssemblerShared return embedsNurseryPointers_; } - ImmGCPtr noteMaybeNurseryPtr(ImmMaybeNurseryPtr ptr) { - if (ptr.value && gc::IsInsideNursery(ptr.value)) { - // noteMaybeNurseryPtr can be reached from off-thread compilation, - // though not with an actual nursery pointer argument in that case. - MOZ_ASSERT(GetJitContext()->runtime->onMainThread()); - // Do not be ion-compiling on the main thread. - MOZ_ASSERT(!GetJitContext()->runtime->mainThread()->ionCompiling); - embedsNurseryPointers_ = true; - } - return ImmGCPtr(ptr); - } - void append(const CallSiteDesc& desc, size_t currentOffset, size_t framePushed) { // framePushed does not include sizeof(AsmJSFrame), so add it in here (see // CallSite::stackDepth). diff --git a/js/src/jit/x64/Assembler-x64.cpp b/js/src/jit/x64/Assembler-x64.cpp index 7e49776f64..419a109140 100644 --- a/js/src/jit/x64/Assembler-x64.cpp +++ b/js/src/jit/x64/Assembler-x64.cpp @@ -175,9 +175,10 @@ Assembler::PatchableJumpAddress(JitCode* code, size_t index) /* static */ void -Assembler::PatchJumpEntry(uint8_t* entry, uint8_t* target) +Assembler::PatchJumpEntry(uint8_t* entry, uint8_t* target, ReprotectCode reprotect) { uint8_t** index = (uint8_t**) (entry + SizeOfExtendedJump - sizeof(void*)); + MaybeAutoWritableJitCode awjc(index, sizeof(void*), reprotect); *index = target; } diff --git a/js/src/jit/x64/Assembler-x64.h b/js/src/jit/x64/Assembler-x64.h index d2445140d4..8b5f2c08e5 100644 --- a/js/src/jit/x64/Assembler-x64.h +++ b/js/src/jit/x64/Assembler-x64.h @@ -265,7 +265,7 @@ class Assembler : public AssemblerX86Shared using AssemblerX86Shared::vmovq; static uint8_t* PatchableJumpAddress(JitCode* code, size_t index); - static void PatchJumpEntry(uint8_t* entry, uint8_t* target); + static void PatchJumpEntry(uint8_t* entry, uint8_t* target, ReprotectCode reprotect); Assembler() : extendedJumpTable_(0) @@ -794,15 +794,20 @@ class Assembler : public AssemblerX86Shared }; static inline void -PatchJump(CodeLocationJump jump, CodeLocationLabel label) +PatchJump(CodeLocationJump jump, CodeLocationLabel label, ReprotectCode reprotect = DontReprotect) { if (X86Encoding::CanRelinkJump(jump.raw(), label.raw())) { + MaybeAutoWritableJitCode awjc(jump.raw() - 8, 8, reprotect); X86Encoding::SetRel32(jump.raw(), label.raw()); } else { - X86Encoding::SetRel32(jump.raw(), jump.jumpTableEntry()); - Assembler::PatchJumpEntry(jump.jumpTableEntry(), label.raw()); + { + MaybeAutoWritableJitCode awjc(jump.raw() - 8, 8, reprotect); + X86Encoding::SetRel32(jump.raw(), jump.jumpTableEntry()); + } + Assembler::PatchJumpEntry(jump.jumpTableEntry(), label.raw(), reprotect); } } + static inline void PatchBackedge(CodeLocationJump& jump_, CodeLocationLabel label, JitRuntime::BackedgeTarget target) { diff --git a/js/src/jit/x64/MacroAssembler-x64.h b/js/src/jit/x64/MacroAssembler-x64.h index 407cf11f72..195c73d200 100644 --- a/js/src/jit/x64/MacroAssembler-x64.h +++ b/js/src/jit/x64/MacroAssembler-x64.h @@ -502,9 +502,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared movePtr(rhs, ScratchReg); cmpPtr(lhs, ScratchReg); } - void cmpPtr(const Operand& lhs, const ImmMaybeNurseryPtr rhs) { - cmpPtr(lhs, noteMaybeNurseryPtr(rhs)); - } void cmpPtr(const Operand& lhs, const ImmWord rhs) { if ((intptr_t)rhs.value <= INT32_MAX && (intptr_t)rhs.value >= INT32_MIN) { cmpPtr(lhs, Imm32((int32_t)rhs.value)); @@ -733,9 +730,6 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared void movePtr(ImmGCPtr imm, Register dest) { movq(imm, dest); } - void movePtr(ImmMaybeNurseryPtr imm, Register dest) { - movePtr(noteMaybeNurseryPtr(imm), dest); - } void loadPtr(AbsoluteAddress address, Register dest) { if (X86Encoding::IsAddressImmediate(address.addr)) { movq(Operand(address), dest); diff --git a/js/src/jit/x86-shared/Assembler-x86-shared.cpp b/js/src/jit/x86-shared/Assembler-x86-shared.cpp index 7542b6f0bd..f6e7393bcf 100644 --- a/js/src/jit/x86-shared/Assembler-x86-shared.cpp +++ b/js/src/jit/x86-shared/Assembler-x86-shared.cpp @@ -62,17 +62,12 @@ TraceDataRelocations(JSTracer* trc, uint8_t* buffer, CompactBufferReader& reader layout.asBits = *word; Value v = IMPL_TO_JSVAL(layout); TraceManuallyBarrieredEdge(trc, &v, "ion-masm-value"); - *word = JSVAL_TO_IMPL(v).asBits; + if (*word != JSVAL_TO_IMPL(v).asBits) + *word = JSVAL_TO_IMPL(v).asBits; continue; } #endif - // The low bit shouldn't be set. If it is, we probably got a dummy - // pointer inserted by CodeGenerator::visitNurseryObject, but we - // shouldn't be able to trigger GC before those are patched to their - // real values. - MOZ_ASSERT(!(*reinterpret_cast(ptr) & 0x1)); - // No barrier needed since these are constants. TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast(ptr), "ion-masm-ptr"); @@ -86,45 +81,6 @@ AssemblerX86Shared::TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBu ::TraceDataRelocations(trc, code->raw(), reader); } -void -AssemblerX86Shared::FixupNurseryObjects(JSContext* cx, JitCode* code, CompactBufferReader& reader, - const ObjectVector& nurseryObjects) -{ - MOZ_ASSERT(!nurseryObjects.empty()); - - uint8_t* buffer = code->raw(); - bool hasNurseryPointers = false; - - while (reader.more()) { - size_t offset = reader.readUnsigned(); - void** ptr = X86Encoding::GetPointerRef(buffer + offset); - - uintptr_t* word = reinterpret_cast(ptr); - -#ifdef JS_PUNBOX64 - if (*word >> JSVAL_TAG_SHIFT) - continue; // This is a Value. -#endif - - if (!(*word & 0x1)) - continue; - - uint32_t index = *word >> 1; - JSObject* obj = nurseryObjects[index]; - *word = uintptr_t(obj); - - // Either all objects are still in the nursery, or all objects are - // tenured. - MOZ_ASSERT_IF(hasNurseryPointers, IsInsideNursery(obj)); - - if (!hasNurseryPointers && IsInsideNursery(obj)) - hasNurseryPointers = true; - } - - if (hasNurseryPointers) - cx->runtime()->gc.storeBuffer.putWholeCellFromMainThread(code); -} - void AssemblerX86Shared::trace(JSTracer* trc) { diff --git a/js/src/jit/x86-shared/Assembler-x86-shared.h b/js/src/jit/x86-shared/Assembler-x86-shared.h index a76e4564d1..c3bceadcd1 100644 --- a/js/src/jit/x86-shared/Assembler-x86-shared.h +++ b/js/src/jit/x86-shared/Assembler-x86-shared.h @@ -213,8 +213,11 @@ class AssemblerX86Shared : public AssemblerShared CompactBufferWriter preBarriers_; void writeDataRelocation(ImmGCPtr ptr) { - if (ptr.value) + if (ptr.value) { + if (gc::IsInsideNursery(ptr.value)) + embedsNurseryPointers_ = true; dataRelocations_.writeUnsigned(masm.currentOffset()); + } } void writePrebarrierOffset(CodeOffsetLabel label) { preBarriers_.writeUnsigned(label.offset()); @@ -332,9 +335,6 @@ class AssemblerX86Shared : public AssemblerShared static void TraceDataRelocations(JSTracer* trc, JitCode* code, CompactBufferReader& reader); - static void FixupNurseryObjects(JSContext* cx, JitCode* code, CompactBufferReader& reader, - const ObjectVector& nurseryObjects); - // MacroAssemblers hold onto gcthings, so they are traced by the GC. void trace(JSTracer* trc); diff --git a/js/src/jit/x86-shared/BaseAssembler-x86-shared.h b/js/src/jit/x86-shared/BaseAssembler-x86-shared.h index ba4e8e6a5b..97aa266823 100644 --- a/js/src/jit/x86-shared/BaseAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/BaseAssembler-x86-shared.h @@ -3679,12 +3679,12 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off void doubleConstant(double d) { - spew(".double %.20f", d); + spew(".double %.16g", d); m_formatter.doubleConstant(d); } void floatConstant(float f) { - spew(".float %.20f", f); + spew(".float %.16g", f); m_formatter.floatConstant(f); } @@ -3696,7 +3696,7 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off } void float32x4Constant(const float f[4]) { - spew(".float %f,%f,%f,%f", f[0], f[1], f[2], f[3]); + spew(".float %g,%g,%g,%g", f[0], f[1], f[2], f[3]); MOZ_ASSERT(m_formatter.isAligned(16)); m_formatter.float32x4Constant(f); } diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h index af2ee86102..fa660e7a21 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.h +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.h @@ -659,6 +659,9 @@ class MacroAssemblerX86Shared : public Assembler void convertInt32ToDouble(const Address& src, FloatRegister dest) { convertInt32ToDouble(Operand(src), dest); } + void convertInt32ToDouble(const BaseIndex& src, FloatRegister dest) { + convertInt32ToDouble(Operand(src), dest); + } void convertInt32ToDouble(const Operand& src, FloatRegister dest) { // Clear the output register first to break dependencies; see above; zeroDouble(dest); diff --git a/js/src/jit/x86/Assembler-x86.h b/js/src/jit/x86/Assembler-x86.h index 56e0bece04..5809961982 100644 --- a/js/src/jit/x86/Assembler-x86.h +++ b/js/src/jit/x86/Assembler-x86.h @@ -159,7 +159,7 @@ namespace js { namespace jit { static inline void -PatchJump(CodeLocationJump jump, CodeLocationLabel label) +PatchJump(CodeLocationJump jump, CodeLocationLabel label, ReprotectCode reprotect = DontReprotect) { #ifdef DEBUG // Assert that we're overwriting a jump instruction, either: @@ -169,6 +169,7 @@ PatchJump(CodeLocationJump jump, CodeLocationLabel label) MOZ_ASSERT(((*x >= 0x80 && *x <= 0x8F) && *(x - 1) == 0x0F) || (*x == 0xE9)); #endif + MaybeAutoWritableJitCode awjc(jump.raw() - 8, 8, reprotect); X86Encoding::SetRel32(jump.raw(), label.raw()); } static inline void @@ -215,9 +216,6 @@ class Assembler : public AssemblerX86Shared masm.push_i32(int32_t(ptr.value)); writeDataRelocation(ptr); } - void push(ImmMaybeNurseryPtr ptr) { - push(noteMaybeNurseryPtr(ptr)); - } void push(const ImmWord imm) { push(Imm32(imm.value)); } @@ -368,9 +366,6 @@ class Assembler : public AssemblerX86Shared MOZ_CRASH("unexpected operand kind"); } } - void cmpl(ImmMaybeNurseryPtr rhs, const Operand& lhs) { - cmpl(noteMaybeNurseryPtr(rhs), lhs); - } void cmpl(Register rhs, AsmJSAbsoluteAddress lhs) { masm.cmpl_rm_disp32(rhs.encoding(), (void*)-1); append(AsmJSAbsoluteLink(CodeOffsetLabel(masm.currentOffset()), lhs.kind())); diff --git a/js/src/jit/x86/MacroAssembler-x86.h b/js/src/jit/x86/MacroAssembler-x86.h index bf9c213af6..2c23d6d3c7 100644 --- a/js/src/jit/x86/MacroAssembler-x86.h +++ b/js/src/jit/x86/MacroAssembler-x86.h @@ -67,6 +67,14 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared MoveResolver moveResolver_; private: + Operand payloadOfAfterStackPush(const Address& address) { + // If we are basing off %esp, the address will be invalid after the + // first push. + if (address.base == StackPointer) + return Operand(address.base, address.offset + 4); + else + return payloadOf(address); + } Operand payloadOf(const Address& address) { return Operand(address.base, address.offset); } @@ -230,7 +238,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared jsval_layout jv = JSVAL_TO_IMPL(val); push(Imm32(jv.s.tag)); if (val.isMarkable()) - push(ImmMaybeNurseryPtr(reinterpret_cast(val.toGCThing()))); + push(ImmGCPtr(reinterpret_cast(val.toGCThing()))); else push(Imm32(jv.s.payload.i32)); } @@ -240,9 +248,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared } void pushValue(const Address& addr) { push(tagOf(addr)); - push(payloadOf(addr)); + push(payloadOfAfterStackPush(addr)); } - void storePayload(const Value &val, Operand dest) { + void storePayload(const Value& val, Operand dest) { jsval_layout jv = JSVAL_TO_IMPL(val); if (val.isMarkable()) movl(ImmGCPtr((gc::Cell*)jv.s.payload.ptr), ToPayload(dest)); @@ -561,9 +569,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared void cmpPtr(Register lhs, Register rhs) { cmp32(lhs, rhs); } - void cmpPtr(const Operand& lhs, ImmMaybeNurseryPtr rhs) { - cmpl(rhs, lhs); - } void testPtr(Register lhs, Register rhs) { test32(lhs, rhs); } @@ -727,9 +732,6 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared void movePtr(ImmGCPtr imm, Register dest) { movl(imm, dest); } - void movePtr(ImmMaybeNurseryPtr imm, Register dest) { - movePtr(noteMaybeNurseryPtr(imm), dest); - } void loadPtr(const Address& address, Register dest) { movl(Operand(address), dest); } diff --git a/js/src/js.msg b/js/src/js.msg index 499558d76f..1b7fef2dc4 100644 --- a/js/src/js.msg +++ b/js/src/js.msg @@ -100,6 +100,7 @@ MSG_DEF(JSMSG_CANT_SET_PROTO_CYCLE, 0, JSEXN_TYPEERR, "can't set prototype: i MSG_DEF(JSMSG_INVALID_ARG_TYPE, 3, JSEXN_TYPEERR, "Invalid type: {0} can't be a{1} {2}") MSG_DEF(JSMSG_TERMINATED, 1, JSEXN_ERR, "Script terminated by timeout at:\n{0}") MSG_DEF(JSMSG_PROTO_NOT_OBJORNULL, 1, JSEXN_TYPEERR, "{0}.prototype is not an object or null") +MSG_DEF(JSMSG_CANT_CALL_CLASS_CONSTRUCTOR, 0, JSEXN_TYPEERR, "class constructors must be invoked with |new|") // JSON MSG_DEF(JSMSG_JSON_BAD_PARSE, 3, JSEXN_SYNTAXERR, "JSON.parse: {0} at line {1} column {2} of the JSON data") diff --git a/js/src/jsapi-tests/testJitMoveEmitterCycles-mips.cpp b/js/src/jsapi-tests/testJitMoveEmitterCycles-mips.cpp index 3e429fc3d9..20bab6529e 100644 --- a/js/src/jsapi-tests/testJitMoveEmitterCycles-mips.cpp +++ b/js/src/jsapi-tests/testJitMoveEmitterCycles-mips.cpp @@ -5,7 +5,7 @@ * 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/. */ -#if defined(JS_MIPS_SIMULATOR) +#if defined(JS_SIMULATOR_MIPS) #include "jit/Linker.h" #include "jit/MacroAssembler.h" #include "jit/mips/Assembler-mips.h" diff --git a/js/src/jsapi-tests/testJitMoveEmitterCycles.cpp b/js/src/jsapi-tests/testJitMoveEmitterCycles.cpp index db949a2b12..a00fce3ff2 100644 --- a/js/src/jsapi-tests/testJitMoveEmitterCycles.cpp +++ b/js/src/jsapi-tests/testJitMoveEmitterCycles.cpp @@ -5,7 +5,7 @@ * 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/. */ -#if defined(JS_ARM_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) #include "jit/arm/Assembler-arm.h" #include "jit/arm/MoveEmitter-arm.h" #include "jit/arm/Simulator-arm.h" diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index dfd8d1b15d..a77a8d22b9 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -1145,7 +1145,7 @@ JSContext::mark(JSTracer* trc) void* ExclusiveContext::stackLimitAddressForJitCode(StackKind kind) { -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR return runtime_->addressOfSimulatorStackLimit(); #else return stackLimitAddress(kind); diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 9fae06ae4f..a9e921180c 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -302,6 +302,12 @@ js::IsAtomsCompartment(JSCompartment* comp) return comp->runtimeFromAnyThread()->isAtomsCompartment(comp); } +JS_FRIEND_API(bool) +js::IsAtomsZone(JS::Zone* zone) +{ + return zone->runtimeFromAnyThread()->isAtomsZone(zone); +} + JS_FRIEND_API(bool) js::IsInNonStrictPropertySet(JSContext* cx) { diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index b5d59c7537..ea2bbc15bb 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -451,6 +451,9 @@ IsSystemZone(JS::Zone* zone); extern JS_FRIEND_API(bool) IsAtomsCompartment(JSCompartment* comp); +extern JS_FRIEND_API(bool) +IsAtomsZone(JS::Zone* zone); + /* * Returns whether we're in a non-strict property set (in that we're in a * non-strict script and the bytecode we're on is a property set). The return diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 12979f0667..77fe9f3ee2 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1987,6 +1987,22 @@ js::SetClassAndProto(JSContext* cx, HandleObject obj, return true; } +/* static */ bool +JSObject::changeToSingleton(JSContext* cx, HandleObject obj) +{ + MOZ_ASSERT(!obj->isSingleton()); + + MarkObjectGroupUnknownProperties(cx, obj->group()); + + ObjectGroup* group = ObjectGroup::lazySingletonGroup(cx, obj->getClass(), + obj->getTaggedProto()); + if (!group) + return false; + + obj->group_ = group; + return true; +} + static bool MaybeResolveConstructor(ExclusiveContext* cxArg, Handle global, JSProtoKey key) { diff --git a/js/src/jsobj.h b/js/src/jsobj.h index fce1c823c2..afc428ba38 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -311,12 +311,14 @@ class JSObject : public js::gc::Cell // along with them, and are not each their own malloc blocks. size_t sizeOfIncludingThisInNursery() const; - /* - * Marks this object as having a singleton type, and leave the group lazy. - * Constructs a new, unique shape for the object. - */ + // Marks this object as having a singleton group, and leave the group lazy. + // Constructs a new, unique shape for the object. This should only be + // called for an object that was just created. static inline bool setSingleton(js::ExclusiveContext* cx, js::HandleObject obj); + // Change an existing object to have a singleton group. + static bool changeToSingleton(JSContext* cx, js::HandleObject obj); + inline js::ObjectGroup* getGroup(JSContext* cx); const js::HeapPtrObjectGroup& groupFromGC() const { diff --git a/js/src/jsprf.cpp b/js/src/jsprf.cpp index cc2db3246c..b5bdb7cc35 100644 --- a/js/src/jsprf.cpp +++ b/js/src/jsprf.cpp @@ -12,6 +12,7 @@ #include "jsprf.h" +#include "mozilla/Snprintf.h" #include "mozilla/Vector.h" #include @@ -286,8 +287,6 @@ static bool cvt_ll(SprintfState* ss, int64_t num, int width, int prec, int radix /* * Convert a double precision floating point number into its printable * form. - * - * XXX stop using sprintf to convert floating point */ static bool cvt_f(SprintfState* ss, double d, const char* fmt0, const char* fmt1) { @@ -303,7 +302,7 @@ static bool cvt_f(SprintfState* ss, double d, const char* fmt0, const char* fmt1 js_memcpy(fin, fmt0, (size_t)amount); fin[amount] = 0; - // Convert floating point using the native sprintf code + // Convert floating point using the native snprintf code #ifdef DEBUG { const char* p = fin; @@ -313,12 +312,7 @@ static bool cvt_f(SprintfState* ss, double d, const char* fmt0, const char* fmt1 } } #endif - sprintf(fout, fin, d); - - // This assert will catch overflow's of fout, when building with - // debugging on. At least this way we can track down the evil piece - // of calling code and fix it! - MOZ_ASSERT(strlen(fout) < sizeof(fout)); + snprintf_literal(fout, fin, d); return (*ss->stuff)(ss, fout, strlen(fout)); } diff --git a/js/src/jspubtd.h b/js/src/jspubtd.h index 4602196bc2..0e313dfc2f 100644 --- a/js/src/jspubtd.h +++ b/js/src/jspubtd.h @@ -163,9 +163,7 @@ struct Runtime , gcStoreBufferPtr_(nullptr) {} - bool needsIncrementalBarrier() const { - return heapState_ == JS::HeapState::Idle; - } + bool isHeapBusy() const { return heapState_ != JS::HeapState::Idle; } js::gc::StoreBuffer* gcStoreBufferPtr() { return gcStoreBufferPtr_; } diff --git a/js/src/jsweakmap.cpp b/js/src/jsweakmap.cpp index 965c87bc6b..860ed3f011 100644 --- a/js/src/jsweakmap.cpp +++ b/js/src/jsweakmap.cpp @@ -348,7 +348,7 @@ WeakMapPostWriteBarrier(JSRuntime* rt, ObjectValueMap* weakMap, JSObject* key) // Strip the barriers from the type before inserting into the store buffer. // This will automatically ensure that barriers do not fire during GC. if (key && IsInsideNursery(key)) - rt->gc.storeBuffer.putGeneric(UnbarrieredRef(weakMap, key)); + rt->gc.storeBuffer.putGeneric(gc::HashKeyRef(weakMap, key)); } static MOZ_ALWAYS_INLINE bool diff --git a/js/src/jsweakmap.h b/js/src/jsweakmap.h index cf00158a74..b7fa0c8f11 100644 --- a/js/src/jsweakmap.h +++ b/js/src/jsweakmap.h @@ -258,13 +258,8 @@ class WeakMap : public HashMap, publ } /* Rekey an entry when moved, ensuring we do not trigger barriers. */ - void entryMoved(Enum& eArg, const Key& k) { - typedef typename HashMap::type, - typename Unbarriered::type, - typename Unbarriered::type, - RuntimeAllocPolicy>::Enum UnbarrieredEnum; - UnbarrieredEnum& e = reinterpret_cast(eArg); - e.rekeyFront(reinterpret_cast::type&>(k)); + void entryMoved(Enum& e, const Key& k) { + e.rekeyFront(k); } protected: @@ -280,28 +275,6 @@ protected: } }; -/* - * At times, you will need to ignore barriers when accessing WeakMap entries. - * Localize the templatized casting craziness here. - */ -template -static inline gc::HashKeyRef, RuntimeAllocPolicy>, Key> -UnbarrieredRef(WeakMap, RelocatablePtr>* map, Key key) -{ - /* - * Some compilers complain about instantiating the WeakMap class for - * unbarriered type arguments, so we cast to a HashMap instead. Because of - * WeakMap's multiple inheritance, we need to do this in two stages, first - * to the HashMap base class and then to the unbarriered version. - */ - - typedef typename WeakMap, RelocatablePtr>::Base BaseMap; - auto baseMap = static_cast(map); - typedef HashMap, RuntimeAllocPolicy> UnbarrieredMap; - typedef gc::HashKeyRef UnbarrieredKeyRef; - return UnbarrieredKeyRef(reinterpret_cast(baseMap), key); -} - /* WeakMap methods exposed so they can be installed in the self-hosting global. */ extern JSObject* diff --git a/js/src/moz.build b/js/src/moz.build index e57cb0f5ec..8c369251cf 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -370,10 +370,38 @@ elif CONFIG['JS_CODEGEN_ARM']: 'jit/arm/MoveEmitter-arm.cpp', 'jit/arm/Trampoline-arm.cpp', ] - if CONFIG['JS_ARM_SIMULATOR']: + if CONFIG['JS_SIMULATOR_ARM']: UNIFIED_SOURCES += [ 'jit/arm/Simulator-arm.cpp' ] +elif CONFIG['JS_CODEGEN_ARM64']: + UNIFIED_SOURCES += [ + 'jit/arm64/Architecture-arm64.cpp', + 'jit/arm64/Assembler-arm64.cpp', + 'jit/arm64/Bailouts-arm64.cpp', + 'jit/arm64/BaselineIC-arm64.cpp', + 'jit/arm64/CodeGenerator-arm64.cpp', + 'jit/arm64/Lowering-arm64.cpp', + 'jit/arm64/MacroAssembler-arm64.cpp', + 'jit/arm64/MoveEmitter-arm64.cpp', + 'jit/arm64/Trampoline-arm64.cpp', + 'jit/arm64/vixl/Assembler-vixl.cpp', + 'jit/arm64/vixl/Cpu-vixl.cpp', + 'jit/arm64/vixl/Decoder-vixl.cpp', + 'jit/arm64/vixl/Disasm-vixl.cpp', + 'jit/arm64/vixl/Instructions-vixl.cpp', + 'jit/arm64/vixl/Instrument-vixl.cpp', + 'jit/arm64/vixl/MacroAssembler-vixl.cpp', + 'jit/arm64/vixl/MozAssembler-vixl.cpp', + 'jit/arm64/vixl/MozInstructions-vixl.cpp', + 'jit/arm64/vixl/Utils-vixl.cpp' + ] + if CONFIG['JS_SIMULATOR_ARM64']: + UNIFIED_SOURCES += [ + 'jit/arm64/vixl/Debugger-vixl.cpp', + 'jit/arm64/vixl/MozSimulator-vixl.cpp', + 'jit/arm64/vixl/Simulator-vixl.cpp' + ] elif CONFIG['JS_CODEGEN_MIPS']: UNIFIED_SOURCES += [ 'jit/mips/Architecture-mips.cpp', @@ -387,7 +415,7 @@ elif CONFIG['JS_CODEGEN_MIPS']: 'jit/mips/MoveEmitter-mips.cpp', 'jit/mips/Trampoline-mips.cpp', ] - if CONFIG['JS_MIPS_SIMULATOR']: + if CONFIG['JS_SIMULATOR_MIPS']: UNIFIED_SOURCES += [ 'jit/mips/Simulator-mips.cpp' ] diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 1e95703dd6..e703f06da8 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -3534,13 +3534,11 @@ EscapeForShell(AutoCStringVector& argv) static Vector sPropagatedFlags; -#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64) static bool PropagateFlagToNestedShells(const char* flag) { return sPropagatedFlags.append(flag); } -#endif static bool NestedShell(JSContext* cx, unsigned argc, jsval* vp) @@ -3905,7 +3903,7 @@ PrintProfilerEvents(JSContext* cx, unsigned argc, Value* vp) return true; } -#if defined(JS_ARM_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) typedef Vector StackChars; Vector stacks; @@ -3953,7 +3951,7 @@ SingleStepCallback(void* arg, jit::Simulator* sim, void* pc) static bool EnableSingleStepProfiling(JSContext* cx, unsigned argc, Value* vp) { -#if defined(JS_ARM_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) CallArgs args = CallArgsFromVp(argc, vp); jit::Simulator* sim = cx->runtime()->simulator(); @@ -3970,7 +3968,7 @@ EnableSingleStepProfiling(JSContext* cx, unsigned argc, Value* vp) static bool DisableSingleStepProfiling(JSContext* cx, unsigned argc, Value* vp) { -#if defined(JS_ARM_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) CallArgs args = CallArgsFromVp(argc, vp); jit::Simulator* sim = cx->runtime()->simulator(); @@ -5915,14 +5913,14 @@ SetRuntimeOptions(JSRuntime* rt, const OptionParser& op) jit::Assembler::AsmPoolMaxOffset = poolMaxOffset; #endif -#if defined(JS_ARM_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) if (op.getBoolOption("arm-sim-icache-checks")) jit::Simulator::ICacheCheckingEnabled = true; int32_t stopAt = op.getIntOption("arm-sim-stop-at"); if (stopAt >= 0) jit::Simulator::StopSimAt = stopAt; -#elif defined(JS_MIPS_SIMULATOR) +#elif defined(JS_SIMULATOR_MIPS) if (op.getBoolOption("mips-sim-icache-checks")) jit::Simulator::ICacheCheckingEnabled = true; @@ -6193,6 +6191,7 @@ main(int argc, char** argv, char** envp) || !op.addIntOption('\0', "baseline-warmup-threshold", "COUNT", "Wait for COUNT calls or iterations before baseline-compiling " "(default: 10)", -1) + || !op.addBoolOption('\0', "non-writable-jitcode", "Allocate JIT code as non-writable memory.") || !op.addBoolOption('\0', "no-fpu", "Pretend CPU does not support floating-point operations " "to test JIT codegen (no-op on platforms other than x86).") || !op.addBoolOption('\0', "no-sse3", "Pretend CPU does not support SSE3 instructions and above " @@ -6222,12 +6221,12 @@ main(int argc, char** argv, char** envp) || !op.addIntOption('\0', "asm-pool-max-offset", "OFFSET", "The maximum pc relative OFFSET permitted in pool reference instructions.", 1024) #endif -#if defined(JS_ARM_SIMULATOR) +#if defined(JS_SIMULATOR_ARM) || !op.addBoolOption('\0', "arm-sim-icache-checks", "Enable icache flush checks in the ARM " "simulator.") || !op.addIntOption('\0', "arm-sim-stop-at", "NUMBER", "Stop the ARM simulator after the given " "NUMBER of instructions.", -1) -#elif defined(JS_MIPS_SIMULATOR) +#elif defined(JS_SIMULATOR_MIPS) || !op.addBoolOption('\0', "mips-sim-icache-checks", "Enable icache flush checks in the MIPS " "simulator.") || !op.addIntOption('\0', "mips-sim-stop-at", "NUMBER", "Stop the MIPS simulator after the given " @@ -6268,6 +6267,11 @@ main(int argc, char** argv, char** envp) OOM_printAllocationCount = op.getBoolOption('O'); #endif + if (op.getBoolOption("non-writable-jitcode")) { + js::jit::ExecutableAllocator::nonWritableJitCode = true; + PropagateFlagToNestedShells("--non-writable-jitcode"); + } + #ifdef JS_CODEGEN_X86 if (op.getBoolOption("no-fpu")) js::jit::CPUInfo::SetFloatingPointDisabled(); diff --git a/js/src/tests/ecma_6/Class/classConstructorNoCall.js b/js/src/tests/ecma_6/Class/classConstructorNoCall.js new file mode 100644 index 0000000000..4d01cf53d5 --- /dev/null +++ b/js/src/tests/ecma_6/Class/classConstructorNoCall.js @@ -0,0 +1,28 @@ +// Class constructors don't have a [[Call]] +var test = ` + +class Foo { + constructor() { } +} + +assertThrowsInstanceOf(Foo, TypeError); + +class Bar extends Foo { + constructor() { } +} + +assertThrowsInstanceOf(Bar, TypeError); + +assertThrowsInstanceOf(class { constructor() { } }, TypeError); +assertThrowsInstanceOf(class extends Foo { constructor() { } }, TypeError); + +assertThrowsInstanceOf(class foo { constructor() { } }, TypeError); +assertThrowsInstanceOf(class foo extends Foo { constructor() { } }, TypeError); + +`; + +if (classesEnabled()) + eval(test); + +if (typeof reportCompare === 'function') + reportCompare(0,0,"OK"); diff --git a/js/src/tests/ecma_6/Class/methodInstallation.js b/js/src/tests/ecma_6/Class/methodInstallation.js index af1521c8bc..dad5803df4 100644 --- a/js/src/tests/ecma_6/Class/methodInstallation.js +++ b/js/src/tests/ecma_6/Class/methodInstallation.js @@ -44,7 +44,7 @@ for (let a of [testClass, assertEq(aConstDesc.writable, true); assertEq(aConstDesc.configurable, true); assertEq(aConstDesc.enumerable, false); - aConstDesc.value(); + new aConstDesc.value(); assertEq(constructorCalled, true); // __proto__ is just an identifier for classes. No prototype changes are made. diff --git a/js/src/tests/lib/tests.py b/js/src/tests/lib/tests.py index a302a3f2f6..956f2f4559 100644 --- a/js/src/tests/lib/tests.py +++ b/js/src/tests/lib/tests.py @@ -15,8 +15,8 @@ JITFLAGS = { 'all': [ [], # no flags, normal baseline and ion ['--ion-eager', '--ion-offthread-compile=off'], # implies --baseline-eager - ['--ion-eager', '--ion-offthread-compile=off', - '--ion-check-range-analysis', '--ion-extra-checks', '--no-sse3', '--no-threads'], + ['--ion-eager', '--ion-offthread-compile=off', '--non-writable-jitcode', + '--ion-check-range-analysis', '--ion-extra-checks', '--no-sse3', '--no-threads'], ['--baseline-eager'], ['--baseline-eager', '--no-fpu'], ['--no-baseline', '--no-ion'], diff --git a/js/src/vm/Debugger-inl.h b/js/src/vm/Debugger-inl.h index f61f6bebb9..c174fddbdf 100644 --- a/js/src/vm/Debugger-inl.h +++ b/js/src/vm/Debugger-inl.h @@ -27,7 +27,7 @@ js::Debugger::onLeaveFrame(JSContext* cx, AbstractFramePtr frame, bool ok) } /* static */ inline js::Debugger* -js::Debugger::fromJSObject(JSObject* obj) +js::Debugger::fromJSObject(const JSObject* obj) { MOZ_ASSERT(js::GetObjectClass(obj) == &jsclass); return (Debugger*) obj->as().getPrivate(); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index f75ee5a079..6c8f496e66 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -8001,16 +8001,27 @@ JS::dbg::onPromiseSettled(JSContext* cx, HandleObject promise) } JS_PUBLIC_API(bool) -JS::dbg::IsDebugger(JS::Value val) +JS::dbg::IsDebugger(const JSObject& obj) { - if (!val.isObject()) - return false; + return js::GetObjectClass(&obj) == &Debugger::jsclass && + js::Debugger::fromJSObject(&obj) != nullptr; +} - JSObject& obj = val.toObject(); - if (obj.getClass() != &Debugger::jsclass) - return false; +JS_PUBLIC_API(bool) +JS::dbg::GetDebuggeeGlobals(JSContext* cx, const JSObject& dbgObj, AutoObjectVector& vector) +{ + MOZ_ASSERT(IsDebugger(dbgObj)); + js::Debugger* dbg = js::Debugger::fromJSObject(&dbgObj); - return js::Debugger::fromJSObject(&obj) != nullptr; + if (!vector.reserve(vector.length() + dbg->debuggees.count())) { + JS_ReportOutOfMemory(cx); + return false; + } + + for (WeakGlobalObjectSet::Range r = dbg->allDebuggees(); !r.empty(); r.popFront()) + vector.infallibleAppend(static_cast(r.front())); + + return true; } diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index 45be04330a..f0fe0d454b 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -190,7 +190,8 @@ class Debugger : private mozilla::LinkedListElement friend class SavedStacks; friend class mozilla::LinkedListElement; friend bool (::JS_DefineDebuggerObject)(JSContext* cx, JS::HandleObject obj); - friend bool (::JS::dbg::IsDebugger)(JS::Value val); + friend bool (::JS::dbg::IsDebugger)(const JSObject&); + friend bool (::JS::dbg::GetDebuggeeGlobals)(JSContext*, const JSObject&, AutoObjectVector&); friend void JS::dbg::onNewPromise(JSContext* cx, HandleObject promise); friend void JS::dbg::onPromiseSettled(JSContext* cx, HandleObject promise); friend bool JS::dbg::FireOnGarbageCollectionHook(JSContext* cx, @@ -618,7 +619,7 @@ class Debugger : private mozilla::LinkedListElement bool init(JSContext* cx); inline const js::HeapPtrNativeObject& toJSObject() const; inline js::HeapPtrNativeObject& toJSObjectRef(); - static inline Debugger* fromJSObject(JSObject* obj); + static inline Debugger* fromJSObject(const JSObject* obj); static Debugger* fromChildJSObject(JSObject* obj); bool hasMemory() const; diff --git a/js/src/vm/DebuggerMemory.cpp b/js/src/vm/DebuggerMemory.cpp index 84d1bd4d41..cae560bdd1 100644 --- a/js/src/vm/DebuggerMemory.cpp +++ b/js/src/vm/DebuggerMemory.cpp @@ -325,11 +325,18 @@ DebuggerMemory::setOnGarbageCollection(JSContext *cx, unsigned argc, Value *vp) /* Debugger.Memory.prototype.takeCensus */ -void -JS::dbg::SetDebuggerMallocSizeOf(JSRuntime* rt, mozilla::MallocSizeOf mallocSizeOf) { +JS_PUBLIC_API(void) +JS::dbg::SetDebuggerMallocSizeOf(JSRuntime* rt, mozilla::MallocSizeOf mallocSizeOf) +{ rt->debuggerMallocSizeOf = mallocSizeOf; } +JS_PUBLIC_API(mozilla::MallocSizeOf) +JS::dbg::GetDebuggerMallocSizeOf(JSRuntime* rt) +{ + return rt->debuggerMallocSizeOf; +} + namespace js { namespace dbg { diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index b9ddcc95e9..ecd2dfe267 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -695,6 +695,11 @@ js::Invoke(JSContext* cx, const CallArgs& args, MaybeConstruct construct) /* Invoke native functions. */ JSFunction* fun = &args.callee().as(); + if (construct != CONSTRUCT && fun->isClassConstructor()) { + JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_CANT_CALL_CLASS_CONSTRUCTOR); + return false; + } + if (fun->isNative()) { MOZ_ASSERT_IF(construct, !fun->isConstructor()); return CallJSNative(cx, fun->native(), args); @@ -2993,7 +2998,9 @@ CASE(JSOP_FUNCALL) bool isFunction = IsFunctionObject(args.calleev(), &maybeFun); /* Don't bother trying to fast-path calls to scripted non-constructors. */ - if (!isFunction || !maybeFun->isInterpreted() || !maybeFun->isConstructor()) { + if (!isFunction || !maybeFun->isInterpreted() || !maybeFun->isConstructor() || + (!construct && maybeFun->isClassConstructor())) + { if (construct) { if (!InvokeConstructor(cx, args)) goto error; diff --git a/js/src/vm/ObjectGroup.cpp b/js/src/vm/ObjectGroup.cpp index 2684a32b18..84d51388d9 100644 --- a/js/src/vm/ObjectGroup.cpp +++ b/js/src/vm/ObjectGroup.cpp @@ -494,8 +494,20 @@ ObjectGroup::defaultNewGroup(ExclusiveContext* cx, const Class* clasp, clasp = &PlainObject::class_; } - if (proto.isObject() && !proto.toObject()->setDelegate(cx)) - return nullptr; + if (proto.isObject() && !proto.toObject()->isDelegate()) { + RootedObject protoObj(cx, proto.toObject()); + if (!protoObj->setDelegate(cx)) + return nullptr; + + // Objects which are prototypes of one another should be singletons, so + // that their type information can be tracked more precisely. Limit + // this group change to plain objects, to avoid issues with other types + // of singletons like typed arrays. + if (protoObj->is() && !protoObj->isSingleton()) { + if (!JSObject::changeToSingleton(cx->asJSContext(), protoObj)) + return nullptr; + } + } ObjectGroupCompartment::NewTable::AddPtr p = table->lookupForAdd(ObjectGroupCompartment::NewEntry::Lookup(clasp, proto, associated)); diff --git a/js/src/vm/ObjectGroup.h b/js/src/vm/ObjectGroup.h index 928d804a8f..dda4698505 100644 --- a/js/src/vm/ObjectGroup.h +++ b/js/src/vm/ObjectGroup.h @@ -157,10 +157,11 @@ enum NewObjectKind { * * Object groups which represent at most one JS object are constructed lazily. * These include groups for native functions, standard classes, scripted - * functions defined at the top level of global/eval scripts, and in some - * other cases. Typical web workloads often create many windows (and many - * copies of standard natives) and many scripts, with comparatively few - * non-singleton groups. + * functions defined at the top level of global/eval scripts, objects which + * dynamically become the prototype of some other object, and in some other + * cases. Typical web workloads often create many windows (and many copies of + * standard natives) and many scripts, with comparatively few non-singleton + * groups. * * We can recover the type information for the object from examining it, * so don't normally track the possible types of its properties as it is diff --git a/js/src/vm/Runtime.cpp b/js/src/vm/Runtime.cpp index a0d00a95e6..578eb43989 100644 --- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -81,6 +81,7 @@ PerThreadData::PerThreadData(JSRuntime* runtime) suppressGC(0), #ifdef DEBUG ionCompiling(false), + ionCompilingSafeForMinorGC(false), gcSweeping(false), #endif activeCompilations(0) @@ -159,7 +160,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime) #endif gc(thisFromCtor()), gcInitialized(false), -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR simulator_(nullptr), #endif scriptAndCountsVector(nullptr), @@ -211,6 +212,7 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime) ctypesActivityCallback(nullptr), offthreadIonCompilationEnabled_(true), parallelParsingEnabled_(true), + autoWritableJitCodeActive_(false), #ifdef DEBUG enteredPolicy(nullptr), #endif @@ -319,7 +321,7 @@ JSRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) dateTimeInfo.updateTimeZoneAdjustment(); -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR simulator_ = js::jit::Simulator::Create(); if (!simulator_) return false; @@ -440,7 +442,7 @@ JSRuntime::~JSRuntime() gc.storeBuffer.disable(); gc.nursery.disable(); -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR js::jit::Simulator::Destroy(simulator_); #endif @@ -583,7 +585,7 @@ JSRuntime::resetJitStackLimit() // Note that, for now, we use the untrusted limit for ion. This is fine, // because it's the most conservative limit, and if we hit it, we'll bail // out of ion into the interpeter, which will do a proper recursion check. -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR jitStackLimit_ = jit::Simulator::StackLimit(); #else jitStackLimit_ = mainThread.nativeStackLimit[StackForUntrustedScript]; diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h index 6c3a193e66..56b230a46b 100644 --- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -528,6 +528,11 @@ class PerThreadData : public PerThreadDataFriendFields // Whether this thread is actively Ion compiling. bool ionCompiling; + // Whether this thread is actively Ion compiling in a context where a minor + // GC could happen simultaneously. If this is true, this thread cannot use + // any pointers into the nursery. + bool ionCompilingSafeForMinorGC; + // Whether this thread is currently sweeping GC things. bool gcSweeping; #endif @@ -570,7 +575,7 @@ class PerThreadData : public PerThreadDataFriendFields js::jit::AutoFlushICache* autoFlushICache() const; void setAutoFlushICache(js::jit::AutoFlushICache* afc); -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR js::jit::Simulator* simulator() const; #endif }; @@ -1000,7 +1005,6 @@ struct JSRuntime : public JS::shadow::Runtime, /* Garbage collector state has been sucessfully initialized. */ bool gcInitialized; - bool isHeapBusy() const { return heapState_ != JS::HeapState::Idle; } bool isHeapMajorCollecting() const { return heapState_ == JS::HeapState::MajorCollecting; } bool isHeapMinorCollecting() const { return heapState_ == JS::HeapState::MinorCollecting; } bool isHeapCollecting() const { return isHeapMinorCollecting() || isHeapMajorCollecting(); } @@ -1016,12 +1020,12 @@ struct JSRuntime : public JS::shadow::Runtime, gc.unlockGC(); } -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR js::jit::Simulator* simulator_; #endif public: -#if defined(JS_ARM_SIMULATOR) || defined(JS_MIPS_SIMULATOR) +#ifdef JS_SIMULATOR js::jit::Simulator* simulator() const; uintptr_t* addressOfSimulatorStackLimit(); #endif @@ -1379,6 +1383,8 @@ struct JSRuntime : public JS::shadow::Runtime, bool offthreadIonCompilationEnabled_; bool parallelParsingEnabled_; + bool autoWritableJitCodeActive_; + public: // Note: these values may be toggled dynamically (in response to about:config @@ -1396,6 +1402,12 @@ struct JSRuntime : public JS::shadow::Runtime, return parallelParsingEnabled_; } + void toggleAutoWritableJitCodeActive(bool b) { + MOZ_ASSERT(autoWritableJitCodeActive_ != b, "AutoWritableJitCode should not be nested."); + MOZ_ASSERT(CurrentThreadCanAccessRuntime(this)); + autoWritableJitCodeActive_ = b; + } + const JS::RuntimeOptions& options() const { return options_; } @@ -1938,13 +1950,16 @@ extern const JSSecurityCallbacks NullSecurityCallbacks; class AutoEnterIonCompilation { public: - explicit AutoEnterIonCompilation(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) { + explicit AutoEnterIonCompilation(bool safeForMinorGC + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; #ifdef DEBUG PerThreadData* pt = js::TlsPerThreadData.get(); MOZ_ASSERT(!pt->ionCompiling); + MOZ_ASSERT(!pt->ionCompilingSafeForMinorGC); pt->ionCompiling = true; + pt->ionCompilingSafeForMinorGC = safeForMinorGC; #endif } @@ -1953,6 +1968,7 @@ class AutoEnterIonCompilation PerThreadData* pt = js::TlsPerThreadData.get(); MOZ_ASSERT(pt->ionCompiling); pt->ionCompiling = false; + pt->ionCompilingSafeForMinorGC = false; #endif } diff --git a/js/src/vm/TypeInference.cpp b/js/src/vm/TypeInference.cpp index 27f30c44a5..b8923d565e 100644 --- a/js/src/vm/TypeInference.cpp +++ b/js/src/vm/TypeInference.cpp @@ -248,16 +248,6 @@ js::ObjectGroupHasProperty(JSContext* cx, ObjectGroup* group, jsid id, const Val TypeSet::Type type = TypeSet::GetValueType(value); - // Type set guards might miss when an object's group changes and its - // properties become unknown. - if (value.isObject() && - !value.toObject().hasLazyGroup() && - ((value.toObject().group()->flags() & OBJECT_FLAG_UNKNOWN_PROPERTIES) || - value.toObject().group()->maybeOriginalUnboxedGroup())) - { - return true; - } - AutoEnterAnalysis enter(cx); /* @@ -269,6 +259,22 @@ js::ObjectGroupHasProperty(JSContext* cx, ObjectGroup* group, jsid id, const Val if (!types) return true; + // Type set guards might miss when an object's group changes and its + // properties become unknown. + if (value.isObject()) { + if (types->unknownObject()) + return true; + for (size_t i = 0; i < types->getObjectCount(); i++) { + if (TypeSet::ObjectKey* key = types->getObject(i)) { + if (key->unknownProperties()) + return true; + } + } + JSObject* obj = &value.toObject(); + if (!obj->hasLazyGroup() && obj->group()->maybeOriginalUnboxedGroup()) + return true; + } + if (!types->hasType(type)) { TypeFailure(cx, "Missing type in object %s %s: %s", TypeSet::ObjectGroupString(group), TypeIdString(id), @@ -605,6 +611,41 @@ TypeSet::addType(Type type, LifoAlloc* alloc) } } +// This class is used for post barriers on type set contents. The only times +// when type sets contain nursery references is when a nursery object has its +// group dynamically changed to a singleton. In such cases the type set will +// need to be traced at the next minor GC. +// +// There is no barrier used for TemporaryTypeSets. These type sets are only +// used during Ion compilation, and if some ConstraintTypeSet contains nursery +// pointers then any number of TemporaryTypeSets might as well. Thus, if there +// are any such ConstraintTypeSets in existence, all off thread Ion +// compilations are canceled by the next minor GC. +class TypeSetRef : public BufferableRef +{ + Zone* zone; + ConstraintTypeSet* types; + + public: + TypeSetRef(Zone* zone, ConstraintTypeSet* types) + : zone(zone), types(types) + {} + + void trace(JSTracer* trc) override { + types->trace(zone, trc); + } +}; + +void +ConstraintTypeSet::postWriteBarrier(ExclusiveContext* cx, Type type) +{ + if (type.isSingletonUnchecked() && IsInsideNursery(type.singletonNoBarrier())) { + JSRuntime* rt = cx->asJSContext()->runtime(); + rt->gc.storeBuffer.putGeneric(TypeSetRef(cx->zone(), this)); + rt->gc.storeBuffer.setShouldCancelIonCompilations(); + } +} + void ConstraintTypeSet::addType(ExclusiveContext* cxArg, Type type) { @@ -618,6 +659,8 @@ ConstraintTypeSet::addType(ExclusiveContext* cxArg, Type type) if (type.isObjectUnchecked() && unknownObject()) type = AnyObjectType(); + postWriteBarrier(cxArg, type); + InferSpew(ISpewOps, "addType: %sT%p%s %s", InferSpewColor(this), this, InferSpewColorReset(), TypeString(type)); @@ -2572,6 +2615,7 @@ UpdatePropertyType(ExclusiveContext* cx, HeapTypeSet* types, NativeObject* obj, { TypeSet::Type type = TypeSet::GetValueType(value); types->TypeSet::addType(type, &cx->typeLifoAlloc()); + types->postWriteBarrier(cx, type); } if (indexed || shape->hadOverwrite()) { @@ -2623,6 +2667,7 @@ ObjectGroup::updateNewPropertyTypes(ExclusiveContext* cx, JSObject* objArg, jsid if (!value.isMagic(JS_ELEMENTS_HOLE)) { TypeSet::Type type = TypeSet::GetValueType(value); types->TypeSet::addType(type, &cx->typeLifoAlloc()); + types->postWriteBarrier(cx, type); } } } else if (!JSID_IS_EMPTY(id)) { @@ -2852,6 +2897,9 @@ ObjectGroup::markUnknown(ExclusiveContext* cx) clearNewScript(cx); ObjectStateChange(cx, this, true); + if (ObjectGroup* unboxedGroup = maybeOriginalUnboxedGroup()) + unboxedGroup->markUnknown(cx); + /* * Existing constraints may have already been added to this object, which we need * to do the right thing for. We can't ensure that we will mark all unknown @@ -3361,7 +3409,7 @@ PreliminaryObjectArrayWithTemplate::writeBarrierPre(PreliminaryObjectArrayWithTe { Shape* shape = objects->shape(); - if (!shape || !shape->runtimeFromAnyThread()->needsIncrementalBarrier()) + if (!shape || shape->runtimeFromAnyThread()->isHeapBusy()) return; JS::Zone* zone = shape->zoneFromAnyThread(); @@ -3926,7 +3974,7 @@ TypeNewScript::trace(JSTracer* trc) /* static */ void TypeNewScript::writeBarrierPre(TypeNewScript* newScript) { - if (!newScript->function()->runtimeFromAnyThread()->needsIncrementalBarrier()) + if (newScript->function()->runtimeFromAnyThread()->isHeapBusy()) return; JS::Zone* zone = newScript->function()->zoneFromAnyThread(); @@ -3945,6 +3993,55 @@ TypeNewScript::sweep() // Tracing ///////////////////////////////////////////////////////////////////// +static inline void +TraceObjectKey(JSTracer* trc, TypeSet::ObjectKey** keyp) +{ + TypeSet::ObjectKey* key = *keyp; + if (key->isGroup()) { + ObjectGroup* group = key->groupNoBarrier(); + TraceManuallyBarrieredEdge(trc, &group, "objectKey_group"); + *keyp = TypeSet::ObjectKey::get(group); + } else { + JSObject* singleton = key->singletonNoBarrier(); + TraceManuallyBarrieredEdge(trc, &singleton, "objectKey_singleton"); + *keyp = TypeSet::ObjectKey::get(singleton); + } +} + +void +ConstraintTypeSet::trace(Zone* zone, JSTracer* trc) +{ + // ConstraintTypeSets only hold strong references during minor collections. + MOZ_ASSERT(zone->runtimeFromMainThread()->isHeapMinorCollecting()); + + unsigned objectCount = baseObjectCount(); + if (objectCount >= 2) { + unsigned oldCapacity = TypeHashSet::Capacity(objectCount); + ObjectKey** oldArray = objectSet; + + clearObjects(); + objectCount = 0; + for (unsigned i = 0; i < oldCapacity; i++) { + ObjectKey* key = oldArray[i]; + if (!key) + continue; + TraceObjectKey(trc, &key); + ObjectKey** pentry = + TypeHashSet::Insert + (zone->types.typeLifoAlloc, objectSet, objectCount, key); + if (pentry) + *pentry = key; + else + CrashAtUnhandlableOOM("ConstraintTypeSet::trace"); + } + setBaseObjectCount(objectCount); + } else if (objectCount == 1) { + ObjectKey* key = (ObjectKey*) objectSet; + TraceObjectKey(trc, &key); + objectSet = reinterpret_cast(key); + } +} + void ConstraintTypeSet::sweep(Zone* zone, AutoClearTypeInferenceStateOnOOM& oom) { diff --git a/js/src/vm/TypeInference.h b/js/src/vm/TypeInference.h index 7c5da134da..d4e59d28c5 100644 --- a/js/src/vm/TypeInference.h +++ b/js/src/vm/TypeInference.h @@ -616,10 +616,15 @@ class ConstraintTypeSet : public TypeSet */ void addType(ExclusiveContext* cx, Type type); + // Trigger a post barrier when writing to this set, if necessary. + // addType(cx, type) takes care of this automatically. + void postWriteBarrier(ExclusiveContext* cx, Type type); + /* Add a new constraint to this set. */ bool addConstraint(JSContext* cx, TypeConstraint* constraint, bool callExisting = true); inline void sweep(JS::Zone* zone, AutoClearTypeInferenceStateOnOOM& oom); + inline void trace(JS::Zone* zone, JSTracer* trc); }; class StackTypeSet : public ConstraintTypeSet diff --git a/js/src/vm/UbiNode.cpp b/js/src/vm/UbiNode.cpp index 1b54b24d87..fb30bd83ed 100644 --- a/js/src/vm/UbiNode.cpp +++ b/js/src/vm/UbiNode.cpp @@ -10,7 +10,6 @@ #include "mozilla/Attributes.h" #include "mozilla/Range.h" #include "mozilla/Scoped.h" -#include "mozilla/UniquePtr.h" #include "jscntxt.h" #include "jsobj.h" @@ -48,10 +47,14 @@ using JS::ubi::TracerConcreteWithCompartment; // All operations on null ubi::Nodes crash. const char16_t* Concrete::typeName() const { MOZ_CRASH("null ubi::Node"); } -EdgeRange* Concrete::edges(JSContext*, bool) const { MOZ_CRASH("null ubi::Node"); } JS::Zone* Concrete::zone() const { MOZ_CRASH("null ubi::Node"); } JSCompartment* Concrete::compartment() const { MOZ_CRASH("null ubi::Node"); } +UniquePtr +Concrete::edges(JSContext*, bool) const { + MOZ_CRASH("null ubi::Node"); +} + size_t Concrete::size(mozilla::MallocSizeOf mallocSizeof) const { @@ -191,16 +194,17 @@ TracerConcrete::zone() const } template -EdgeRange* +UniquePtr TracerConcrete::edges(JSContext* cx, bool wantNames) const { - js::ScopedJSDeletePtr r(js_new(cx)); - if (!r) + UniquePtr> range( + cx->new_(cx)); + if (!range) return nullptr; - if (!r->init(cx, ptr, ::js::gc::MapTypeToTraceKind::kind, wantNames)) + if (!range->init(cx, ptr, ::js::gc::MapTypeToTraceKind::kind, wantNames)) return nullptr; - return r.forget(); + return UniquePtr(range.release()); } template @@ -324,8 +328,8 @@ RootList::init(ZoneSet& debuggees) bool RootList::init(HandleObject debuggees) { - MOZ_ASSERT(debuggees && JS::dbg::IsDebugger(ObjectValue(*debuggees))); - js::Debugger* dbg = js::Debugger::fromJSObject(debuggees); + MOZ_ASSERT(debuggees && JS::dbg::IsDebugger(*debuggees)); + js::Debugger* dbg = js::Debugger::fromJSObject(debuggees.get()); ZoneSet debuggeeZones; if (!debuggeeZones.init()) @@ -357,7 +361,7 @@ RootList::addRoot(Node node, const char16_t* edgeName) MOZ_ASSERT(noGC.isSome()); MOZ_ASSERT_IF(wantNames, edgeName); - mozilla::UniquePtr name; + UniquePtr name; if (edgeName) { name = DuplicateString(cx, edgeName); if (!name) @@ -367,32 +371,12 @@ RootList::addRoot(Node node, const char16_t* edgeName) return edges.append(mozilla::Move(SimpleEdge(name.release(), node))); } -// An EdgeRange concrete class that holds a pre-existing vector of SimpleEdges. -class PreComputedEdgeRange : public EdgeRange { - SimpleEdgeVector& edges; - size_t i; - - void settle() { - front_ = i < edges.length() ? &edges[i] : nullptr; - } - - public: - explicit PreComputedEdgeRange(JSContext* cx, SimpleEdgeVector& edges) - : edges(edges), - i(0) - { - settle(); - } - - void popFront() override { i++; settle(); } -}; - const char16_t Concrete::concreteTypeName[] = MOZ_UTF16("RootList"); -EdgeRange* +UniquePtr Concrete::edges(JSContext* cx, bool wantNames) const { MOZ_ASSERT_IF(wantNames, get().wantNames); - return js_new(cx, get().edges); + return UniquePtr(cx->new_(cx, get().edges)); } } // namespace ubi diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp index 09120f012f..0a48352165 100644 --- a/js/src/vm/UnboxedObject.cpp +++ b/js/src/vm/UnboxedObject.cpp @@ -1897,6 +1897,9 @@ js::TryConvertToUnboxedLayout(ExclusiveContext* cx, Shape* templateShape, if (!obj) continue; + if (obj->isSingleton() || obj->group() != group) + return true; + objectCount++; if (isArray) { diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h index ecf6ed833d..2bfe458f54 100644 --- a/js/src/vm/Xdr.h +++ b/js/src/vm/Xdr.h @@ -29,11 +29,11 @@ namespace js { * * https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode */ -static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 284; +static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 285; static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND); -static_assert(JSErr_Limit == 393, +static_assert(JSErr_Limit == 394, "GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or " "removed MSG_DEFs from js.msg, you should increment " "XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's " diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index 772ceb9ce6..14758b0c5c 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -233,7 +233,7 @@ public: JS::Zone* zone = js::GetContextZone(cx); ZoneStringCache* cache = static_cast(JS_GetZoneUserData(zone)); if (cache && buf == cache->mBuffer) { - MOZ_ASSERT(JS::GetTenuredGCThingZone(cache->mString) == zone); + MOZ_ASSERT(JS::GetStringZone(cache->mString) == zone); JS::MarkStringAsLive(zone, cache->mString); rval.setString(cache->mString); *sharedBuffer = false; diff --git a/layout/base/AccessibleCaret.cpp b/layout/base/AccessibleCaret.cpp new file mode 100644 index 0000000000..e2704416c1 --- /dev/null +++ b/layout/base/AccessibleCaret.cpp @@ -0,0 +1,269 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "AccessibleCaret.h" + +#include "AccessibleCaretLogger.h" +#include "mozilla/Preferences.h" +#include "nsCanvasFrame.h" +#include "nsCaret.h" +#include "nsDOMTokenList.h" +#include "nsIFrame.h" + +namespace mozilla { +using namespace dom; + +#undef AC_LOG +#define AC_LOG(message, ...) \ + AC_LOG_BASE("AccessibleCaret (%p): " message, this, ##__VA_ARGS__); + +#undef AC_LOGV +#define AC_LOGV(message, ...) \ + AC_LOGV_BASE("AccessibleCaret (%p): " message, this, ##__VA_ARGS__); + +NS_IMPL_ISUPPORTS(AccessibleCaret::DummyTouchListener, nsIDOMEventListener) + +// ----------------------------------------------------------------------------- +// Implementation of AccessibleCaret methods + +AccessibleCaret::AccessibleCaret(nsIPresShell* aPresShell) + : mPresShell(aPresShell) +{ + // Check all resources required. + MOZ_ASSERT(mPresShell); + MOZ_ASSERT(RootFrame()); + MOZ_ASSERT(mPresShell->GetDocument()); + MOZ_ASSERT(mPresShell->GetCanvasFrame()); + MOZ_ASSERT(mPresShell->GetCanvasFrame()->GetCustomContentContainer()); + + InjectCaretElement(mPresShell->GetDocument()); +} + +AccessibleCaret::~AccessibleCaret() +{ + RemoveCaretElement(mPresShell->GetDocument()); +} + +void +AccessibleCaret::SetAppearance(Appearance aAppearance) +{ + if (mAppearance == aAppearance) { + return; + } + + ErrorResult rv; + CaretElement()->ClassList()->Remove(AppearanceString(mAppearance), rv); + MOZ_ASSERT(!rv.Failed(), "Remove old appearance failed!"); + + CaretElement()->ClassList()->Add(AppearanceString(aAppearance), rv); + MOZ_ASSERT(!rv.Failed(), "Add new appearance failed!"); + + mAppearance = aAppearance; + + // Need to reset rect since the cached rect will be compared in SetPosition. + if (mAppearance == Appearance::None) { + mImaginaryCaretRect = nsRect(); + } +} + +void +AccessibleCaret::SetSelectionBarEnabled(bool aEnabled) +{ + if (mSelectionBarEnabled == aEnabled) { + return; + } + + AC_LOG("%s, enabled %d", __FUNCTION__, aEnabled); + + ErrorResult rv; + CaretElement()->ClassList()->Toggle(NS_LITERAL_STRING("no-bar"), + Optional(!aEnabled), rv); + MOZ_ASSERT(!rv.Failed()); + + mSelectionBarEnabled = aEnabled; +} + +/* static */ nsString +AccessibleCaret::AppearanceString(Appearance aAppearance) +{ + nsAutoString string; + switch (aAppearance) { + case Appearance::None: + case Appearance::NormalNotShown: + string = NS_LITERAL_STRING("none"); + break; + case Appearance::Normal: + string = NS_LITERAL_STRING("normal"); + break; + case Appearance::Right: + string = NS_LITERAL_STRING("right"); + break; + case Appearance::Left: + string = NS_LITERAL_STRING("left"); + break; + } + return string; +} + +bool +AccessibleCaret::Intersects(const AccessibleCaret& aCaret) const +{ + MOZ_ASSERT(mPresShell == aCaret.mPresShell); + + if (!IsVisuallyVisible() || !aCaret.IsVisuallyVisible()) { + return false; + } + + nsRect rect = nsLayoutUtils::GetRectRelativeToFrame(CaretElement(), RootFrame()); + nsRect rhsRect = nsLayoutUtils::GetRectRelativeToFrame(aCaret.CaretElement(), RootFrame()); + return rect.Intersects(rhsRect); +} + +bool +AccessibleCaret::Contains(const nsPoint& aPoint) const +{ + if (!IsVisuallyVisible()) { + return false; + } + + nsRect rect = + nsLayoutUtils::GetRectRelativeToFrame(CaretImageElement(), RootFrame()); + + return rect.Contains(aPoint); +} + +void +AccessibleCaret::InjectCaretElement(nsIDocument* aDocument) +{ + ErrorResult rv; + nsCOMPtr element = CreateCaretElement(aDocument); + mCaretElementHolder = aDocument->InsertAnonymousContent(*element, rv); + + MOZ_ASSERT(!rv.Failed(), "Insert anonymous content should not fail!"); + MOZ_ASSERT(mCaretElementHolder.get(), "We must have anonymous content!"); + + // InsertAnonymousContent will clone the element to make an AnonymousContent. + // Since event listeners are not being cloned when cloning a node, we need to + // add the listener here. + CaretElement()->AddEventListener(NS_LITERAL_STRING("touchstart"), + mDummyTouchListener, false); +} + +already_AddRefed +AccessibleCaret::CreateCaretElement(nsIDocument* aDocument) const +{ + // Content structure of AccessibleCaret + //
<- CaretElement() + //
<- CaretImageElement() + //
<- SelectionBarElement() + + ErrorResult rv; + nsCOMPtr parent = aDocument->CreateHTMLElement(nsGkAtoms::div); + parent->ClassList()->Add(NS_LITERAL_STRING("moz-accessiblecaret"), rv); + parent->ClassList()->Add(NS_LITERAL_STRING("none"), rv); + parent->ClassList()->Add(NS_LITERAL_STRING("no-bar"), rv); + + nsCOMPtr image = aDocument->CreateHTMLElement(nsGkAtoms::div); + image->ClassList()->Add(NS_LITERAL_STRING("image"), rv); + parent->AppendChildTo(image, false); + + nsCOMPtr bar = aDocument->CreateHTMLElement(nsGkAtoms::div); + bar->ClassList()->Add(NS_LITERAL_STRING("bar"), rv); + parent->AppendChildTo(bar, false); + + return parent.forget(); +} + +void +AccessibleCaret::RemoveCaretElement(nsIDocument* aDocument) +{ + CaretElement()->RemoveEventListener(NS_LITERAL_STRING("touchstart"), + mDummyTouchListener, false); + + ErrorResult rv; + aDocument->RemoveAnonymousContent(*mCaretElementHolder, rv); + // It's OK rv is failed since nsCanvasFrame might not exists now. +} + +AccessibleCaret::PositionChangedResult +AccessibleCaret::SetPosition(nsIFrame* aFrame, int32_t aOffset) +{ + if (!CustomContentContainerFrame()) { + return PositionChangedResult::NotChanged; + } + + nsRect imaginaryCaretRectInFrame = + nsCaret::GetGeometryForFrame(aFrame, aOffset, nullptr); + + imaginaryCaretRectInFrame = + nsLayoutUtils::ClampRectToScrollFrames(aFrame, imaginaryCaretRectInFrame); + + if (imaginaryCaretRectInFrame.IsEmpty()) { + // Don't bother to set the caret position since it's invisible. + return PositionChangedResult::Invisible; + } + + nsRect imaginaryCaretRect = imaginaryCaretRectInFrame; + nsLayoutUtils::TransformRect(aFrame, RootFrame(), imaginaryCaretRect); + + if (imaginaryCaretRect.IsEqualEdges(mImaginaryCaretRect)) { + return PositionChangedResult::NotChanged; + } + + mImaginaryCaretRect = imaginaryCaretRect; + + // SetCaretElementPosition() and SetSelectionBarElementPosition() require the + // input rect relative to container frame. + nsRect imaginaryCaretRectInContainerFrame = imaginaryCaretRectInFrame; + nsLayoutUtils::TransformRect(aFrame, CustomContentContainerFrame(), + imaginaryCaretRectInContainerFrame); + SetCaretElementPosition(imaginaryCaretRectInContainerFrame); + SetSelectionBarElementPosition(imaginaryCaretRectInContainerFrame); + + return PositionChangedResult::Changed; +} + +nsIFrame* +AccessibleCaret::CustomContentContainerFrame() const +{ + nsCanvasFrame* canvasFrame = mPresShell->GetCanvasFrame(); + Element* container = canvasFrame->GetCustomContentContainer(); + nsIFrame* containerFrame = container->GetPrimaryFrame(); + return containerFrame; +} + +void +AccessibleCaret::SetCaretElementPosition(const nsRect& aRect) +{ + nsPoint position = CaretElementPosition(aRect); + nsAutoString styleStr; + styleStr.AppendPrintf("left: %dpx; top: %dpx;", + nsPresContext::AppUnitsToIntCSSPixels(position.x), + nsPresContext::AppUnitsToIntCSSPixels(position.y)); + + ErrorResult rv; + CaretElement()->SetAttribute(NS_LITERAL_STRING("style"), styleStr, rv); + MOZ_ASSERT(!rv.Failed()); + + AC_LOG("Set caret style: %s", NS_ConvertUTF16toUTF8(styleStr).get()); +} + +void +AccessibleCaret::SetSelectionBarElementPosition(const nsRect& aRect) +{ + int32_t height = nsPresContext::AppUnitsToIntCSSPixels(aRect.height); + nsAutoString barStyleStr; + barStyleStr.AppendPrintf("margin-top: -%dpx; height: %dpx;", + height, height); + + ErrorResult rv; + SelectionBarElement()->SetAttribute(NS_LITERAL_STRING("style"), barStyleStr, rv); + MOZ_ASSERT(!rv.Failed()); + + AC_LOG("Set bar style: %s", NS_ConvertUTF16toUTF8(barStyleStr).get()); +} + +} // namespace mozilla diff --git a/layout/base/AccessibleCaret.h b/layout/base/AccessibleCaret.h new file mode 100644 index 0000000000..5d6f95bebb --- /dev/null +++ b/layout/base/AccessibleCaret.h @@ -0,0 +1,209 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef AccessibleCaret_h__ +#define AccessibleCaret_h__ + +#include "mozilla/Attributes.h" +#include "mozilla/dom/AnonymousContent.h" +#include "mozilla/dom/Element.h" +#include "nsCOMPtr.h" +#include "nsIDOMEventListener.h" +#include "nsISupportsBase.h" +#include "nsISupportsImpl.h" +#include "nsRect.h" +#include "mozilla/nsRefPtr.h" +#include "nsString.h" + +class nsIDocument; +class nsIFrame; +class nsIPresShell; +struct nsPoint; + +namespace mozilla { + +// ----------------------------------------------------------------------------- +// Upon the creation of AccessibleCaret, it will insert DOM Element as an +// anonymous content containing the caret image. The caret appearance and +// position can be controlled by SetAppearance() and SetPosition(). +// +// All the rect or point are relative to root frame except being specified +// explicitly. +// +// None of the methods in AccessibleCaret will flush layout or style. To ensure +// that SetPosition() works correctly, the caller must make sure the layout is +// up to date. +// +class AccessibleCaret final +{ +public: + explicit AccessibleCaret(nsIPresShell* aPresShell); + ~AccessibleCaret(); + + // This enumeration representing the visibility and visual style of an + // AccessibleCaret. + // + // Use SetAppearance() to change the appearance, and use GetAppearance() to + // get the current appearance. + enum class Appearance : uint8_t { + // Do not display the caret at all. + None, + + // Display the caret in default style. + Normal, + + // The caret should be displayed logically but it is kept invisible to the + // user. This enum is the only difference between "logically visible" and + // "visually visible". It can be used for reasons such as: + // 1. Out of scroll port. + // 2. For UX requirement such as hide a caret in an empty text area. + NormalNotShown, + + // Display the caret which is tilted to the left. + Left, + + // Display the caret which is tilted to the right. + Right + }; + + Appearance GetAppearance() const + { + return mAppearance; + } + + void SetAppearance(Appearance aAppearance); + + // Return true if current appearance is either Normal, NormalNotShown, Left, + // or Right. + bool IsLogicallyVisible() const + { + return mAppearance != Appearance::None; + } + + // Return true if current appearance is either Normal, Left, or Right. + bool IsVisuallyVisible() const + { + return (mAppearance != Appearance::None) && + (mAppearance != Appearance::NormalNotShown); + } + + // Set true to enable the "Text Selection Bar" described in "Text Selection + // Visual Spec" in bug 921965. + void SetSelectionBarEnabled(bool aEnabled); + + // This enumeration representing the result returned by SetPosition(). + enum class PositionChangedResult : uint8_t { + // Position is not changed. + NotChanged, + + // Position is changed. + Changed, + + // Position is out of scroll port. + Invisible + }; + PositionChangedResult SetPosition(nsIFrame* aFrame, int32_t aOffset); + + // Does two AccessibleCarets overlap? + bool Intersects(const AccessibleCaret& aCaret) const; + + // Is the point within the caret's rect? The point should be relative to root + // frame. + bool Contains(const nsPoint& aPoint) const; + + // The geometry center of the imaginary caret (nsCaret) to which this + // AccessibleCaret is attached. It is needed when dragging the caret. + nsPoint LogicalPosition() const + { + return mImaginaryCaretRect.Center(); + } + + // Element for 'Intersects' test. Container of image and bar elements. + dom::Element* CaretElement() const + { + return mCaretElementHolder->GetContentNode(); + } + +private: + // Argument aRect should be relative to CustomContentContainerFrame(). + void SetCaretElementPosition(const nsRect& aRect); + void SetSelectionBarElementPosition(const nsRect& aRect); + + // Element which contains the caret image for 'Contains' test. + dom::Element* CaretImageElement() const + { + return CaretElement()->GetFirstElementChild(); + } + + // Element which represents the text selection bar. + dom::Element* SelectionBarElement() const + { + return CaretElement()->GetLastElementChild(); + } + + nsIFrame* RootFrame() const + { + return mPresShell->GetRootFrame(); + } + + nsIFrame* CustomContentContainerFrame() const; + + // Transform Appearance to CSS class name in ua.css. + static nsString AppearanceString(Appearance aAppearance); + + already_AddRefed CreateCaretElement(nsIDocument* aDocument) const; + + // Inject caret element into custom content container. + void InjectCaretElement(nsIDocument* aDocument); + + // Remove caret element from custom content container. + void RemoveCaretElement(nsIDocument* aDocument); + + // The bottom-center of the imaginary caret to which this AccessibleCaret is + // attached. + static nsPoint CaretElementPosition(const nsRect& aRect) + { + return aRect.TopLeft() + nsPoint(aRect.width / 2, aRect.height); + } + + class DummyTouchListener final : public nsIDOMEventListener + { + public: + NS_DECL_ISUPPORTS + NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override + { + return NS_OK; + } + + private: + virtual ~DummyTouchListener() {}; + }; + + // Member variables + Appearance mAppearance = Appearance::None; + + bool mSelectionBarEnabled = false; + + // AccessibleCaretManager owns us. When it's destroyed by + // AccessibleCaretEventHub::Terminate() which is called in + // PresShell::Destroy(), it frees us automatically. No need to worry we + // outlive mPresShell. + nsIPresShell* MOZ_NON_OWNING_REF const mPresShell = nullptr; + + nsRefPtr mCaretElementHolder; + + // mImaginaryCaretRect is relative to root frame. + nsRect mImaginaryCaretRect; + + // A no-op touch-start listener which prevents APZ from panning when dragging + // the caret. + nsRefPtr mDummyTouchListener{new DummyTouchListener()}; + +}; // class AccessibleCaret + +} // namespace mozilla + +#endif // AccessibleCaret_h__ diff --git a/layout/base/AccessibleCaretEventHub.cpp b/layout/base/AccessibleCaretEventHub.cpp new file mode 100644 index 0000000000..24158851b9 --- /dev/null +++ b/layout/base/AccessibleCaretEventHub.cpp @@ -0,0 +1,814 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "AccessibleCaretEventHub.h" + +#include "AccessibleCaretLogger.h" +#include "AccessibleCaretManager.h" +#include "gfxPrefs.h" +#include "mozilla/MouseEvents.h" +#include "mozilla/TextEvents.h" +#include "mozilla/TouchEvents.h" +#include "nsDocShell.h" +#include "nsFocusManager.h" +#include "nsFrameSelection.h" +#include "nsITimer.h" +#include "nsPresContext.h" + +namespace mozilla { + +#ifdef PR_LOGGING + +#undef AC_LOG +#define AC_LOG(message, ...) \ + AC_LOG_BASE("AccessibleCaretEventHub (%p): " message, this, ##__VA_ARGS__); + +#undef AC_LOGV +#define AC_LOGV(message, ...) \ + AC_LOGV_BASE("AccessibleCaretEventHub (%p): " message, this, ##__VA_ARGS__); + +#endif // #ifdef PR_LOGGING + +NS_IMPL_ISUPPORTS(AccessibleCaretEventHub, nsIReflowObserver, nsIScrollObserver, + nsISelectionListener, nsISupportsWeakReference); + +// ----------------------------------------------------------------------------- +// NoActionState +// +class AccessibleCaretEventHub::NoActionState + : public AccessibleCaretEventHub::State +{ +public: + NS_IMPL_STATE_UTILITIES(NoActionState) + + virtual nsEventStatus OnPress(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint, + int32_t aTouchId) override + { + nsEventStatus rv = nsEventStatus_eIgnore; + + if (NS_SUCCEEDED(aContext->mManager->PressCaret(aPoint))) { + aContext->SetState(aContext->PressCaretState()); + rv = nsEventStatus_eConsumeNoDefault; + } else { + aContext->SetState(aContext->PressNoCaretState()); + } + + aContext->mPressPoint = aPoint; + aContext->mActiveTouchId = aTouchId; + + return rv; + } + + virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->OnScrollStart(); + aContext->SetState(aContext->ScrollState()); + } + + virtual void OnScrolling(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->OnScrolling(); + } + + virtual void OnScrollPositionChanged(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->OnScrollPositionChanged(); + } + + virtual void OnSelectionChanged(AccessibleCaretEventHub* aContext, + nsIDOMDocument* aDoc, nsISelection* aSel, + int16_t aReason) override + { + aContext->mManager->OnSelectionChanged(aDoc, aSel, aReason); + } + + virtual void OnBlur(AccessibleCaretEventHub* aContext, + bool aIsLeavingDocument) override + { + aContext->mManager->OnBlur(); + } + + virtual void OnReflow(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->OnReflow(); + } + + virtual void Enter(AccessibleCaretEventHub* aContext) override + { + aContext->mPressPoint = nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + aContext->mActiveTouchId = kInvalidTouchId; + } +}; + +// ----------------------------------------------------------------------------- +// PressCaretState: Always consume the event since we've pressed on the caret. +// +class AccessibleCaretEventHub::PressCaretState + : public AccessibleCaretEventHub::State +{ +public: + NS_IMPL_STATE_UTILITIES(PressCaretState) + + virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint) override + { + if (aContext->MoveDistanceIsLarge(aPoint)) { + if (NS_SUCCEEDED(aContext->mManager->DragCaret(aPoint))) { + aContext->SetState(aContext->DragCaretState()); + } + } + + return nsEventStatus_eConsumeNoDefault; + } + + virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->ReleaseCaret(); + aContext->mManager->TapCaret(aContext->mPressPoint); + aContext->SetState(aContext->NoActionState()); + + return nsEventStatus_eConsumeNoDefault; + } + + virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint) override + { + return nsEventStatus_eConsumeNoDefault; + } +}; + +// ----------------------------------------------------------------------------- +// DragCaretState: Always consume the event since we've pressed on the caret. +// +class AccessibleCaretEventHub::DragCaretState + : public AccessibleCaretEventHub::State +{ +public: + NS_IMPL_STATE_UTILITIES(DragCaretState) + + virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint) override + { + aContext->mManager->DragCaret(aPoint); + + return nsEventStatus_eConsumeNoDefault; + } + + virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->ReleaseCaret(); + aContext->SetState(aContext->NoActionState()); + + return nsEventStatus_eConsumeNoDefault; + } +}; + +// ----------------------------------------------------------------------------- +// PressNoCaretState +// +class AccessibleCaretEventHub::PressNoCaretState + : public AccessibleCaretEventHub::State +{ +public: + NS_IMPL_STATE_UTILITIES(PressNoCaretState) + + virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint) override + { + if (aContext->MoveDistanceIsLarge(aPoint)) { + aContext->SetState(aContext->NoActionState()); + } + + return nsEventStatus_eIgnore; + } + + virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) override + { + aContext->SetState(aContext->NoActionState()); + + return nsEventStatus_eIgnore; + } + + virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint) override + { + aContext->SetState(aContext->LongTapState()); + + return aContext->GetState()->OnLongTap(aContext, aPoint); + } + + virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->OnScrollStart(); + aContext->SetState(aContext->ScrollState()); + } + + virtual void OnBlur(AccessibleCaretEventHub* aContext, + bool aIsLeavingDocument) override + { + aContext->mManager->OnBlur(); + if (aIsLeavingDocument) { + aContext->SetState(aContext->NoActionState()); + } + } + + virtual void OnSelectionChanged(AccessibleCaretEventHub* aContext, + nsIDOMDocument* aDoc, nsISelection* aSel, + int16_t aReason) override + { + aContext->mManager->OnSelectionChanged(aDoc, aSel, aReason); + } + + virtual void OnReflow(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->OnReflow(); + } + + virtual void Enter(AccessibleCaretEventHub* aContext) override + { + aContext->LaunchLongTapInjector(); + } + + virtual void Leave(AccessibleCaretEventHub* aContext) override + { + aContext->CancelLongTapInjector(); + } +}; + +// ----------------------------------------------------------------------------- +// ScrollState +// +class AccessibleCaretEventHub::ScrollState + : public AccessibleCaretEventHub::State +{ +public: + NS_IMPL_STATE_UTILITIES(ScrollState) + + virtual void OnScrollEnd(AccessibleCaretEventHub* aContext) override + { + aContext->SetState(aContext->PostScrollState()); + } + + virtual void OnBlur(AccessibleCaretEventHub* aContext, + bool aIsLeavingDocument) override + { + aContext->mManager->OnBlur(); + if (aIsLeavingDocument) { + aContext->SetState(aContext->NoActionState()); + } + } +}; + +// ----------------------------------------------------------------------------- +// PostScrollState: In this state, we are waiting for another APZ start, press +// event, or momentum wheel scroll. +// +class AccessibleCaretEventHub::PostScrollState + : public AccessibleCaretEventHub::State +{ +public: + NS_IMPL_STATE_UTILITIES(PostScrollState) + + virtual nsEventStatus OnPress(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint, + int32_t aTouchId) override + { + aContext->mManager->OnScrollEnd(); + aContext->SetState(aContext->NoActionState()); + + return aContext->GetState()->OnPress(aContext, aPoint, aTouchId); + } + + virtual void OnScrollStart(AccessibleCaretEventHub* aContext) override + { + aContext->SetState(aContext->ScrollState()); + } + + virtual void OnScrollEnd(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->OnScrollEnd(); + aContext->SetState(aContext->NoActionState()); + } + + virtual void OnScrolling(AccessibleCaretEventHub* aContext) override + { + // Momentum scroll by wheel event. + aContext->LaunchScrollEndInjector(); + } + + virtual void OnBlur(AccessibleCaretEventHub* aContext, + bool aIsLeavingDocument) override + { + aContext->mManager->OnBlur(); + if (aIsLeavingDocument) { + aContext->SetState(aContext->NoActionState()); + } + } + + virtual void Enter(AccessibleCaretEventHub* aContext) override + { + // Launch the injector to leave PostScrollState. + aContext->LaunchScrollEndInjector(); + } + + virtual void Leave(AccessibleCaretEventHub* aContext) override + { + aContext->CancelScrollEndInjector(); + } +}; + +// ----------------------------------------------------------------------------- +// LongTapState +// +class AccessibleCaretEventHub::LongTapState + : public AccessibleCaretEventHub::State +{ +public: + NS_IMPL_STATE_UTILITIES(LongTapState) + + virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint) override + { + nsEventStatus rv = nsEventStatus_eIgnore; + + if (NS_SUCCEEDED(aContext->mManager->SelectWordOrShortcut(aPoint))) { + rv = nsEventStatus_eConsumeNoDefault; + } + + aContext->SetState(aContext->NoActionState()); + + return rv; + } + + virtual void OnReflow(AccessibleCaretEventHub* aContext) override + { + aContext->mManager->OnReflow(); + } +}; + +// ----------------------------------------------------------------------------- +// Implementation of AccessibleCaretEventHub methods +// +AccessibleCaretEventHub::State* +AccessibleCaretEventHub::GetState() const +{ + return mState; +} + +void +AccessibleCaretEventHub::SetState(State* aState) +{ + MOZ_ASSERT(aState); + + AC_LOG("%s -> %s", mState->Name(), aState->Name()); + + mState->Leave(this); + mState = aState; + mState->Enter(this); +} + +NS_IMPL_STATE_CLASS_GETTER(NoActionState) +NS_IMPL_STATE_CLASS_GETTER(PressCaretState) +NS_IMPL_STATE_CLASS_GETTER(DragCaretState) +NS_IMPL_STATE_CLASS_GETTER(PressNoCaretState) +NS_IMPL_STATE_CLASS_GETTER(ScrollState) +NS_IMPL_STATE_CLASS_GETTER(PostScrollState) +NS_IMPL_STATE_CLASS_GETTER(LongTapState) + +AccessibleCaretEventHub::AccessibleCaretEventHub() +{ +} + +AccessibleCaretEventHub::~AccessibleCaretEventHub() +{ +} + +void +AccessibleCaretEventHub::Init(nsIPresShell* aPresShell) +{ + if (mInitialized || !aPresShell || !aPresShell->GetCanvasFrame() || + !aPresShell->GetCanvasFrame()->GetCustomContentContainer()) { + return; + } + + // Without nsAutoScriptBlocker, the script might be run after constructing + // mFirstCaret in AccessibleCaretManager's constructor, which might destructs + // the whole frame tree. Therefore we'll fail to construct mSecondCaret + // because we cannot get root frame or canvas frame from mPresShell to inject + // anonymous content. To avoid that, we protect Init() by nsAutoScriptBlocker. + // To reproduce, run "./mach crashtest layout/base/crashtests/897852.html" + // without the following scriptBlocker. + nsAutoScriptBlocker scriptBlocker; + + mPresShell = aPresShell; + + nsPresContext* presContext = mPresShell->GetPresContext(); + MOZ_ASSERT(presContext, "PresContext should be given in PresShell::Init()"); + + nsIDocShell* docShell = presContext->GetDocShell(); + if (!docShell) { + return; + } + +#if defined(MOZ_WIDGET_GONK) + mUseAsyncPanZoom = gfxPrefs::AsyncPanZoomEnabled(); +#endif + + docShell->AddWeakReflowObserver(this); + docShell->AddWeakScrollObserver(this); + + mDocShell = static_cast(docShell); + + mLongTapInjectorTimer = do_CreateInstance("@mozilla.org/timer;1"); + mScrollEndInjectorTimer = do_CreateInstance("@mozilla.org/timer;1"); + + mManager = MakeUnique(mPresShell); + + mInitialized = true; +} + +void +AccessibleCaretEventHub::Terminate() +{ + if (!mInitialized) { + return; + } + + nsRefPtr docShell(mDocShell.get()); + if (docShell) { + docShell->RemoveWeakReflowObserver(this); + docShell->RemoveWeakScrollObserver(this); + } + + if (mLongTapInjectorTimer) { + mLongTapInjectorTimer->Cancel(); + } + + if (mScrollEndInjectorTimer) { + mScrollEndInjectorTimer->Cancel(); + } + + mManager = nullptr; + mPresShell = nullptr; + mInitialized = false; +} + +nsEventStatus +AccessibleCaretEventHub::HandleEvent(WidgetEvent* aEvent) +{ + nsEventStatus status = nsEventStatus_eIgnore; + + if (!mInitialized) { + return status; + } + + switch (aEvent->mClass) { + case eMouseEventClass: + status = HandleMouseEvent(aEvent->AsMouseEvent()); + break; + + case eWheelEventClass: + status = HandleWheelEvent(aEvent->AsWheelEvent()); + break; + + case eTouchEventClass: + status = HandleTouchEvent(aEvent->AsTouchEvent()); + break; + + case eKeyboardEventClass: + status = HandleKeyboardEvent(aEvent->AsKeyboardEvent()); + break; + + default: + break; + } + + return status; +} + +nsEventStatus +AccessibleCaretEventHub::HandleMouseEvent(WidgetMouseEvent* aEvent) +{ + nsEventStatus rv = nsEventStatus_eIgnore; + + if (aEvent->button != WidgetMouseEvent::eLeftButton) { + return rv; + } + + int32_t id = (mActiveTouchId == kInvalidTouchId ? + kDefaultTouchId : mActiveTouchId); + nsPoint point = GetMouseEventPosition(aEvent); + + switch (aEvent->message) { + case NS_MOUSE_BUTTON_DOWN: + AC_LOGV("Before NS_MOUSE_BUTTON_DOWN, state: %s", mState->Name()); + rv = mState->OnPress(this, point, id); + AC_LOGV("After NS_MOUSE_BUTTON_DOWN, state: %s, consume: %d", + mState->Name(), rv); + break; + + case NS_MOUSE_MOVE: + AC_LOGV("Before NS_MOUSE_MOVE, state: %s", mState->Name()); + rv = mState->OnMove(this, point); + AC_LOGV("After NS_MOUSE_MOVE, state: %s, consume: %d", mState->Name(), rv); + break; + + case NS_MOUSE_BUTTON_UP: + AC_LOGV("Before NS_MOUSE_BUTTON_UP, state: %s", mState->Name()); + rv = mState->OnRelease(this); + AC_LOGV("After NS_MOUSE_BUTTON_UP, state: %s, consume: %d", mState->Name(), + rv); + break; + + case NS_MOUSE_MOZLONGTAP: + AC_LOGV("Before NS_MOUSE_MOZLONGTAP, state: %s", mState->Name()); + rv = mState->OnLongTap(this, point); + AC_LOGV("After NS_MOUSE_MOZLONGTAP, state: %s, consume: %d", mState->Name(), + rv); + break; + + default: + break; + } + + return rv; +} + +nsEventStatus +AccessibleCaretEventHub::HandleWheelEvent(WidgetWheelEvent* aEvent) +{ + switch (aEvent->message) { + case NS_WHEEL_WHEEL: + AC_LOGV("NS_WHEEL_WHEEL, isMomentum %d, state: %s", aEvent->isMomentum, + mState->Name()); + mState->OnScrolling(this); + break; + + case NS_WHEEL_START: + AC_LOGV("NS_WHEEL_START, state: %s", mState->Name()); + mState->OnScrollStart(this); + break; + + case NS_WHEEL_STOP: + AC_LOGV("NS_WHEEL_STOP, state: %s", mState->Name()); + mState->OnScrollEnd(this); + break; + + default: + break; + } + + // Always ignore this event since we only want to know scroll start and scroll + // end, not to consume it. + return nsEventStatus_eIgnore; +} + +nsEventStatus +AccessibleCaretEventHub::HandleTouchEvent(WidgetTouchEvent* aEvent) +{ + nsEventStatus rv = nsEventStatus_eIgnore; + + int32_t id = (mActiveTouchId == kInvalidTouchId ? + aEvent->touches[0]->Identifier() : mActiveTouchId); + nsPoint point = GetTouchEventPosition(aEvent, id); + + switch (aEvent->message) { + case NS_TOUCH_START: + AC_LOGV("Before NS_TOUCH_START, state: %s", mState->Name()); + rv = mState->OnPress(this, point, id); + AC_LOGV("After NS_TOUCH_START, state: %s, consume: %d", mState->Name(), rv); + break; + + case NS_TOUCH_MOVE: + AC_LOGV("Before NS_TOUCH_MOVE, state: %s", mState->Name()); + rv = mState->OnMove(this, point); + AC_LOGV("After NS_TOUCH_MOVE, state: %s, consume: %d", mState->Name(), rv); + break; + + case NS_TOUCH_END: + AC_LOGV("Before NS_TOUCH_END, state: %s", mState->Name()); + rv = mState->OnRelease(this); + AC_LOGV("After NS_TOUCH_END, state: %s, consume: %d", mState->Name(), rv); + break; + + case NS_TOUCH_CANCEL: + AC_LOGV("Before NS_TOUCH_CANCEL, state: %s", mState->Name()); + rv = mState->OnRelease(this); + AC_LOGV("After NS_TOUCH_CANCEL, state: %s, consume: %d", mState->Name(), + rv); + break; + + default: + break; + } + + return rv; +} + +nsEventStatus +AccessibleCaretEventHub::HandleKeyboardEvent(WidgetKeyboardEvent* aEvent) +{ + switch (aEvent->message) { + case NS_KEY_UP: + case NS_KEY_DOWN: + case NS_KEY_PRESS: + mManager->OnKeyboardEvent(); + break; + + default: + break; + } + + return nsEventStatus_eIgnore; +} + +bool +AccessibleCaretEventHub::MoveDistanceIsLarge(const nsPoint& aPoint) const +{ + nsPoint delta = aPoint - mPressPoint; + return NS_hypot(delta.x, delta.y) > + nsPresContext::AppUnitsPerCSSPixel() * kMoveStartToleranceInPixel; +} + +void +AccessibleCaretEventHub::LaunchLongTapInjector() +{ + if (mUseAsyncPanZoom) { + return; + } + + if (!mLongTapInjectorTimer) { + return; + } + + int32_t longTapDelay = gfxPrefs::UiClickHoldContextMenusDelay(); + mLongTapInjectorTimer->InitWithFuncCallback(FireLongTap, this, longTapDelay, + nsITimer::TYPE_ONE_SHOT); +} + +void +AccessibleCaretEventHub::CancelLongTapInjector() +{ + if (mUseAsyncPanZoom) { + return; + } + + if (!mLongTapInjectorTimer) { + return; + } + + mLongTapInjectorTimer->Cancel(); +} + +/* static */ void +AccessibleCaretEventHub::FireLongTap(nsITimer* aTimer, + void* aAccessibleCaretEventHub) +{ + auto self = static_cast(aAccessibleCaretEventHub); + self->mState->OnLongTap(self, self->mPressPoint); +} + +NS_IMETHODIMP +AccessibleCaretEventHub::Reflow(DOMHighResTimeStamp aStart, + DOMHighResTimeStamp aEnd) +{ + if (!mInitialized) { + return NS_OK; + } + + AC_LOG("%s, state: %s", __FUNCTION__, mState->Name()); + mState->OnReflow(this); + return NS_OK; +} + +NS_IMETHODIMP +AccessibleCaretEventHub::ReflowInterruptible(DOMHighResTimeStamp aStart, + DOMHighResTimeStamp aEnd) +{ + if (!mInitialized) { + return NS_OK; + } + + return Reflow(aStart, aEnd); +} + +void +AccessibleCaretEventHub::AsyncPanZoomStarted() +{ + if (!mInitialized) { + return; + } + + AC_LOG("%s, state: %s", __FUNCTION__, mState->Name()); + mState->OnScrollStart(this); +} + +void +AccessibleCaretEventHub::AsyncPanZoomStopped() +{ + if (!mInitialized) { + return; + } + + AC_LOG("%s, state: %s", __FUNCTION__, mState->Name()); + mState->OnScrollEnd(this); +} + +void +AccessibleCaretEventHub::ScrollPositionChanged() +{ + if (!mInitialized) { + return; + } + + AC_LOG("%s, state: %s", __FUNCTION__, mState->Name()); + mState->OnScrollPositionChanged(this); +} + +void +AccessibleCaretEventHub::LaunchScrollEndInjector() +{ + if (!mScrollEndInjectorTimer) { + return; + } + + mScrollEndInjectorTimer->InitWithFuncCallback( + FireScrollEnd, this, kScrollEndTimerDelay, nsITimer::TYPE_ONE_SHOT); +} + +void +AccessibleCaretEventHub::CancelScrollEndInjector() +{ + if (!mScrollEndInjectorTimer) { + return; + } + + mScrollEndInjectorTimer->Cancel(); +} + +/* static */ void +AccessibleCaretEventHub::FireScrollEnd(nsITimer* aTimer, + void* aAccessibleCaretEventHub) +{ + auto self = static_cast(aAccessibleCaretEventHub); + self->mState->OnScrollEnd(self); +} + +nsresult +AccessibleCaretEventHub::NotifySelectionChanged(nsIDOMDocument* aDoc, + nsISelection* aSel, + int16_t aReason) +{ + if (!mInitialized) { + return NS_OK; + } + + AC_LOG("%s, state: %s, reason: %d", __FUNCTION__, mState->Name(), aReason); + mState->OnSelectionChanged(this, aDoc, aSel, aReason); + return NS_OK; +} + +void +AccessibleCaretEventHub::NotifyBlur(bool aIsLeavingDocument) +{ + if (!mInitialized) { + return; + } + + AC_LOG("%s, state: %s", __FUNCTION__, mState->Name()); + mState->OnBlur(this, aIsLeavingDocument); +} + +nsPoint +AccessibleCaretEventHub::GetTouchEventPosition(WidgetTouchEvent* aEvent, + int32_t aIdentifier) const +{ + for (dom::Touch* touch : aEvent->touches) { + if (touch->Identifier() == aIdentifier) { + LayoutDeviceIntPoint touchIntPoint = touch->mRefPoint; + + // Get event coordinate relative to root frame. + nsIFrame* rootFrame = mPresShell->GetRootFrame(); + return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, touchIntPoint, + rootFrame); + } + } + return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); +} + +nsPoint +AccessibleCaretEventHub::GetMouseEventPosition(WidgetMouseEvent* aEvent) const +{ + LayoutDeviceIntPoint mouseIntPoint = aEvent->AsGUIEvent()->refPoint; + + // Get event coordinate relative to root frame. + nsIFrame* rootFrame = mPresShell->GetRootFrame(); + return nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, mouseIntPoint, + rootFrame); +} + +} // namespace mozilla diff --git a/layout/base/AccessibleCaretEventHub.h b/layout/base/AccessibleCaretEventHub.h new file mode 100644 index 0000000000..51661ab7b0 --- /dev/null +++ b/layout/base/AccessibleCaretEventHub.h @@ -0,0 +1,227 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef AccessibleCaretEventHub_h +#define AccessibleCaretEventHub_h + +#include "mozilla/EventForwards.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/WeakPtr.h" +#include "nsCOMPtr.h" +#include "nsIFrame.h" +#include "nsIReflowObserver.h" +#include "nsIScrollObserver.h" +#include "nsISelectionListener.h" +#include "nsPoint.h" +#include "mozilla/nsRefPtr.h" +#include "nsWeakReference.h" + +class nsDocShell; +class nsIPresShell; +class nsITimer; + +namespace mozilla { +class AccessibleCaretManager; +class WidgetKeyboardEvent; +class WidgetMouseEvent; +class WidgetTouchEvent; +class WidgetWheelEvent; + +// ----------------------------------------------------------------------------- +// Each PresShell holds a shared pointer to an AccessibleCaretEventHub; each +// AccessibleCaretEventHub holds a unique pointer to an AccessibleCaretManager. +// Thus, there's one AccessibleCaretManager per PresShell. +// +// AccessibleCaretEventHub implements a state pattern. It receives events from +// PresShell and callbacks by observers and listeners, and then relays them to +// the current concrete state which calls necessary event-handling methods in +// AccessibleCaretManager. +// +// We separate AccessibleCaretEventHub from AccessibleCaretManager to make the +// state transitions in AccessibleCaretEventHub testable. We put (nearly) all +// the operations involving PresShell, Selection, and AccessibleCaret +// manipulation in AccessibleCaretManager so that we can mock methods in +// AccessibleCaretManager in gtest. We test the correctness of the state +// transitions by giving events, callbacks, and the return values by mocked +// methods of AccessibleCaretEventHub. See TestAccessibleCaretEventHub.cpp. +// +// Besides dealing with real events, AccessibleCaretEventHub also synthesizes +// fake events such as scroll-end or long-tap providing APZ is not in use. +// +// State transition diagram: +// http://hg.mozilla.org/mozilla-central/file/default/layout/base/doc/AccessibleCaretEventHubStates.png +// Source code of the diagram: +// http://hg.mozilla.org/mozilla-central/file/default/layout/base/doc/AccessibleCaretEventHubStates.dot +// +class AccessibleCaretEventHub : public nsIReflowObserver, + public nsIScrollObserver, + public nsISelectionListener, + public nsSupportsWeakReference +{ +public: + explicit AccessibleCaretEventHub(); + virtual void Init(nsIPresShell* aPresShell); + virtual void Terminate(); + + nsEventStatus HandleEvent(WidgetEvent* aEvent); + + // Call this function to notify the blur event happened. + void NotifyBlur(bool aIsLeavingDocument); + + NS_DECL_ISUPPORTS + NS_DECL_NSIREFLOWOBSERVER + NS_DECL_NSISELECTIONLISTENER + + // Override nsIScrollObserver methods. + virtual void ScrollPositionChanged() override; + virtual void AsyncPanZoomStarted() override; + virtual void AsyncPanZoomStopped() override; + + // Base state + class State; + State* GetState() const; + +protected: + virtual ~AccessibleCaretEventHub(); + +#define NS_DECL_STATE_CLASS_GETTER(aClassName) \ + class aClassName; \ + static State* aClassName(); + +#define NS_IMPL_STATE_CLASS_GETTER(aClassName) \ + AccessibleCaretEventHub::State* AccessibleCaretEventHub::aClassName() \ + { \ + return AccessibleCaretEventHub::aClassName::Singleton(); \ + } + + // Concrete state getters + NS_DECL_STATE_CLASS_GETTER(NoActionState) + NS_DECL_STATE_CLASS_GETTER(PressCaretState) + NS_DECL_STATE_CLASS_GETTER(DragCaretState) + NS_DECL_STATE_CLASS_GETTER(PressNoCaretState) + NS_DECL_STATE_CLASS_GETTER(ScrollState) + NS_DECL_STATE_CLASS_GETTER(PostScrollState) + NS_DECL_STATE_CLASS_GETTER(LongTapState) + + void SetState(State* aState); + + nsEventStatus HandleMouseEvent(WidgetMouseEvent* aEvent); + nsEventStatus HandleWheelEvent(WidgetWheelEvent* aEvent); + nsEventStatus HandleTouchEvent(WidgetTouchEvent* aEvent); + nsEventStatus HandleKeyboardEvent(WidgetKeyboardEvent* aEvent); + + virtual nsPoint GetTouchEventPosition(WidgetTouchEvent* aEvent, + int32_t aIdentifier) const; + virtual nsPoint GetMouseEventPosition(WidgetMouseEvent* aEvent) const; + + bool MoveDistanceIsLarge(const nsPoint& aPoint) const; + + void LaunchLongTapInjector(); + void CancelLongTapInjector(); + static void FireLongTap(nsITimer* aTimer, void* aAccessibleCaretEventHub); + + void LaunchScrollEndInjector(); + void CancelScrollEndInjector(); + static void FireScrollEnd(nsITimer* aTimer, void* aAccessibleCaretEventHub); + + // Member variables + bool mInitialized = false; + + // True if async-pan-zoom should be used. + bool mUseAsyncPanZoom = false; + + State* mState = NoActionState(); + + // Will be set to nullptr in Terminate(). + nsIPresShell* MOZ_NON_OWNING_REF mPresShell = nullptr; + + UniquePtr mManager; + + WeakPtr mDocShell; + + // Use this timer for injecting a long tap event when APZ is disabled. If APZ + // is enabled, it will send long tap event to us. + nsCOMPtr mLongTapInjectorTimer; + + // Use this timer for injecting a simulated scroll end. + nsCOMPtr mScrollEndInjectorTimer; + + // Last mouse button down event or touch start event point. + nsPoint mPressPoint{ NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE }; + + // For filter multitouch event + int32_t mActiveTouchId = kInvalidTouchId; + + static const int32_t kScrollEndTimerDelay = 300; + static const int32_t kMoveStartToleranceInPixel = 5; + static const int32_t kInvalidTouchId = -1; + static const int32_t kDefaultTouchId = 0; // For mouse event +}; + +// ----------------------------------------------------------------------------- +// The base class for concrete states. A concrete state should inherit from this +// class, and override the methods to handle the events or callbacks. A concrete +// state is also responsible for transforming itself to the next concrete state. +// +class AccessibleCaretEventHub::State +{ +public: +#define NS_IMPL_STATE_UTILITIES(aClassName) \ + virtual const char* Name() const override { return #aClassName; } \ + static aClassName* Singleton() \ + { \ + static aClassName singleton; \ + return &singleton; \ + } + + virtual const char* Name() const { return ""; } + + virtual nsEventStatus OnPress(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint, int32_t aTouchId) + { + return nsEventStatus_eIgnore; + } + + virtual nsEventStatus OnMove(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint) + { + return nsEventStatus_eIgnore; + } + + virtual nsEventStatus OnRelease(AccessibleCaretEventHub* aContext) + { + return nsEventStatus_eIgnore; + } + + virtual nsEventStatus OnLongTap(AccessibleCaretEventHub* aContext, + const nsPoint& aPoint) + { + return nsEventStatus_eIgnore; + } + + virtual void OnScrollStart(AccessibleCaretEventHub* aContext) {} + virtual void OnScrollEnd(AccessibleCaretEventHub* aContext) {} + virtual void OnScrolling(AccessibleCaretEventHub* aContext) {} + virtual void OnScrollPositionChanged(AccessibleCaretEventHub* aContext) {} + virtual void OnBlur(AccessibleCaretEventHub* aContext, + bool aIsLeavingDocument) {} + virtual void OnSelectionChanged(AccessibleCaretEventHub* aContext, + nsIDOMDocument* aDoc, nsISelection* aSel, + int16_t aReason) {} + virtual void OnReflow(AccessibleCaretEventHub* aContext) {} + virtual void Enter(AccessibleCaretEventHub* aContext) {} + virtual void Leave(AccessibleCaretEventHub* aContext) {} + +protected: + explicit State() = default; + virtual ~State() = default; + State(const State&) = delete; + void operator=(const State&) = delete; +}; + +} // namespace mozilla + +#endif // AccessibleCaretEventHub_h diff --git a/layout/base/AccessibleCaretLogger.cpp b/layout/base/AccessibleCaretLogger.cpp new file mode 100644 index 0000000000..c1908b6e2a --- /dev/null +++ b/layout/base/AccessibleCaretLogger.cpp @@ -0,0 +1,27 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "AccessibleCaretLogger.h" + +namespace mozilla { + +#ifdef PR_LOGGING + +PRLogModuleInfo* +GetAccessibleCaretLog() +{ + static PRLogModuleInfo* log = nullptr; + + if (!log) { + log = PR_NewLogModule("AccessibleCaret"); + } + + return log; +} + +#endif // PR_LOGGING + +} // namespace mozilla diff --git a/layout/base/AccessibleCaretLogger.h b/layout/base/AccessibleCaretLogger.h new file mode 100644 index 0000000000..b9d2f86c2a --- /dev/null +++ b/layout/base/AccessibleCaretLogger.h @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef AccessibleCaretLog_h +#define AccessibleCaretLog_h + +#include "prlog.h" + +namespace mozilla { +#ifdef PR_LOGGING + +PRLogModuleInfo* GetAccessibleCaretLog(); + +#ifndef AC_LOG_BASE +#define AC_LOG_BASE(...) PR_LOG(GetAccessibleCaretLog(), PR_LOG_DEBUG, (__VA_ARGS__)); +#endif + +#ifndef AC_LOGV_BASE +#define AC_LOGV_BASE(...) \ + PR_LOG(GetAccessibleCaretLog(), PR_LOG_DEBUG + 1, (__VA_ARGS__)); +#endif + +#else + +#ifndef AC_LOGV_BASE +#define AC_LOGV_BASE(...) +#endif + +#ifndef AC_LOGV_BASE +#define AC_LOGV_BASE(...) +#endif + +#endif // PR_LOGGING + +} // namespace mozilla + +#endif // AccessibleCaretLog_h diff --git a/layout/base/AccessibleCaretManager.cpp b/layout/base/AccessibleCaretManager.cpp new file mode 100644 index 0000000000..88b3d7bb27 --- /dev/null +++ b/layout/base/AccessibleCaretManager.cpp @@ -0,0 +1,873 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "AccessibleCaretManager.h" + +#include "AccessibleCaret.h" +#include "AccessibleCaretEventHub.h" +#include "AccessibleCaretLogger.h" +#include "mozilla/dom/Element.h" +#include "mozilla/dom/Selection.h" +#include "mozilla/dom/TreeWalker.h" +#include "nsCaret.h" +#include "nsContentUtils.h" +#include "nsFocusManager.h" +#include "nsFrame.h" +#include "nsFrameSelection.h" +#include "nsGenericHTMLElement.h" + +namespace mozilla { + +#ifdef PR_LOGGING + +#undef AC_LOG +#define AC_LOG(message, ...) \ + AC_LOG_BASE("AccessibleCaretManager (%p): " message, this, ##__VA_ARGS__); + +#undef AC_LOGV +#define AC_LOGV(message, ...) \ + AC_LOGV_BASE("AccessibleCaretManager (%p): " message, this, ##__VA_ARGS__); + +#endif // #ifdef PR_LOGGING + +using namespace dom; +using Appearance = AccessibleCaret::Appearance; +using PositionChangedResult = AccessibleCaret::PositionChangedResult; + +AccessibleCaretManager::AccessibleCaretManager(nsIPresShell* aPresShell) + : mPresShell(aPresShell) +{ + if (mPresShell) { + mFirstCaret = MakeUnique(mPresShell); + mSecondCaret = MakeUnique(mPresShell); + + mCaretTimeoutTimer = do_CreateInstance("@mozilla.org/timer;1"); + } +} + +AccessibleCaretManager::~AccessibleCaretManager() +{ + CancelCaretTimeoutTimer(); +} + +nsresult +AccessibleCaretManager::OnSelectionChanged(nsIDOMDocument* aDoc, + nsISelection* aSel, int16_t aReason) +{ + AC_LOG("aSel: %p, GetSelection(): %p, aReason: %d", aSel, GetSelection(), + aReason); + + if (aSel != GetSelection()) { + return NS_OK; + } + + // Move the cursor by Javascript. + if (aReason == nsISelectionListener::NO_REASON) { + HideCarets(); + return NS_OK; + } + + // Move cursor by keyboard. + if (aReason & nsISelectionListener::KEYPRESS_REASON) { + HideCarets(); + return NS_OK; + } + + // Range will collapse after cutting or copying text. + if (aReason & (nsISelectionListener::COLLAPSETOSTART_REASON | + nsISelectionListener::COLLAPSETOEND_REASON)) { + HideCarets(); + return NS_OK; + } + + UpdateCarets(); + return NS_OK; +} + +void +AccessibleCaretManager::HideCarets() +{ + if (mFirstCaret->IsLogicallyVisible() || mSecondCaret->IsLogicallyVisible()) { + AC_LOG("%s", __FUNCTION__); + mFirstCaret->SetAppearance(Appearance::None); + mSecondCaret->SetAppearance(Appearance::None); + CancelCaretTimeoutTimer(); + } +} + +void +AccessibleCaretManager::UpdateCarets() +{ + mCaretMode = GetCaretMode(); + + switch (mCaretMode) { + case CaretMode::None: + HideCarets(); + break; + case CaretMode::Cursor: + UpdateCaretsForCursorMode(); + break; + case CaretMode::Selection: + UpdateCaretsForSelectionMode(); + break; + } +} + +void +AccessibleCaretManager::UpdateCaretsForCursorMode() +{ + AC_LOG("%s, selection: %p", __FUNCTION__, GetSelection()); + + nsRefPtr caret = mPresShell->GetCaret(); + if (!caret || !caret->IsVisible()) { + HideCarets(); + return; + } + + nsRefPtr fs = GetFrameSelection(); + Selection* selection = GetSelection(); + if (!fs || !selection) { + HideCarets(); + return; + } + + nsINode* focusNode = selection->GetFocusNode(); + nsIContent* focusContent = focusNode->AsContent(); + uint32_t focusOffset = selection->FocusOffset(); + + nsIFrame* frame = nullptr; + int32_t offset = 0; + nsresult rv = nsCaret::GetCaretFrameForNodeOffset( + fs, focusContent, focusOffset, fs->GetHint(), fs->GetCaretBidiLevel(), + &frame, &offset); + + if (NS_FAILED(rv) || !frame) { + HideCarets(); + return; + } + + Element* editingHost = frame->GetContent()->GetEditingHost(); + if (!editingHost) { + HideCarets(); + return; + } + + // No need to consider whether the caret's position is out of scrollport. + // According to the spec, we need to explicitly hide it after the scrolling is + // ended. + mFirstCaret->SetPosition(frame, offset); + mFirstCaret->SetSelectionBarEnabled(false); + if (nsContentUtils::HasNonEmptyTextContent( + editingHost, nsContentUtils::eRecurseIntoChildren)) { + mFirstCaret->SetAppearance(Appearance::Normal); + LaunchCaretTimeoutTimer(); + } else { + mFirstCaret->SetAppearance(Appearance::NormalNotShown); + } + mSecondCaret->SetAppearance(Appearance::None); +} + +void +AccessibleCaretManager::UpdateCaretsForSelectionMode() +{ + AC_LOG("%s, selection: %p", __FUNCTION__, GetSelection()); + + int32_t startOffset = 0; + nsIFrame* startFrame = FindFirstNodeWithFrame(false, &startOffset); + + int32_t endOffset = 0; + nsIFrame* endFrame = FindFirstNodeWithFrame(true, &endOffset); + + if (!startFrame || !endFrame || + nsLayoutUtils::CompareTreePosition(startFrame, endFrame) > 0) { + HideCarets(); + return; + } + + auto updateSingleCaret = [](AccessibleCaret * aCaret, nsIFrame * aFrame, + int32_t aOffset)->PositionChangedResult + { + PositionChangedResult result = aCaret->SetPosition(aFrame, aOffset); + aCaret->SetSelectionBarEnabled(true); + switch (result) { + case PositionChangedResult::NotChanged: + // Do nothing + break; + case PositionChangedResult::Changed: + aCaret->SetAppearance(Appearance::Normal); + break; + case PositionChangedResult::Invisible: + aCaret->SetAppearance(Appearance::NormalNotShown); + break; + } + return result; + }; + + PositionChangedResult firstCaretResult = + updateSingleCaret(mFirstCaret.get(), startFrame, startOffset); + PositionChangedResult secondCaretResult = + updateSingleCaret(mSecondCaret.get(), endFrame, endOffset); + + if (firstCaretResult == PositionChangedResult::Changed || + secondCaretResult == PositionChangedResult::Changed) { + // Flush layout to make the carets intersection correct. + mPresShell->FlushPendingNotifications(Flush_Layout); + } + + UpdateCaretsForTilt(); +} + +void +AccessibleCaretManager::UpdateCaretsForTilt() +{ + if (mFirstCaret->IsVisuallyVisible() && mSecondCaret->IsVisuallyVisible()) { + if (mFirstCaret->Intersects(*mSecondCaret)) { + if (mFirstCaret->LogicalPosition().x <= + mSecondCaret->LogicalPosition().x) { + mFirstCaret->SetAppearance(Appearance::Left); + mSecondCaret->SetAppearance(Appearance::Right); + } else { + mFirstCaret->SetAppearance(Appearance::Right); + mSecondCaret->SetAppearance(Appearance::Left); + } + } else { + mFirstCaret->SetAppearance(Appearance::Normal); + mSecondCaret->SetAppearance(Appearance::Normal); + } + } +} + +nsresult +AccessibleCaretManager::PressCaret(const nsPoint& aPoint) +{ + nsresult rv = NS_ERROR_FAILURE; + + if (mFirstCaret->Contains(aPoint)) { + mActiveCaret = mFirstCaret.get(); + SetSelectionDirection(eDirPrevious); + } else if (mSecondCaret->Contains(aPoint)) { + mActiveCaret = mSecondCaret.get(); + SetSelectionDirection(eDirNext); + } + + if (mActiveCaret) { + mOffsetYToCaretLogicalPosition = + mActiveCaret->LogicalPosition().y - aPoint.y; + SetSelectionDragState(true); + CancelCaretTimeoutTimer(); + rv = NS_OK; + } + + return rv; +} + +nsresult +AccessibleCaretManager::DragCaret(const nsPoint& aPoint) +{ + MOZ_ASSERT(mActiveCaret); + MOZ_ASSERT(GetCaretMode() != CaretMode::None); + + nsPoint point(aPoint.x, aPoint.y + mOffsetYToCaretLogicalPosition); + DragCaretInternal(point); + UpdateCarets(); + return NS_OK; +} + +nsresult +AccessibleCaretManager::ReleaseCaret() +{ + MOZ_ASSERT(mActiveCaret); + + mActiveCaret = nullptr; + SetSelectionDragState(false); + LaunchCaretTimeoutTimer(); + return NS_OK; +} + +nsresult +AccessibleCaretManager::TapCaret(const nsPoint& aPoint) +{ + MOZ_ASSERT(GetCaretMode() != CaretMode::None); + + nsresult rv = NS_ERROR_FAILURE; + + if (GetCaretMode() == CaretMode::Cursor) { + rv = NS_OK; + } + + return rv; +} + +nsresult +AccessibleCaretManager::SelectWordOrShortcut(const nsPoint& aPoint) +{ + if (!mPresShell) { + return NS_ERROR_UNEXPECTED; + } + + nsIFrame* rootFrame = mPresShell->GetRootFrame(); + if (!rootFrame) { + return NS_ERROR_NOT_AVAILABLE; + } + + // Find content offsets for mouse down point + nsIFrame* ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, aPoint, + nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC); + if (!ptFrame) { + return NS_ERROR_FAILURE; + } + + bool selectable; + ptFrame->IsSelectable(&selectable, nullptr); + if (!selectable) { + return NS_ERROR_FAILURE; + } + + nsPoint ptInFrame = aPoint; + nsLayoutUtils::TransformPoint(rootFrame, ptFrame, ptInFrame); + + nsIContent* editingHost = ptFrame->GetContent()->GetEditingHost(); + if (ChangeFocus(ptFrame) && + (editingHost && !nsContentUtils::HasNonEmptyTextContent( + editingHost, nsContentUtils::eRecurseIntoChildren))) { + // Content is empty. No need to select word. + AC_LOG("%s, Cannot select word bacause content is empty", __FUNCTION__); + return NS_OK; + } + + nsresult rv = SelectWord(ptFrame, ptInFrame); + UpdateCarets(); + return rv; +} + +void +AccessibleCaretManager::OnScrollStart() +{ + AC_LOG("%s", __FUNCTION__); + + HideCarets(); +} + +void +AccessibleCaretManager::OnScrollEnd() +{ + if (mCaretMode != GetCaretMode()) { + return; + } + + if (GetCaretMode() == CaretMode::Cursor) { + AC_LOG("%s: HideCarets()", __FUNCTION__); + HideCarets(); + } else { + AC_LOG("%s: UpdateCarets()", __FUNCTION__); + UpdateCarets(); + } +} + +void +AccessibleCaretManager::OnScrolling() +{ + if (mCaretMode != GetCaretMode()) { + return; + } + + if (GetCaretMode() == CaretMode::Cursor) { + AC_LOG("%s: HideCarets()", __FUNCTION__); + HideCarets(); + } else { + AC_LOG("%s: UpdateCarets()", __FUNCTION__); + UpdateCarets(); + } +} + +void +AccessibleCaretManager::OnScrollPositionChanged() +{ + if (mCaretMode != GetCaretMode()) { + return; + } + + AC_LOG("%s: UpdateCarets()", __FUNCTION__); + UpdateCarets(); +} + +void +AccessibleCaretManager::OnReflow() +{ + if (mCaretMode != GetCaretMode()) { + return; + } + + if (mFirstCaret->IsVisuallyVisible() || mSecondCaret->IsVisuallyVisible()) { + AC_LOG("%s: UpdateCarets()", __FUNCTION__); + UpdateCarets(); + } +} + +void +AccessibleCaretManager::OnBlur() +{ + AC_LOG("%s: HideCarets()", __FUNCTION__); + HideCarets(); +} + +void +AccessibleCaretManager::OnKeyboardEvent() +{ + if (GetCaretMode() == CaretMode::Cursor) { + AC_LOG("%s: HideCarets()", __FUNCTION__); + HideCarets(); + } +} + +nsIContent* +AccessibleCaretManager::GetFocusedContent() const +{ + nsFocusManager* fm = nsFocusManager::GetFocusManager(); + MOZ_ASSERT(fm); + return fm->GetFocusedContent(); +} + +Selection* +AccessibleCaretManager::GetSelection() const +{ + nsRefPtr fs = GetFrameSelection(); + if (!fs) { + return nullptr; + } + return fs->GetSelection(nsISelectionController::SELECTION_NORMAL); +} + +already_AddRefed +AccessibleCaretManager::GetFrameSelection() const +{ + nsIContent* focusedContent = GetFocusedContent(); + if (focusedContent) { + nsIFrame* focusFrame = focusedContent->GetPrimaryFrame(); + if (!focusFrame) { + return nullptr; + } + + // Prevent us from touching the nsFrameSelection associated with other + // PresShell. + nsRefPtr fs = focusFrame->GetFrameSelection(); + if (!fs || fs->GetShell() != mPresShell) { + return nullptr; + } + + return fs.forget(); + } else { + // For non-editable content + return mPresShell->FrameSelection(); + } +} + +AccessibleCaretManager::CaretMode +AccessibleCaretManager::GetCaretMode() const +{ + Selection* selection = GetSelection(); + if (!selection) { + return CaretMode::None; + } + + uint32_t rangeCount = selection->RangeCount(); + if (rangeCount <= 0) { + return CaretMode::None; + } + + if (selection->IsCollapsed()) { + return CaretMode::Cursor; + } + + return CaretMode::Selection; +} + +bool +AccessibleCaretManager::ChangeFocus(nsIFrame* aFrame) const +{ + nsIFrame* currFrame = aFrame; + nsIContent* newFocusContent = nullptr; + while (currFrame) { + int32_t tabIndexUnused = 0; + if (currFrame->IsFocusable(&tabIndexUnused, true)) { + newFocusContent = currFrame->GetContent(); + nsCOMPtr domElement(do_QueryInterface(newFocusContent)); + if (domElement) + break; + } + currFrame = currFrame->GetParent(); + } + + // If target frame is focusable, we should move focus to it. If target frame + // isn't focusable, and our previous focused content is editable, we should + // clear focus. + nsFocusManager* fm = nsFocusManager::GetFocusManager(); + if (newFocusContent && currFrame) { + nsCOMPtr domElement(do_QueryInterface(newFocusContent)); + fm->SetFocus(domElement, 0); + } else { + nsIContent* focusedContent = GetFocusedContent(); + if (focusedContent) { + // Clear focus if content was editable element, or contentEditable. + nsGenericHTMLElement* focusedGeneric = + nsGenericHTMLElement::FromContent(focusedContent); + if (focusedContent->GetTextEditorRootContent() || + (focusedGeneric && focusedGeneric->IsContentEditable())) { + nsIDOMWindow* win = mPresShell->GetDocument()->GetWindow(); + if (win) { + fm->ClearFocus(win); + } + } + } + } + + return (newFocusContent && currFrame); +} + +nsresult +AccessibleCaretManager::SelectWord(nsIFrame* aFrame, const nsPoint& aPoint) const +{ + SetSelectionDragState(true); + nsFrame* frame = static_cast(aFrame); + nsresult rs = frame->SelectByTypeAtPoint(mPresShell->GetPresContext(), aPoint, + eSelectWord, eSelectWord, 0); + +#ifdef DEBUG_FRAME_DUMP + nsCString frameTag; + frame->ListTag(frameTag); + AC_LOG("Frame=%s, ptInFrame=(%d, %d)", frameTag.get(), aPoint.x, aPoint.y); +#endif + + SetSelectionDragState(false); + ClearMaintainedSelection(); + + return rs; +} + +void +AccessibleCaretManager::SetSelectionDragState(bool aState) const +{ + nsRefPtr fs = GetFrameSelection(); + if (fs) { + fs->SetDragState(aState); + } +} + +void +AccessibleCaretManager::SetSelectionDirection(nsDirection aDir) const +{ + Selection* selection = GetSelection(); + if (selection) { + selection->AdjustAnchorFocusForMultiRange(aDir); + } +} + +void +AccessibleCaretManager::ClearMaintainedSelection() const +{ + // Selection made by double-clicking for example will maintain the original + // word selection. We should clear it so that we can drag caret freely. + nsRefPtr fs = GetFrameSelection(); + if (fs) { + fs->MaintainSelection(eSelectNoAmount); + } +} + +nsIFrame* +AccessibleCaretManager::FindFirstNodeWithFrame(bool aBackward, + int32_t* aOutOffset) const +{ + if (!mPresShell) { + return nullptr; + } + + nsRefPtr selection = GetSelection(); + if (!selection) { + return nullptr; + } + + nsRefPtr fs = GetFrameSelection(); + if (!fs) { + return nullptr; + } + + uint32_t rangeCount = selection->RangeCount(); + if (rangeCount <= 0) { + return nullptr; + } + + nsRange* range = selection->GetRangeAt(aBackward ? rangeCount - 1 : 0); + nsRefPtr startNode = + aBackward ? range->GetEndParent() : range->GetStartParent(); + nsRefPtr endNode = + aBackward ? range->GetStartParent() : range->GetEndParent(); + int32_t offset = aBackward ? range->EndOffset() : range->StartOffset(); + nsCOMPtr startContent = do_QueryInterface(startNode); + CaretAssociationHint hintStart = + aBackward ? CARET_ASSOCIATE_BEFORE : CARET_ASSOCIATE_AFTER; + nsIFrame* startFrame = + fs->GetFrameForNodeOffset(startContent, offset, hintStart, aOutOffset); + + if (startFrame) { + return startFrame; + } + + ErrorResult err; + nsRefPtr walker = mPresShell->GetDocument()->CreateTreeWalker( + *startNode, nsIDOMNodeFilter::SHOW_ALL, nullptr, err); + + if (!walker) { + return nullptr; + } + + startFrame = startContent ? startContent->GetPrimaryFrame() : nullptr; + while (!startFrame && startNode != endNode) { + startNode = aBackward ? walker->PreviousNode(err) : walker->NextNode(err); + + if (!startNode) { + break; + } + + startContent = startNode->AsContent(); + startFrame = startContent ? startContent->GetPrimaryFrame() : nullptr; + } + return startFrame; +} + +bool +AccessibleCaretManager::CompareRangeWithContentOffset(nsIFrame::ContentOffsets& aOffsets) +{ + Selection* selection = GetSelection(); + if (!selection) { + return false; + } + + uint32_t rangeCount = selection->RangeCount(); + MOZ_ASSERT(rangeCount > 0); + + int32_t rangeIndex = (mActiveCaret == mFirstCaret.get() ? rangeCount - 1 : 0); + nsRefPtr range = selection->GetRangeAt(rangeIndex); + + nsINode* node = nullptr; + int32_t nodeOffset = 0; + CaretAssociationHint hint; + nsDirection dir; + + if (mActiveCaret == mFirstCaret.get()) { + // Check previous character of end node offset + node = range->GetEndParent(); + nodeOffset = range->EndOffset(); + hint = CARET_ASSOCIATE_BEFORE; + dir = eDirPrevious; + } else { + // Check next character of start node offset + node = range->GetStartParent(); + nodeOffset = range->StartOffset(); + hint = CARET_ASSOCIATE_AFTER; + dir = eDirNext; + } + nsCOMPtr content = do_QueryInterface(node); + + nsRefPtr fs = GetFrameSelection(); + if (!fs) { + return false; + } + + int32_t offset = 0; + nsIFrame* theFrame = + fs->GetFrameForNodeOffset(content, nodeOffset, hint, &offset); + + if (!theFrame) { + return false; + } + + // Move one character forward/backward from point and get offset + nsPeekOffsetStruct pos(eSelectCluster, + dir, + offset, + nsPoint(0, 0), + true, + true, //limit on scrolled views + false, + false, + false); + nsresult rv = theFrame->PeekOffset(&pos); + if (NS_FAILED(rv)) { + pos.mResultContent = content; + pos.mContentOffset = nodeOffset; + } + + // Compare with current point + int32_t result = nsContentUtils::ComparePoints(aOffsets.content, + aOffsets.StartOffset(), + pos.mResultContent, + pos.mContentOffset); + if ((mActiveCaret == mFirstCaret.get() && result == 1) || + (mActiveCaret == mSecondCaret.get() && result == -1)) { + aOffsets.content = pos.mResultContent; + aOffsets.offset = pos.mContentOffset; + aOffsets.secondaryOffset = pos.mContentOffset; + } + + return true; +} + +nsresult +AccessibleCaretManager::DragCaretInternal(const nsPoint& aPoint) +{ + if (!mPresShell) { + return NS_ERROR_NULL_POINTER; + } + + nsIFrame* rootFrame = mPresShell->GetRootFrame(); + if (!rootFrame) { + return NS_ERROR_NULL_POINTER; + } + + nsPoint point = AdjustDragBoundary(aPoint); + + // Find out which content we point to + nsIFrame* ptFrame = nsLayoutUtils::GetFrameForPoint( + rootFrame, point, + nsLayoutUtils::IGNORE_PAINT_SUPPRESSION | nsLayoutUtils::IGNORE_CROSS_DOC); + if (!ptFrame) { + return NS_ERROR_FAILURE; + } + + nsRefPtr fs = GetFrameSelection(); + if (!fs) { + return NS_ERROR_NULL_POINTER; + } + + nsresult result; + nsIFrame* newFrame = nullptr; + nsPoint newPoint; + nsPoint ptInFrame = point; + nsLayoutUtils::TransformPoint(rootFrame, ptFrame, ptInFrame); + result = fs->ConstrainFrameAndPointToAnchorSubtree(ptFrame, ptInFrame, + &newFrame, newPoint); + if (NS_FAILED(result) || !newFrame) { + return NS_ERROR_FAILURE; + } + + bool selectable; + newFrame->IsSelectable(&selectable, nullptr); + if (!selectable) { + return NS_ERROR_FAILURE; + } + + nsIFrame::ContentOffsets offsets = + newFrame->GetContentOffsetsFromPoint(newPoint); + if (!offsets.content) { + return NS_ERROR_FAILURE; + } + + Selection* selection = GetSelection(); + if (!selection) { + return NS_ERROR_NULL_POINTER; + } + + if (GetCaretMode() == CaretMode::Selection && + !CompareRangeWithContentOffset(offsets)) { + return NS_ERROR_FAILURE; + } + + ClearMaintainedSelection(); + + nsIFrame* anchorFrame = nullptr; + selection->GetPrimaryFrameForAnchorNode(&anchorFrame); + + nsIFrame* scrollable = + nsLayoutUtils::GetClosestFrameOfType(anchorFrame, nsGkAtoms::scrollFrame); + nsWeakFrame weakScrollable = scrollable; + fs->HandleClick(offsets.content, offsets.StartOffset(), offsets.EndOffset(), + GetCaretMode() == CaretMode::Selection, false, + offsets.associate); + if (!weakScrollable.IsAlive()) { + return NS_OK; + } + + // Scroll scrolled frame. + nsIScrollableFrame* saf = do_QueryFrame(scrollable); + nsIFrame* capturingFrame = saf->GetScrolledFrame(); + nsPoint ptInScrolled = point; + nsLayoutUtils::TransformPoint(rootFrame, capturingFrame, ptInScrolled); + fs->StartAutoScrollTimer(capturingFrame, ptInScrolled, kAutoScrollTimerDelay); + return NS_OK; +} + +nsPoint +AccessibleCaretManager::AdjustDragBoundary(const nsPoint& aPoint) const +{ + // Bug 1068474: Adjust the Y-coordinate so that the carets won't be in tilt + // mode when a caret is being dragged surpass the other caret. + // + // For example, when dragging the second caret, the horizontal boundary (lower + // bound) of its Y-coordinate is the logical position of the first caret. + // Likewise, when dragging the first caret, the horizontal boundary (upper + // bound) of its Y-coordinate is the logical position of the second caret. + nsPoint adjustedPoint = aPoint; + + if (GetCaretMode() == CaretMode::Selection) { + if (mActiveCaret == mFirstCaret.get()) { + nscoord dragDownBoundaryY = mSecondCaret->LogicalPosition().y; + if (adjustedPoint.y > dragDownBoundaryY) { + adjustedPoint.y = dragDownBoundaryY; + } + } else { + nscoord dragUpBoundaryY = mFirstCaret->LogicalPosition().y; + if (adjustedPoint.y < dragUpBoundaryY) { + adjustedPoint.y = dragUpBoundaryY; + } + } + } + + return adjustedPoint; +} + +uint32_t +AccessibleCaretManager::CaretTimeoutMs() const +{ + static bool added = false; + static uint32_t caretTimeoutMs = 0; + + if (!added) { + Preferences::AddUintVarCache(&caretTimeoutMs, + "layout.accessiblecaret.timeout_ms"); + added = true; + } + + return caretTimeoutMs; +} + +void +AccessibleCaretManager::LaunchCaretTimeoutTimer() +{ + if (!mCaretTimeoutTimer || CaretTimeoutMs() == 0 || + GetCaretMode() != CaretMode::Cursor || mActiveCaret) { + return; + } + + nsTimerCallbackFunc callback = [](nsITimer* aTimer, void* aClosure) { + auto self = static_cast(aClosure); + if (self->GetCaretMode() == CaretMode::Cursor) { + self->HideCarets(); + } + }; + + mCaretTimeoutTimer->InitWithFuncCallback(callback, this, CaretTimeoutMs(), + nsITimer::TYPE_ONE_SHOT); +} + +void +AccessibleCaretManager::CancelCaretTimeoutTimer() +{ + if (mCaretTimeoutTimer) { + mCaretTimeoutTimer->Cancel(); + } +} + +} // namespace mozilla diff --git a/layout/base/AccessibleCaretManager.h b/layout/base/AccessibleCaretManager.h new file mode 100644 index 0000000000..2a3fb17430 --- /dev/null +++ b/layout/base/AccessibleCaretManager.h @@ -0,0 +1,174 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef AccessibleCaretManager_h +#define AccessibleCaretManager_h + +#include "nsCOMPtr.h" +#include "nsCoord.h" +#include "nsIFrame.h" +#include "nsISelectionListener.h" +#include "mozilla/nsRefPtr.h" +#include "nsWeakReference.h" +#include "mozilla/EventForwards.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/WeakPtr.h" + +class nsFrameSelection; +class nsIContent; +class nsIPresShell; +struct nsPoint; + +namespace mozilla { + +namespace dom { +class Selection; +} + +class AccessibleCaret; + +// ----------------------------------------------------------------------------- +// AccessibleCaretManager does not deal with events or callbacks directly. It +// relies on AccessibleCaretEventHub to call its public methods to do the work. +// All codes needed to interact with PresShell, Selection, and AccessibleCaret +// should be written in AccessibleCaretManager. +// +// None the public methods in AccessibleCaretManager will flush layout or style +// prior to performing its task. The caller must ensure the layout is up to +// date. +// +class AccessibleCaretManager +{ +public: + explicit AccessibleCaretManager(nsIPresShell* aPresShell); + virtual ~AccessibleCaretManager(); + + // The aPoint in the following public methods should be relative to root + // frame. + + // Press caret on the given point. Return NS_OK if the point is actually on + // one of the carets. + virtual nsresult PressCaret(const nsPoint& aPoint); + + // Drag caret to the given point. It's required to call PressCaret() + // beforehand. + virtual nsresult DragCaret(const nsPoint& aPoint); + + // Release caret from he previous press action. It's required to call + // PressCaret() beforehand. + virtual nsresult ReleaseCaret(); + + // A quick single tap on caret on given point without dragging. + virtual nsresult TapCaret(const nsPoint& aPoint); + + // Select a word or bring up paste shortcut (if Gaia is listening) under the + // given point. + virtual nsresult SelectWordOrShortcut(const nsPoint& aPoint); + + // Handle scroll-start event. + virtual void OnScrollStart(); + + // Handle scroll-end event. + virtual void OnScrollEnd(); + + // Handle NS_WHEEL_WHEEL event. + virtual void OnScrolling(); + + // Handle ScrollPositionChanged from nsIScrollObserver. + virtual void OnScrollPositionChanged(); + + // Handle reflow event from nsIReflowObserver. + virtual void OnReflow(); + + // Handle blur event from nsFocusManager. + virtual void OnBlur(); + + // Handle NotifySelectionChanged event from nsISelectionListener. + virtual nsresult OnSelectionChanged(nsIDOMDocument* aDoc, + nsISelection* aSel, + int16_t aReason); + // Handle key event. + virtual void OnKeyboardEvent(); + +protected: + // This enum representing the number of AccessibleCarets on the screen. + enum class CaretMode : uint8_t { + // No caret on the screen. + None, + + // One caret, i.e. the selection is collapsed. + Cursor, + + // Two carets, i.e. the selection is not collapsed. + Selection + }; + CaretMode GetCaretMode() const; + + void UpdateCarets(); + void HideCarets(); + + void UpdateCaretsForCursorMode(); + void UpdateCaretsForSelectionMode(); + void UpdateCaretsForTilt(); + + bool ChangeFocus(nsIFrame* aFrame) const; + nsresult SelectWord(nsIFrame* aFrame, const nsPoint& aPoint) const; + void SetSelectionDragState(bool aState) const; + void SetSelectionDirection(nsDirection aDir) const; + + // If aBackward is false, find the first node from the first range in current + // selection, and return the frame and the offset into that frame. If aBackward + // is true, find the last node from the last range instead. + nsIFrame* FindFirstNodeWithFrame(bool aBackward, int32_t* aOutOffset) const; + + nsresult DragCaretInternal(const nsPoint& aPoint); + nsPoint AdjustDragBoundary(const nsPoint& aPoint) const; + void ClearMaintainedSelection() const; + + dom::Selection* GetSelection() const; + already_AddRefed GetFrameSelection() const; + nsIContent* GetFocusedContent() const; + + // If we're dragging the first caret, we do not want to drag it over the + // previous character of the second caret. Same as the second caret. So we + // check if content offset exceeds the previous/next character of second/first + // caret base the active caret. + bool CompareRangeWithContentOffset(nsIFrame::ContentOffsets& aOffsets); + + // Timeout in milliseconds to hide the AccessibleCaret under cursor mode while + // no one touches it. + uint32_t CaretTimeoutMs() const; + void LaunchCaretTimeoutTimer(); + void CancelCaretTimeoutTimer(); + + // Member variables + nscoord mOffsetYToCaretLogicalPosition = NS_UNCONSTRAINEDSIZE; + + // AccessibleCaretEventHub owns us. When it's Terminate() called by + // PresShell::Destroy(), we will be destroyed. No need to worry we outlive + // mPresShell. + nsIPresShell* MOZ_NON_OWNING_REF const mPresShell = nullptr; + + // First caret is attached to nsCaret in cursor mode, and is attached to + // selection highlight as the left caret in selection mode. + UniquePtr mFirstCaret; + + // Second caret is used solely in selection mode, and is attached to selection + // highlight as the right caret. + UniquePtr mSecondCaret; + + // The caret being pressed or dragged. + AccessibleCaret* mActiveCaret = nullptr; + + nsCOMPtr mCaretTimeoutTimer; + CaretMode mCaretMode = CaretMode::None; + + static const int32_t kAutoScrollTimerDelay = 30; +}; + +} // namespace mozilla + +#endif // AccessibleCaretManager_h diff --git a/layout/base/SelectionCarets.cpp b/layout/base/SelectionCarets.cpp index 8fbac6e392..54608b5b61 100644 --- a/layout/base/SelectionCarets.cpp +++ b/layout/base/SelectionCarets.cpp @@ -201,13 +201,13 @@ SelectionCarets::HandleEvent(WidgetEvent* aEvent) if (IsOnStartFrameInner(ptInRoot)) { mDragMode = START_FRAME; mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - ptInRoot.y; - SetSelectionDirection(false); + SetSelectionDirection(eDirPrevious); SetSelectionDragState(true); return nsEventStatus_eConsumeNoDefault; } else if (IsOnEndFrameInner(ptInRoot)) { mDragMode = END_FRAME; mCaretCenterToDownPointOffsetY = GetCaretYCenterPosition() - ptInRoot.y; - SetSelectionDirection(true); + SetSelectionDirection(eDirNext); SetSelectionDragState(true); return nsEventStatus_eConsumeNoDefault; } else { @@ -770,6 +770,9 @@ SelectionCarets::DragSelection(const nsPoint &movePoint) return nsEventStatus_eConsumeNoDefault; } + // Clear maintain selection so that we can drag caret freely. + fs->MaintainSelection(eSelectNoAmount); + // Move caret postion. nsIFrame *scrollable = nsLayoutUtils::GetClosestFrameOfType(anchorFrame, nsGkAtoms::scrollFrame); @@ -854,11 +857,11 @@ SelectionCarets::SetSelectionDragState(bool aState) } void -SelectionCarets::SetSelectionDirection(bool aForward) +SelectionCarets::SetSelectionDirection(nsDirection aDir) { nsRefPtr selection = GetSelection(); if (selection) { - selection->SetDirection(aForward ? eDirNext : eDirPrevious); + selection->AdjustAnchorFocusForMultiRange(aDir); } } @@ -1115,7 +1118,7 @@ SelectionCarets::NotifySelectionChanged(nsIDOMDocument* aDoc, } static void -DispatchScrollViewChangeEvent(nsIPresShell *aPresShell, const dom::ScrollState aState, const mozilla::CSSIntPoint aScrollPos) +DispatchScrollViewChangeEvent(nsIPresShell *aPresShell, const dom::ScrollState aState) { nsCOMPtr doc = aPresShell->GetDocument(); if (doc) { @@ -1124,8 +1127,6 @@ DispatchScrollViewChangeEvent(nsIPresShell *aPresShell, const dom::ScrollState a detail.mBubbles = true; detail.mCancelable = false; detail.mState = aState; - detail.mScrollX = aScrollPos.x; - detail.mScrollY = aScrollPos.y; nsRefPtr event = ScrollViewChangeEvent::Constructor(doc, NS_LITERAL_STRING("scrollviewchange"), detail); @@ -1136,26 +1137,25 @@ DispatchScrollViewChangeEvent(nsIPresShell *aPresShell, const dom::ScrollState a } void -SelectionCarets::AsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos) +SelectionCarets::AsyncPanZoomStarted() { if (mVisible) { mInAsyncPanZoomGesture = true; SetVisibility(false); - SELECTIONCARETS_LOG("Dispatch scroll started with position x=%d, y=%d", - aScrollPos.x, aScrollPos.y); - DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Started, aScrollPos); + SELECTIONCARETS_LOG("Dispatch scroll started"); + DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Started); } else { nsRefPtr selection = GetSelection(); if (selection && selection->RangeCount() && selection->IsCollapsed()) { mInAsyncPanZoomGesture = true; - DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Started, aScrollPos); + DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Started); } } } void -SelectionCarets::AsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos) +SelectionCarets::AsyncPanZoomStopped() { if (mInAsyncPanZoomGesture) { mInAsyncPanZoomGesture = false; @@ -1166,10 +1166,9 @@ SelectionCarets::AsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos) DispatchSelectionStateChangedEvent(GetSelection(), SelectionState::Updateposition); - SELECTIONCARETS_LOG("Dispatch scroll stopped with position x=%d, y=%d", - aScrollPos.x, aScrollPos.y); + SELECTIONCARETS_LOG("Dispatch scroll stopped"); - DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Stopped, aScrollPos); + DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Stopped); } } @@ -1180,6 +1179,10 @@ SelectionCarets::ScrollPositionChanged() if (!mUseAsyncPanZoom) { SetVisibility(false); //TODO: handling scrolling for selection bubble when APZ is off + // Dispatch event to notify gaia to hide selection bubble. + // Positions will be updated when scroll is end, so no need to calculate + // and keep scroll positions here. An arbitrary (0, 0) is sent instead. + DispatchScrollViewChangeEvent(mPresShell, dom::ScrollState::Started); SELECTIONCARETS_LOG("Launch scroll end detector"); LaunchScrollEndDetector(); diff --git a/layout/base/SelectionCarets.h b/layout/base/SelectionCarets.h index 68ea99653f..5072685208 100644 --- a/layout/base/SelectionCarets.h +++ b/layout/base/SelectionCarets.h @@ -7,6 +7,7 @@ #ifndef SelectionCarets_h__ #define SelectionCarets_h__ +#include "nsDirection.h" #include "nsIReflowObserver.h" #include "nsIScrollObserver.h" #include "nsISelectionListener.h" @@ -78,8 +79,8 @@ public: virtual void ScrollPositionChanged() override; // AsyncPanZoom started/stopped callbacks from nsIScrollObserver - virtual void AsyncPanZoomStarted(const mozilla::CSSIntPoint aScrollPos) override; - virtual void AsyncPanZoomStopped(const mozilla::CSSIntPoint aScrollPos) override; + virtual void AsyncPanZoomStarted() override; + virtual void AsyncPanZoomStopped() override; void Init(); void Terminate(); @@ -138,7 +139,7 @@ private: */ void SetSelectionDragState(bool aState); - void SetSelectionDirection(bool aForward); + void SetSelectionDirection(nsDirection aDir); /** * Move start frame of selection caret to given position. diff --git a/layout/base/doc/AccessibleCaretEventHubStates.dot b/layout/base/doc/AccessibleCaretEventHubStates.dot new file mode 100644 index 0000000000..0a440d1644 --- /dev/null +++ b/layout/base/doc/AccessibleCaretEventHubStates.dot @@ -0,0 +1,37 @@ +// Steps to generate AccessibleCaretEventHubStates.png +// 1. Install Graphviz +// 2. dot -T png -o AccessibleCaretEventHubStates.png AccessibleCaretEventHubStates.dot +digraph event_hub_states { + node [style=filled]; + edge [color="gray30", fontcolor="gray20", fontsize=12] + + NoAction [label="NoAction\n(Initial)"color="#96FF2F"]; + NoAction -> PressCaret [label="Press & on a caret"]; + NoAction -> PressNoCaret [label="Press & not on a caret"]; + NoAction -> Scroll [label="Scroll start"]; + + PressCaret [color="#84D8FF"]; + PressCaret -> DragCaret [label="Move & distance is large"]; + PressCaret -> NoAction [label="Release (synthesizing a tap)"]; + + DragCaret [color="#84D8FF"]; + DragCaret -> DragCaret [label="Move"]; + DragCaret -> NoAction [label="Release"]; + + PressNoCaret [color="#E8C516"]; + PressNoCaret -> NoAction [label="Move & distance is large or\nRelease or\nBlur"]; + PressNoCaret -> LongTap [label="Long tap"]; + PressNoCaret -> Scroll [label="Scroll start", constraint=false]; + + LongTap [color="#E8C516"] + LongTap -> NoAction; + + Scroll [color="#FF9022"] + Scroll -> PostScroll [label="Scroll end"]; + Scroll -> NoAction [label="Blur"]; + + PostScroll [color="#FF9022"] + PostScroll -> Scroll [label="Scroll start"]; + PostScroll -> NoAction [label="Blur or\nWait 300ms"]; + PostScroll -> NoAction [label="Press (forward to NoAction)", constraint=false]; +} diff --git a/layout/base/doc/AccessibleCaretEventHubStates.png b/layout/base/doc/AccessibleCaretEventHubStates.png new file mode 100644 index 0000000000000000000000000000000000000000..cb1f63b25f2f702ecc3e9eeac337fda9e32685d6 GIT binary patch literal 92942 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%0DTJw#o|D#T*i1Ozf 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

  • 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�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%0A=Dq?rceBf zd_HjP|Ol;hb1LAcqj3jSs%9PVfBoQ(r~m)} literal 0 HcmV?d00001 diff --git a/layout/base/gtest/TestAccessibleCaretEventHub.cpp b/layout/base/gtest/TestAccessibleCaretEventHub.cpp new file mode 100644 index 0000000000..4e18fb8577 --- /dev/null +++ b/layout/base/gtest/TestAccessibleCaretEventHub.cpp @@ -0,0 +1,761 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "gtest/gtest.h" +#include "gmock/gmock.h" + +#include +#include + +#include "AccessibleCaretEventHub.h" +#include "AccessibleCaretManager.h" +#include "gfxPrefs.h" +#include "mozilla/BasicEvents.h" +#include "mozilla/MouseEvents.h" +#include "mozilla/TouchEvents.h" + +using ::testing::AtLeast; +using ::testing::DefaultValue; +using ::testing::Eq; +using ::testing::InSequence; +using ::testing::MockFunction; +using ::testing::Return; +using ::testing::_; + +// ----------------------------------------------------------------------------- +// This file test the state transitions of AccessibleCaretEventHub under +// various combination of events and callbacks. + +namespace mozilla +{ + +class MockAccessibleCaretManager : public AccessibleCaretManager +{ +public: + explicit MockAccessibleCaretManager() + : AccessibleCaretManager(nullptr) + { + } + + MOCK_METHOD1(PressCaret, nsresult(const nsPoint& aPoint)); + MOCK_METHOD1(DragCaret, nsresult(const nsPoint& aPoint)); + MOCK_METHOD0(ReleaseCaret, nsresult()); + MOCK_METHOD1(TapCaret, nsresult(const nsPoint& aPoint)); + MOCK_METHOD1(SelectWordOrShortcut, nsresult(const nsPoint& aPoint)); + MOCK_METHOD0(OnScrollStart, void()); + MOCK_METHOD0(OnScrollEnd, void()); + MOCK_METHOD0(OnScrolling, void()); + MOCK_METHOD0(OnScrollPositionChanged, void()); + MOCK_METHOD0(OnBlur, void()); +}; + +class MockAccessibleCaretEventHub : public AccessibleCaretEventHub +{ +public: + using AccessibleCaretEventHub::NoActionState; + using AccessibleCaretEventHub::PressCaretState; + using AccessibleCaretEventHub::DragCaretState; + using AccessibleCaretEventHub::PressNoCaretState; + using AccessibleCaretEventHub::ScrollState; + using AccessibleCaretEventHub::PostScrollState; + using AccessibleCaretEventHub::FireScrollEnd; + + explicit MockAccessibleCaretEventHub() + { + mManager = MakeUnique(); + mInitialized = true; + } + + virtual nsPoint GetTouchEventPosition(WidgetTouchEvent* aEvent, + int32_t aIdentifier) const override + { + // Return the device point directly. + LayoutDeviceIntPoint touchIntPoint = aEvent->touches[0]->mRefPoint; + return nsPoint(touchIntPoint.x, touchIntPoint.y); + } + + virtual nsPoint GetMouseEventPosition(WidgetMouseEvent* aEvent) const override + { + // Return the device point directly. + LayoutDeviceIntPoint mouseIntPoint = aEvent->AsGUIEvent()->refPoint; + return nsPoint(mouseIntPoint.x, mouseIntPoint.y); + } + + MockAccessibleCaretManager* GetMockAccessibleCaretManager() + { + return static_cast(mManager.get()); + } + + void SetUseAsyncPanZoom(bool aUseAsyncPanZoom) + { + mUseAsyncPanZoom = aUseAsyncPanZoom; + } +}; + +// Print the name of the state for debugging. +::std::ostream& operator<<(::std::ostream& aOstream, + const MockAccessibleCaretEventHub::State* aState) +{ + return aOstream << aState->Name(); +} + +class AccessibleCaretEventHubTester : public ::testing::Test +{ +public: + explicit AccessibleCaretEventHubTester() + { + DefaultValue::Set(NS_OK); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); + } + + static UniquePtr CreateMouseEvent(uint32_t aMessage, nscoord aX, + nscoord aY) + { + auto event = MakeUnique(true, aMessage, nullptr, + WidgetMouseEvent::eReal); + + event->button = WidgetMouseEvent::eLeftButton; + event->refPoint = LayoutDeviceIntPoint(aX, aY); + + return Move(event); + } + + static UniquePtr CreateMousePressEvent(nscoord aX, nscoord aY) + { + return CreateMouseEvent(NS_MOUSE_BUTTON_DOWN, aX, aY); + } + + static UniquePtr CreateMouseMoveEvent(nscoord aX, nscoord aY) + { + return CreateMouseEvent(NS_MOUSE_MOVE, aX, aY); + } + + static UniquePtr CreateMouseReleaseEvent(nscoord aX, nscoord aY) + { + return CreateMouseEvent(NS_MOUSE_BUTTON_UP, aX, aY); + } + + static UniquePtr CreateLongTapEvent(nscoord aX, nscoord aY) + { + return CreateMouseEvent(NS_MOUSE_MOZLONGTAP, aX, aY); + } + + static UniquePtr CreateTouchEvent(uint32_t aMessage, nscoord aX, + nscoord aY) + { + auto event = MakeUnique(true, aMessage, nullptr); + int32_t identifier = 0; + LayoutDeviceIntPoint point(aX, aY); + nsIntPoint radius(19, 19); + float rotationAngle = 0; + float force = 1; + + nsRefPtr touch( + new dom::Touch(identifier, point, radius, rotationAngle, force)); + event->touches.AppendElement(touch); + + return Move(event); + } + + static UniquePtr CreateTouchPressEvent(nscoord aX, nscoord aY) + { + return CreateTouchEvent(NS_TOUCH_START, aX, aY); + } + + static UniquePtr CreateTouchMoveEvent(nscoord aX, nscoord aY) + { + return CreateTouchEvent(NS_TOUCH_MOVE, aX, aY); + } + + static UniquePtr CreateTouchReleaseEvent(nscoord aX, nscoord aY) + { + return CreateTouchEvent(NS_TOUCH_END, aX, aY); + } + + static UniquePtr CreateWheelEvent(uint32_t aMessage) + { + auto event = MakeUnique(true, aMessage, nullptr); + + return Move(event); + } + + void HandleEventAndCheckState(UniquePtr aEvent, + MockAccessibleCaretEventHub::State* aExpectedState, + nsEventStatus aExpectedEventStatus) + { + nsEventStatus rv = mHub->HandleEvent(aEvent.get()); + EXPECT_EQ(mHub->GetState(), aExpectedState); + EXPECT_EQ(rv, aExpectedEventStatus); + } + + void CheckState(MockAccessibleCaretEventHub::State* aExpectedState) + { + EXPECT_EQ(mHub->GetState(), aExpectedState); + } + + template + void TestPressReleaseOnNoCaret(PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template + void TestPressReleaseOnCaret(PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template + void TestPressMoveReleaseOnNoCaret(PressEventCreator aPressEventCreator, + MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template + void TestPressMoveReleaseOnCaret(PressEventCreator aPressEventCreator, + MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template + void TestLongTapWithSelectWordSuccessful( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template + void TestLongTapWithSelectWordFailed( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + template + void TestEventDrivenAsyncPanZoomScroll( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator); + + // Member variables + nsRefPtr mHub{new MockAccessibleCaretEventHub()}; + +}; // class AccessibleCaretEventHubTester + +TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnNoCaret) +{ + TestPressReleaseOnNoCaret(CreateMousePressEvent, CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnNoCaret) +{ + TestPressReleaseOnNoCaret(CreateTouchPressEvent, CreateTouchReleaseEvent); +} + +template +void +AccessibleCaretEventHubTester::TestPressReleaseOnNoCaret( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_)) + .WillOnce(Return(NS_ERROR_FAILURE)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret()).Times(0); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), TapCaret(_)).Times(0); + + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aReleaseEventCreator(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnCaret) +{ + TestPressReleaseOnCaret(CreateMousePressEvent, CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnCaret) +{ + TestPressReleaseOnCaret(CreateTouchPressEvent, CreateTouchReleaseEvent); +} + +template +void +AccessibleCaretEventHubTester::TestPressReleaseOnCaret( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_)) + .WillOnce(Return(NS_OK)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_)) + .Times(0); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), TapCaret(_)); + } + + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(CreateLongTapEvent(0, 0), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(aReleaseEventCreator(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eConsumeNoDefault); +} + +TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnNoCaret) +{ + TestPressMoveReleaseOnNoCaret(CreateMousePressEvent, CreateMouseMoveEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnNoCaret) +{ + TestPressMoveReleaseOnNoCaret(CreateTouchPressEvent, CreateTouchMoveEvent, + CreateTouchReleaseEvent); +} + +template +void +AccessibleCaretEventHubTester::TestPressMoveReleaseOnNoCaret( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + nscoord x0 = 0, y0 = 0; + nscoord x1 = 100, y1 = 100; + nscoord x2 = 300, y2 = 300; + nscoord x3 = 400, y3 = 400; + + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_)) + .WillOnce(Return(NS_ERROR_FAILURE)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)).Times(0); + } + + HandleEventAndCheckState(aPressEventCreator(x0, y0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + // A small move with the distance between (x0, y0) and (x1, y1) below the + // tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x1, y1), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + // A large move to simulate a dragging to select text since the distance + // between (x0, y0) and (x2, y2) is above the tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x2, y2), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aReleaseEventCreator(x3, y3), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnCaret) +{ + TestPressMoveReleaseOnCaret(CreateMousePressEvent, CreateMouseMoveEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnCaret) +{ + TestPressMoveReleaseOnCaret(CreateTouchPressEvent, CreateTouchMoveEvent, + CreateTouchReleaseEvent); +} + +template +void +AccessibleCaretEventHubTester::TestPressMoveReleaseOnCaret( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + nscoord x0 = 0, y0 = 0; + nscoord x1 = 100, y1 = 100; + nscoord x2 = 300, y2 = 300; + nscoord x3 = 400, y3 = 400; + + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_)) + .WillOnce(Return(NS_OK)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)) + .Times(2) // two valid drag operations + .WillRepeatedly(Return(NS_OK)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret()) + .WillOnce(Return(NS_OK)); + } + + HandleEventAndCheckState(aPressEventCreator(x0, y0), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + // A small move with the distance between (x0, y0) and (x1, y1) below the + // tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x1, y1), + MockAccessibleCaretEventHub::PressCaretState(), + nsEventStatus_eConsumeNoDefault); + + // A large move forms a valid drag since the distance between (x0, y0) and + // (x2, y2) is above the tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x2, y2), + MockAccessibleCaretEventHub::DragCaretState(), + nsEventStatus_eConsumeNoDefault); + + // Also a valid drag since the distance between (x0, y0) and (x3, y3) above + // the tolerance value even if the distance between (x2, y2) and (x3, y3) is + // below the tolerance value. + HandleEventAndCheckState(aMoveEventCreator(x3, y3), + MockAccessibleCaretEventHub::DragCaretState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(aReleaseEventCreator(x3, y3), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eConsumeNoDefault); +} + +TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordSuccessful) +{ + TestLongTapWithSelectWordSuccessful(CreateMousePressEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordSuccessful) +{ + TestLongTapWithSelectWordSuccessful(CreateTouchPressEvent, + CreateTouchReleaseEvent); +} + +template +void +AccessibleCaretEventHubTester::TestLongTapWithSelectWordSuccessful( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_)) + .WillOnce(Return(NS_ERROR_FAILURE)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_)) + .WillOnce(Return(NS_OK)); + } + + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(CreateLongTapEvent(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eConsumeNoDefault); + + HandleEventAndCheckState(aReleaseEventCreator(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordFailed) +{ + TestLongTapWithSelectWordFailed(CreateMousePressEvent, + CreateMouseReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordFailed) +{ + TestLongTapWithSelectWordFailed(CreateTouchPressEvent, + CreateTouchReleaseEvent); +} + +template +void +AccessibleCaretEventHubTester::TestLongTapWithSelectWordFailed( + PressEventCreator aPressEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_)) + .WillOnce(Return(NS_ERROR_FAILURE)); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_)) + .WillOnce(Return(NS_ERROR_FAILURE)); + } + + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(CreateLongTapEvent(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aReleaseEventCreator(0, 0), + MockAccessibleCaretEventHub::NoActionState(), + nsEventStatus_eIgnore); +} + +TEST_F(AccessibleCaretEventHubTester, TestTouchEventDrivenAsyncPanZoomScroll) +{ + TestEventDrivenAsyncPanZoomScroll(CreateTouchPressEvent, CreateTouchMoveEvent, + CreateTouchReleaseEvent); +} + +TEST_F(AccessibleCaretEventHubTester, TestMouseEventDrivenAsyncPanZoomScroll) +{ + TestEventDrivenAsyncPanZoomScroll(CreateMousePressEvent, CreateMouseMoveEvent, + CreateMouseReleaseEvent); +} + +template +void +AccessibleCaretEventHubTester::TestEventDrivenAsyncPanZoomScroll( + PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator, + ReleaseEventCreator aReleaseEventCreator) +{ + MockFunction check; + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_)) + .WillOnce(Return(NS_ERROR_FAILURE)); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)).Times(0); + + EXPECT_CALL(check, Call("1")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + + EXPECT_CALL(check, Call("2")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_)) + .WillOnce(Return(NS_ERROR_FAILURE)); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)).Times(0); + + EXPECT_CALL(check, Call("3")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + + EXPECT_CALL(check, Call("4")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + } + + mHub->SetUseAsyncPanZoom(true); + + // Receive press event. + HandleEventAndCheckState(aPressEventCreator(0, 0), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aMoveEventCreator(100, 100), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + check.Call("1"); + + // Event driven scroll started + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + HandleEventAndCheckState(aMoveEventCreator(160, 160), + MockAccessibleCaretEventHub::ScrollState(), + nsEventStatus_eIgnore); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + // Event driven scroll ended + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + HandleEventAndCheckState(aReleaseEventCreator(210, 210), + MockAccessibleCaretEventHub::PostScrollState(), + nsEventStatus_eIgnore); + + check.Call("2"); + + // Receive another press event. + HandleEventAndCheckState(aPressEventCreator(220, 220), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(aMoveEventCreator(230, 230), + MockAccessibleCaretEventHub::PressNoCaretState(), + nsEventStatus_eIgnore); + + check.Call("3"); + + // Another APZ scroll started + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + // Another APZ scroll ended + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + HandleEventAndCheckState(aReleaseEventCreator(310, 310), + MockAccessibleCaretEventHub::PostScrollState(), + nsEventStatus_eIgnore); + + check.Call("4"); + + // Simulate scroll end fired by timer. + MockAccessibleCaretEventHub::FireScrollEnd(nullptr, mHub); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +TEST_F(AccessibleCaretEventHubTester, TestNoEventAsyncPanZoomScroll) +{ + MockFunction check; + { + InSequence dummy; + + EXPECT_CALL(check, Call("1")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrolling()).Times(0); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), + OnScrollPositionChanged()).Times(0); + + EXPECT_CALL(check, Call("2")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + } + + mHub->SetUseAsyncPanZoom(true); + + check.Call("1"); + + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + check.Call("2"); + + // Simulate scroll end fired by timer. + MockAccessibleCaretEventHub::FireScrollEnd(nullptr, mHub); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollStartedThenBlur) +{ + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()).Times(0); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur()); + } + + mHub->SetUseAsyncPanZoom(true); + + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->NotifyBlur(true); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollEndedThenBlur) +{ + { + InSequence dummy; + + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()).Times(0); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur()); + } + + mHub->SetUseAsyncPanZoom(true); + + mHub->AsyncPanZoomStarted(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->ScrollPositionChanged(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::ScrollState()); + + mHub->AsyncPanZoomStopped(); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::PostScrollState()); + + mHub->NotifyBlur(true); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +TEST_F(AccessibleCaretEventHubTester, TestWheelEventScroll) +{ + MockFunction check; + { + InSequence dummy; + + EXPECT_CALL(check, Call("1")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart()); + + EXPECT_CALL(check, Call("2")); + EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()); + } + + check.Call("1"); + + HandleEventAndCheckState(CreateWheelEvent(NS_WHEEL_START), + MockAccessibleCaretEventHub::ScrollState(), + nsEventStatus_eIgnore); + + HandleEventAndCheckState(CreateWheelEvent(NS_WHEEL_WHEEL), + MockAccessibleCaretEventHub::ScrollState(), + nsEventStatus_eIgnore); + + mHub->ScrollPositionChanged(); + + HandleEventAndCheckState(CreateWheelEvent(NS_WHEEL_STOP), + MockAccessibleCaretEventHub::PostScrollState(), + nsEventStatus_eIgnore); + + // Momentum scroll + HandleEventAndCheckState(CreateWheelEvent(NS_WHEEL_WHEEL), + MockAccessibleCaretEventHub::PostScrollState(), + nsEventStatus_eIgnore); + + check.Call("2"); + + // Simulate scroll end fired by timer. + MockAccessibleCaretEventHub::FireScrollEnd(nullptr, mHub); + EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState()); +} + +}; // namespace mozilla diff --git a/layout/base/gtest/moz.build b/layout/base/gtest/moz.build new file mode 100644 index 0000000000..2f27721ef8 --- /dev/null +++ b/layout/base/gtest/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +UNIFIED_SOURCES += [ + 'TestAccessibleCaretEventHub.cpp' +] + +include('/ipc/chromium/chromium-config.mozbuild') + +LOCAL_INCLUDES += [ + '/docshell/base', + '/layout/base' +] + +# Workaround bug 1142396. Suppress the warning from gmock library for clang. +if CONFIG['CLANG_CXX']: + CXXFLAGS += ['-Wno-null-dereference'] + +FINAL_LIBRARY = 'xul-gtest' + +FAIL_ON_WARNINGS = True diff --git a/layout/base/moz.build b/layout/base/moz.build index 49c5e40758..d95eb5e56a 100644 --- a/layout/base/moz.build +++ b/layout/base/moz.build @@ -63,6 +63,10 @@ EXPORTS.mozilla += [ ] UNIFIED_SOURCES += [ + 'AccessibleCaret.cpp', + 'AccessibleCaretEventHub.cpp', + 'AccessibleCaretLogger.cpp', + 'AccessibleCaretManager.cpp', 'ActiveLayerTracker.cpp', 'DisplayItemClip.cpp', 'DisplayListClipState.cpp', @@ -110,6 +114,9 @@ SOURCES += [ 'nsRefreshDriver.cpp', ] +if CONFIG['ENABLE_TESTS']: + DIRS += ['gtest'] + FAIL_ON_WARNINGS = True include('/ipc/chromium/chromium-config.mozbuild') diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index 212abfbe86..b45cd88b4c 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -58,6 +58,7 @@ class nsCanvasFrame; class nsAString; class nsCaret; namespace mozilla { +class AccessibleCaretEventHub; class TouchCaret; class SelectionCarets; } // namespace mozilla @@ -807,6 +808,11 @@ public: */ virtual mozilla::dom::Element* GetSelectionCaretsEndElement() const = 0; + /** + * Get the AccessibleCaretEventHub, if it exists. AddRefs it. + */ + virtual already_AddRefed GetAccessibleCaretEventHub() const = 0; + /** * Get the caret, if it exists. AddRefs it. */ diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index dc43ba2d1e..3c85487766 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -2468,21 +2468,29 @@ nsLayoutUtils::ContainsPoint(const nsRect& aRect, const nsPoint& aPoint, bool nsLayoutUtils::IsRectVisibleInScrollFrames(nsIFrame* aFrame, const nsRect& aRect) +{ + return !ClampRectToScrollFrames(aFrame, aRect).IsEmpty(); +} + +nsRect +nsLayoutUtils::ClampRectToScrollFrames(nsIFrame* aFrame, const nsRect& aRect) { nsIFrame* closestScrollFrame = nsLayoutUtils::GetClosestFrameOfType(aFrame, nsGkAtoms::scrollFrame); + nsRect resultRect = aRect; + while (closestScrollFrame) { nsIScrollableFrame* sf = do_QueryFrame(closestScrollFrame); - nsRect scrollPortRect = sf->GetScrollPortRect(); - nsRect rectRelativeToScrollFrame = aRect; - nsLayoutUtils::TransformRect(aFrame, closestScrollFrame, - rectRelativeToScrollFrame); + nsRect scrollPortRect = sf->GetScrollPortRect(); + nsLayoutUtils::TransformRect(closestScrollFrame, aFrame, scrollPortRect); + + resultRect = resultRect.Intersect(scrollPortRect); // Check whether aRect is visible in the scroll frame or not. - if (!scrollPortRect.Intersects(rectRelativeToScrollFrame)) { - return false; + if (resultRect.IsEmpty()) { + break; } // Get next ancestor scroll frame. @@ -2491,7 +2499,7 @@ nsLayoutUtils::IsRectVisibleInScrollFrames(nsIFrame* aFrame, const nsRect& aRect nsGkAtoms::scrollFrame); } - return true; + return resultRect; } bool diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 0cc8ddf6d3..a486600e4d 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -858,6 +858,13 @@ public: static bool IsRectVisibleInScrollFrames(nsIFrame* aFrame, const nsRect& aRect); + /** + * Clamp aRect relative to aFrame to the scroll frames boundary searching from + * aFrame. + */ + static nsRect ClampRectToScrollFrames(nsIFrame* aFrame, + const nsRect& aRect); + /** * Return true if a "layer transform" could be computed for aFrame, * and optionally return the computed transform. The returned diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 44c90e408a..37feb98704 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -78,6 +78,7 @@ #include "nsIPermissionManager.h" #include "nsIMozBrowserFrame.h" #include "nsCaret.h" +#include "AccessibleCaretEventHub.h" #include "TouchCaret.h" #include "SelectionCarets.h" #include "nsIDOMHTMLDocument.h" @@ -708,6 +709,7 @@ static uint32_t sNextPresShellId; static bool sPointerEventEnabled = true; static bool sTouchCaretEnabled = false; static bool sSelectionCaretEnabled = false; +static bool sAccessibleCaretEnabled = false; static bool sBeforeAfterKeyboardEventEnabled = false; /* static */ bool @@ -732,6 +734,17 @@ PresShell::SelectionCaretPrefEnabled() return sSelectionCaretEnabled; } +/* static */ bool +PresShell::AccessibleCaretEnabled() +{ + static bool initialized = false; + if (!initialized) { + Preferences::AddBoolVarCache(&sAccessibleCaretEnabled, "layout.accessiblecaret.enabled"); + initialized = true; + } + return sAccessibleCaretEnabled; +} + /* static */ bool PresShell::BeforeAfterKeyboardEventEnabled() { @@ -892,17 +905,21 @@ PresShell::Init(nsIDocument* aDocument, // before creating any frames. SetPreferenceStyleRules(false); - if (TouchCaretPrefEnabled()) { + if (TouchCaretPrefEnabled() && !AccessibleCaretEnabled()) { // Create touch caret handle mTouchCaret = new TouchCaret(this); } - if (SelectionCaretPrefEnabled()) { + if (SelectionCaretPrefEnabled() && !AccessibleCaretEnabled()) { // Create selection caret handle mSelectionCarets = new SelectionCarets(this); mSelectionCarets->Init(); } + if (AccessibleCaretEnabled()) { + // Need to happen before nsFrameSelection has been set up. + mAccessibleCaretEventHub = new AccessibleCaretEventHub(); + } NS_ADDREF(mSelection = new nsFrameSelection()); @@ -1172,6 +1189,11 @@ PresShell::Destroy() mSelectionCarets = nullptr; } + if (mAccessibleCaretEventHub) { + mAccessibleCaretEventHub->Terminate(); + mAccessibleCaretEventHub = nullptr; + } + // release our pref style sheet, if we have one still ClearPreferenceStyleRules(); @@ -1934,6 +1956,11 @@ PresShell::Initialize(nscoord aWidth, nscoord aHeight) mFrameConstructor->EndUpdate(); } + // Initialize after nsCanvasFrame is created. + if (mAccessibleCaretEventHub) { + mAccessibleCaretEventHub->Init(this); + } + // nsAutoCauseReflowNotifier (which sets up a script blocker) going out of // scope may have killed us too NS_ENSURE_STATE(!mHaveShutDown); @@ -2231,6 +2258,12 @@ already_AddRefed PresShell::GetSelectionCarets() const return selectionCaret.forget(); } +already_AddRefed PresShell::GetAccessibleCaretEventHub() const +{ + nsRefPtr eventHub = mAccessibleCaretEventHub; + return eventHub.forget(); +} + void PresShell::SetCaret(nsCaret *aNewCaret) { mCaret = aNewCaret; @@ -7274,6 +7307,28 @@ PresShell::HandleEvent(nsIFrame* aFrame, } } + if (AccessibleCaretEnabled()) { + // We have to target the focus window because regardless of where the + // touch goes, we want to access the copy paste manager. + nsCOMPtr window = GetFocusedDOMWindowInOurWindow(); + nsCOMPtr retargetEventDoc = + window ? window->GetExtantDoc() : nullptr; + nsCOMPtr presShell = + retargetEventDoc ? retargetEventDoc->GetShell() : nullptr; + + nsRefPtr eventHub = + presShell ? presShell->GetAccessibleCaretEventHub() : nullptr; + if (eventHub) { + *aEventStatus = eventHub->HandleEvent(aEvent); + if (*aEventStatus == nsEventStatus_eConsumeNoDefault) { + // If the event is consumed, cancel APZC panning by setting + // mMultipleActionsPrevented. + aEvent->mFlags.mMultipleActionsPrevented = true; + return NS_OK; + } + } + } + if (sPointerEventEnabled) { UpdateActivePointerState(aEvent); } diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h index a2df16dcf8..8a8c01961e 100644 --- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -77,6 +77,8 @@ public: // Selection caret preference static bool SelectionCaretPrefEnabled(); + static bool AccessibleCaretEnabled(); + // BeforeAfterKeyboardEvent preference static bool BeforeAfterKeyboardEventEnabled(); @@ -240,6 +242,9 @@ public: virtual already_AddRefed GetSelectionCarets() const override; virtual mozilla::dom::Element* GetSelectionCaretsStartElement() const override; virtual mozilla::dom::Element* GetSelectionCaretsEndElement() const override; + + virtual already_AddRefed GetAccessibleCaretEventHub() const override; + // caret handling virtual already_AddRefed GetCaret() const override; NS_IMETHOD SetCaretEnabled(bool aInEnable) override; @@ -811,6 +816,7 @@ protected: // TouchCaret nsRefPtr mTouchCaret; nsRefPtr mSelectionCarets; + nsRefPtr mAccessibleCaretEventHub; // This timer controls painting suppression. Until it fires // or all frames are constructed, we won't paint anything but diff --git a/layout/base/tests/marionette/manifest.ini b/layout/base/tests/marionette/manifest.ini index bb946e9720..020dabb71f 100644 --- a/layout/base/tests/marionette/manifest.ini +++ b/layout/base/tests/marionette/manifest.ini @@ -13,4 +13,4 @@ skip = false [test_touchcaret.py] [test_selectioncarets.py] -[test_selectioncarets_multiplerange.py] +[test_selectioncarets2.py] diff --git a/layout/base/tests/marionette/test_selectioncarets.py b/layout/base/tests/marionette/test_selectioncarets.py index 0bd6113ad4..6e0850a10a 100644 --- a/layout/base/tests/marionette/test_selectioncarets.py +++ b/layout/base/tests/marionette/test_selectioncarets.py @@ -1,3 +1,4 @@ + # -*- coding: utf-8 -*- # 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 @@ -5,14 +6,18 @@ from marionette_driver.by import By from marionette_driver.marionette import Actions -from marionette_test import MarionetteTestCase +from marionette import MarionetteTestCase from marionette_driver.selection import SelectionManager from marionette_driver.gestures import long_press_without_contextmenu -from math import ceil, floor +class CommonCaretsTestCase(object): + '''Common test cases for a selection with a two carets. -class SelectionCaretsTest(MarionetteTestCase): + To run these test cases, a subclass must inherit from both this class and + MarionetteTestCase. + + ''' _long_press_time = 1 # 1 second _input_selector = (By.ID, 'input') _textarea_selector = (By.ID, 'textarea') @@ -25,15 +30,40 @@ class SelectionCaretsTest(MarionetteTestCase): def setUp(self): # Code to execute before a tests are run. - MarionetteTestCase.setUp(self) + super(CommonCaretsTestCase, self).setUp() self.actions = Actions(self.marionette) - def openTestHtml(self, enabled=True): + # The carets to be tested. + self.carets_tested_pref = None + + # The carets to be disabled in this test suite. + self.carets_disabled_pref = None + + def set_pref(self, pref_name, value): + '''Set a preference to value. + + For example: + >>> set_pref('layout.accessiblecaret.enabled', True) + + ''' + pref_name = repr(pref_name) + if isinstance(value, bool): + value = 'true' if value else 'false' + elif isinstance(value, int): + value = str(value) + else: + value = repr(value) + + script = '''SpecialPowers.pushPrefEnv({"set": [[%s, %s]]}, marionetteScriptFinished);''' % ( + pref_name, value) + + self.marionette.execute_async_script(script) + + def open_test_html(self, enabled=True): '''Open html for testing and locate elements, and enable/disable touch caret.''' - self.marionette.execute_script( - 'SpecialPowers.setBoolPref("selectioncaret.enabled", %s);' % - ('true' if enabled else 'false')) + self.set_pref(self.carets_tested_pref, enabled) + self.set_pref(self.carets_disabled_pref, False) test_html = self.marionette.absolute_url('test_selectioncarets.html') self.marionette.navigate(test_html) @@ -44,12 +74,11 @@ class SelectionCaretsTest(MarionetteTestCase): self._contenteditable = self.marionette.find_element(*self._contenteditable_selector) self._content = self.marionette.find_element(*self._content_selector) - def openTestHtml2(self, enabled=True): + def open_test_html2(self, enabled=True): '''Open html for testing and locate elements, and enable/disable touch caret.''' - self.marionette.execute_script( - 'SpecialPowers.setBoolPref("selectioncaret.enabled", %s);' % - ('true' if enabled else 'false')) + self.set_pref(self.carets_tested_pref, enabled) + self.set_pref(self.carets_disabled_pref, False) test_html2 = self.marionette.absolute_url('test_selectioncarets_multipleline.html') self.marionette.navigate(test_html2) @@ -215,11 +244,11 @@ class SelectionCaretsTest(MarionetteTestCase): tilt_left_margin_left = -17 left_caret_left_edge_x = caret3_x + caret_margin_left + tilt_left_margin_left - el.tap(ceil(left_caret_left_edge_x), caret3_y) + el.tap(left_caret_left_edge_x + 2, caret3_y) right_caret_right_edge_x = (caret4_x + caret_margin_left + tilt_right_margin_left + caret_width) - el.tap(floor(right_caret_right_edge_x), caret4_y) + el.tap(right_caret_right_edge_x - 2, caret4_y) # Drag the left caret back to the initial selection, the first word. self.actions.flick(el, caret3_x, caret3_y, caret1_x, caret1_y).perform() @@ -230,202 +259,216 @@ class SelectionCaretsTest(MarionetteTestCase): # test cases with selection carets enabled ######################################################################## def test_input_long_press_to_select_a_word(self): - self.openTestHtml(enabled=True) + self.open_test_html() self._test_long_press_to_select_a_word(self._input, self.assertEqual) def test_input_move_selection_carets(self): - self.openTestHtml(enabled=True) + self.open_test_html() self._test_move_selection_carets(self._input, self.assertEqual) def test_input_minimum_select_one_character(self): - self.openTestHtml(enabled=True) + self.open_test_html() self._test_minimum_select_one_character(self._input, self.assertEqual) def test_input_focus_obtained_by_long_press_from_textarea(self): - self.openTestHtml(enabled=True) + self.open_test_html() self._test_focus_obtained_by_long_press(self._textarea, self._input) def test_input_focus_obtained_by_long_press_from_contenteditable(self): - self.openTestHtml(enabled=True) + self.open_test_html() self._test_focus_obtained_by_long_press(self._contenteditable, self._input) def test_input_focus_obtained_by_long_press_from_content_non_editable(self): - self.openTestHtml(enabled=True) + self.open_test_html() self._test_focus_obtained_by_long_press(self._content, self._input) def test_input_handle_tilt_when_carets_overlap_to_each_other(self): - self.openTestHtml(enabled=True) + self.open_test_html() self._test_handle_tilt_when_carets_overlap_to_each_other(self._input, self.assertEqual) ######################################################################## # test cases with selection carets disabled ######################################################################## def test_input_long_press_to_select_a_word_disabled(self): - self.openTestHtml(enabled=False) + self.open_test_html(enabled=False) self._test_long_press_to_select_a_word(self._input, self.assertNotEqual) def test_input_move_selection_carets_disabled(self): - self.openTestHtml(enabled=False) + self.open_test_html(enabled=False) self._test_move_selection_carets(self._input, self.assertNotEqual) ######################################################################## #