diff --git a/dom/html/HTMLObjectElement.cpp b/dom/html/HTMLObjectElement.cpp index e0e79b69af..a0d06a8c65 100644 --- a/dom/html/HTMLObjectElement.cpp +++ b/dom/html/HTMLObjectElement.cpp @@ -193,7 +193,13 @@ HTMLObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID, nsIAtom* aName, // attributes before inserting the node into the document. if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren && aName == nsGkAtoms::data) { - return LoadObject(aNotify, true); + nsContentUtils::AddScriptRunner(NS_NewRunnableFunction( + [self = RefPtr(this), aNotify]() { + if (self->IsInComposedDoc()) { + self->LoadObject(aNotify, true); + } + })); + return NS_OK; } } diff --git a/dom/html/HTMLSharedObjectElement.cpp b/dom/html/HTMLSharedObjectElement.cpp index f0cf4c188c..d7eec215a0 100644 --- a/dom/html/HTMLSharedObjectElement.cpp +++ b/dom/html/HTMLSharedObjectElement.cpp @@ -177,8 +177,13 @@ HTMLSharedObjectElement::AfterMaybeChangeAttr(int32_t aNamespaceID, // a document, just in case that the caller wants to set additional // attributes before inserting the node into the document. if (aNotify && IsInComposedDoc() && mIsDoneAddingChildren) { - nsresult rv = LoadObject(aNotify, true); - NS_ENSURE_SUCCESS(rv, rv); + nsContentUtils::AddScriptRunner(NS_NewRunnableFunction( + [self = RefPtr(this), aNotify]() { + if (self->IsInComposedDoc()) { + self->LoadObject(aNotify, true); + } + })); + return NS_OK; } } } diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h index 9d95c7f7ab..6d9888469e 100644 --- a/js/src/jit/MacroAssembler.h +++ b/js/src/jit/MacroAssembler.h @@ -2121,6 +2121,15 @@ class MacroAssembler : public MacroAssemblerSpecific inline void assertStackAlignment(uint32_t alignment, int32_t offset = 0); }; +// StackMacroAssembler checks no GC will happen while it's on the stack. +class MOZ_RAII StackMacroAssembler : public MacroAssembler { + JS::AutoCheckCannotGC nogc; + +public: + StackMacroAssembler() : MacroAssembler() {} + explicit StackMacroAssembler(JSContext* cx) : MacroAssembler(cx) {} +}; + static inline Assembler::DoubleCondition JSOpToDoubleCondition(JSOp op) { diff --git a/js/src/moz.build b/js/src/moz.build index 9cad8e52e1..6664007adb 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -123,7 +123,7 @@ if CONFIG['JS_BUNDLED_EDITLINE']: DIRS += ['editline'] if CONFIG['JS_NEW_REGEXP']: - DIRS += ['regexp'] + DIRS += ['new-regexp'] if not CONFIG['JS_DISABLE_SHELL']: DIRS += ['shell'] diff --git a/js/src/regexp/RegExpTypes.h b/js/src/new-regexp/RegExpTypes.h similarity index 100% rename from js/src/regexp/RegExpTypes.h rename to js/src/new-regexp/RegExpTypes.h diff --git a/js/src/regexp/VERSION b/js/src/new-regexp/VERSION similarity index 100% rename from js/src/regexp/VERSION rename to js/src/new-regexp/VERSION diff --git a/js/src/regexp/gen-regexp-special-case.cc b/js/src/new-regexp/gen-regexp-special-case.cc similarity index 99% rename from js/src/regexp/gen-regexp-special-case.cc rename to js/src/new-regexp/gen-regexp-special-case.cc index b4a8c3da48..5a82c5d277 100644 --- a/js/src/regexp/gen-regexp-special-case.cc +++ b/js/src/new-regexp/gen-regexp-special-case.cc @@ -7,7 +7,7 @@ #include #include -#include "regexp/special-case.h" +#include "new-regexp/special-case.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/import-irregexp.py b/js/src/new-regexp/import-irregexp.py similarity index 100% rename from js/src/regexp/import-irregexp.py rename to js/src/new-regexp/import-irregexp.py diff --git a/js/src/regexp/moz.build b/js/src/new-regexp/moz.build similarity index 85% rename from js/src/regexp/moz.build rename to js/src/new-regexp/moz.build index 4caa4589c0..2a8fab2ef6 100644 --- a/js/src/regexp/moz.build +++ b/js/src/new-regexp/moz.build @@ -34,4 +34,9 @@ if CONFIG['ENABLE_INTL_API']: SOURCES += [ 'property-sequences.cc', 'special-case.cc' - ] \ No newline at end of file + ] + +if CONFIG['_MSC_VER']: + # This is intended as a temporary workaround to unblock compilation + # on VS2015 in warnings as errors mode. + CXXFLAGS += ['-wd4275'] \ No newline at end of file diff --git a/js/src/regexp/property-sequences.cc b/js/src/new-regexp/property-sequences.cc similarity index 99% rename from js/src/regexp/property-sequences.cc rename to js/src/new-regexp/property-sequences.cc index e07d6da531..ca1a7f2c3c 100644 --- a/js/src/regexp/property-sequences.cc +++ b/js/src/new-regexp/property-sequences.cc @@ -4,7 +4,7 @@ #ifdef V8_INTL_SUPPORT -#include "regexp/property-sequences.h" +#include "new-regexp/property-sequences.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/property-sequences.h b/js/src/new-regexp/property-sequences.h similarity index 94% rename from js/src/regexp/property-sequences.h rename to js/src/new-regexp/property-sequences.h index ed39e23795..f079da7ac6 100644 --- a/js/src/regexp/property-sequences.h +++ b/js/src/new-regexp/property-sequences.h @@ -7,7 +7,7 @@ #ifdef V8_INTL_SUPPORT -#include "regexp/regexp-shim.h" +#include "new-regexp/regexp-shim.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-ast.cc b/js/src/new-regexp/regexp-ast.cc similarity index 99% rename from js/src/regexp/regexp-ast.cc rename to js/src/new-regexp/regexp-ast.cc index 8f7dd69478..8de26720fa 100644 --- a/js/src/regexp/regexp-ast.cc +++ b/js/src/new-regexp/regexp-ast.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-ast.h" +#include "new-regexp/regexp-ast.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-ast.h b/js/src/new-regexp/regexp-ast.h similarity index 99% rename from js/src/regexp/regexp-ast.h rename to js/src/new-regexp/regexp-ast.h index 311929d0b9..32bbcf0bf9 100644 --- a/js/src/regexp/regexp-ast.h +++ b/js/src/new-regexp/regexp-ast.h @@ -5,7 +5,7 @@ #ifndef V8_REGEXP_REGEXP_AST_H_ #define V8_REGEXP_REGEXP_AST_H_ -#include "regexp/regexp-shim.h" +#include "new-regexp/regexp-shim.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-bytecode-generator-inl.h b/js/src/new-regexp/regexp-bytecode-generator-inl.h similarity index 93% rename from js/src/regexp/regexp-bytecode-generator-inl.h rename to js/src/new-regexp/regexp-bytecode-generator-inl.h index 69a054fd20..a2d1ac1cb0 100644 --- a/js/src/regexp/regexp-bytecode-generator-inl.h +++ b/js/src/new-regexp/regexp-bytecode-generator-inl.h @@ -5,9 +5,9 @@ #ifndef V8_REGEXP_REGEXP_BYTECODE_GENERATOR_INL_H_ #define V8_REGEXP_REGEXP_BYTECODE_GENERATOR_INL_H_ -#include "regexp/regexp-bytecode-generator.h" +#include "new-regexp/regexp-bytecode-generator.h" -#include "regexp/regexp-bytecodes.h" +#include "new-regexp/regexp-bytecodes.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-bytecode-generator.cc b/js/src/new-regexp/regexp-bytecode-generator.cc similarity index 97% rename from js/src/regexp/regexp-bytecode-generator.cc rename to js/src/new-regexp/regexp-bytecode-generator.cc index db151de851..2670322d37 100644 --- a/js/src/regexp/regexp-bytecode-generator.cc +++ b/js/src/new-regexp/regexp-bytecode-generator.cc @@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-bytecode-generator.h" +#include "new-regexp/regexp-bytecode-generator.h" -#include "regexp/regexp-bytecode-generator-inl.h" -#include "regexp/regexp-bytecode-peephole.h" -#include "regexp/regexp-bytecodes.h" -#include "regexp/regexp-macro-assembler.h" +#include "new-regexp/regexp-bytecode-generator-inl.h" +#include "new-regexp/regexp-bytecode-peephole.h" +#include "new-regexp/regexp-bytecodes.h" +#include "new-regexp/regexp-macro-assembler.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-bytecode-generator.h b/js/src/new-regexp/regexp-bytecode-generator.h similarity index 99% rename from js/src/regexp/regexp-bytecode-generator.h rename to js/src/new-regexp/regexp-bytecode-generator.h index f5502464d4..274fd3953d 100644 --- a/js/src/regexp/regexp-bytecode-generator.h +++ b/js/src/new-regexp/regexp-bytecode-generator.h @@ -5,7 +5,7 @@ #ifndef V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_ #define V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_ -#include "regexp/regexp-macro-assembler.h" +#include "new-regexp/regexp-macro-assembler.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-bytecode-peephole.cc b/js/src/new-regexp/regexp-bytecode-peephole.cc similarity index 99% rename from js/src/regexp/regexp-bytecode-peephole.cc rename to js/src/new-regexp/regexp-bytecode-peephole.cc index 4266b4a807..f105a50945 100644 --- a/js/src/regexp/regexp-bytecode-peephole.cc +++ b/js/src/new-regexp/regexp-bytecode-peephole.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-bytecode-peephole.h" +#include "new-regexp/regexp-bytecode-peephole.h" -#include "regexp/regexp-bytecodes.h" +#include "new-regexp/regexp-bytecodes.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-bytecode-peephole.h b/js/src/new-regexp/regexp-bytecode-peephole.h similarity index 96% rename from js/src/regexp/regexp-bytecode-peephole.h rename to js/src/new-regexp/regexp-bytecode-peephole.h index 31d5a2d480..781f0c9143 100644 --- a/js/src/regexp/regexp-bytecode-peephole.h +++ b/js/src/new-regexp/regexp-bytecode-peephole.h @@ -5,7 +5,7 @@ #ifndef V8_REGEXP_REGEXP_BYTECODE_PEEPHOLE_H_ #define V8_REGEXP_REGEXP_BYTECODE_PEEPHOLE_H_ -#include "regexp/regexp-shim.h" +#include "new-regexp/regexp-shim.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-bytecodes.cc b/js/src/new-regexp/regexp-bytecodes.cc similarity index 96% rename from js/src/regexp/regexp-bytecodes.cc rename to js/src/new-regexp/regexp-bytecodes.cc index ae8f93ac9e..679a7c06a7 100644 --- a/js/src/regexp/regexp-bytecodes.cc +++ b/js/src/new-regexp/regexp-bytecodes.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-bytecodes.h" +#include "new-regexp/regexp-bytecodes.h" #include diff --git a/js/src/regexp/regexp-bytecodes.h b/js/src/new-regexp/regexp-bytecodes.h similarity index 99% rename from js/src/regexp/regexp-bytecodes.h rename to js/src/new-regexp/regexp-bytecodes.h index 1cfef1b2d4..e5ab7cf661 100644 --- a/js/src/regexp/regexp-bytecodes.h +++ b/js/src/new-regexp/regexp-bytecodes.h @@ -5,7 +5,7 @@ #ifndef V8_REGEXP_REGEXP_BYTECODES_H_ #define V8_REGEXP_REGEXP_BYTECODES_H_ -#include "regexp/regexp-shim.h" +#include "new-regexp/regexp-shim.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-compiler-tonode.cc b/js/src/new-regexp/regexp-compiler-tonode.cc similarity index 99% rename from js/src/regexp/regexp-compiler-tonode.cc rename to js/src/new-regexp/regexp-compiler-tonode.cc index 257030589d..7de167eefe 100644 --- a/js/src/regexp/regexp-compiler-tonode.cc +++ b/js/src/new-regexp/regexp-compiler-tonode.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-compiler.h" +#include "new-regexp/regexp-compiler.h" -#include "regexp/regexp.h" +#include "new-regexp/regexp.h" #ifdef V8_INTL_SUPPORT -#include "regexp/special-case.h" +#include "new-regexp/special-case.h" #endif // V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT diff --git a/js/src/regexp/regexp-compiler.cc b/js/src/new-regexp/regexp-compiler.cc similarity index 99% rename from js/src/regexp/regexp-compiler.cc rename to js/src/new-regexp/regexp-compiler.cc index c0070061f8..98771354cf 100644 --- a/js/src/regexp/regexp-compiler.cc +++ b/js/src/new-regexp/regexp-compiler.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-compiler.h" +#include "new-regexp/regexp-compiler.h" -#include "regexp/regexp-macro-assembler-arch.h" +#include "new-regexp/regexp-macro-assembler-arch.h" #ifdef V8_INTL_SUPPORT -#include "regexp/special-case.h" +#include "new-regexp/special-case.h" #endif // V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT diff --git a/js/src/regexp/regexp-compiler.h b/js/src/new-regexp/regexp-compiler.h similarity index 99% rename from js/src/regexp/regexp-compiler.h rename to js/src/new-regexp/regexp-compiler.h index 1954f1a4c4..186d5e838c 100644 --- a/js/src/regexp/regexp-compiler.h +++ b/js/src/new-regexp/regexp-compiler.h @@ -7,7 +7,7 @@ #include -#include "regexp/regexp-nodes.h" +#include "new-regexp/regexp-nodes.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-dotprinter.cc b/js/src/new-regexp/regexp-dotprinter.cc similarity index 98% rename from js/src/regexp/regexp-dotprinter.cc rename to js/src/new-regexp/regexp-dotprinter.cc index 9bf800dfc2..2bf393c32b 100644 --- a/js/src/regexp/regexp-dotprinter.cc +++ b/js/src/new-regexp/regexp-dotprinter.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-dotprinter.h" +#include "new-regexp/regexp-dotprinter.h" -#include "regexp/regexp-compiler.h" +#include "new-regexp/regexp-compiler.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-dotprinter.h b/js/src/new-regexp/regexp-dotprinter.h similarity index 93% rename from js/src/regexp/regexp-dotprinter.h rename to js/src/new-regexp/regexp-dotprinter.h index e5781184c0..0bd03e77f4 100644 --- a/js/src/regexp/regexp-dotprinter.h +++ b/js/src/new-regexp/regexp-dotprinter.h @@ -5,7 +5,7 @@ #ifndef V8_REGEXP_REGEXP_DOTPRINTER_H_ #define V8_REGEXP_REGEXP_DOTPRINTER_H_ -#include "regexp/regexp-shim.h" +#include "new-regexp/regexp-shim.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-error.cc b/js/src/new-regexp/regexp-error.cc similarity index 93% rename from js/src/regexp/regexp-error.cc rename to js/src/new-regexp/regexp-error.cc index 3906f9d9ff..9db98d4b83 100644 --- a/js/src/regexp/regexp-error.cc +++ b/js/src/new-regexp/regexp-error.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-error.h" +#include "new-regexp/regexp-error.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-error.h b/js/src/new-regexp/regexp-error.h similarity index 100% rename from js/src/regexp/regexp-error.h rename to js/src/new-regexp/regexp-error.h diff --git a/js/src/regexp/regexp-interpreter.cc b/js/src/new-regexp/regexp-interpreter.cc similarity index 99% rename from js/src/regexp/regexp-interpreter.cc rename to js/src/new-regexp/regexp-interpreter.cc index 7735d68855..7a492fca2a 100644 --- a/js/src/regexp/regexp-interpreter.cc +++ b/js/src/new-regexp/regexp-interpreter.cc @@ -4,12 +4,12 @@ // A simple interpreter for the Irregexp byte code. -#include "regexp/regexp-interpreter.h" +#include "new-regexp/regexp-interpreter.h" -#include "regexp/regexp-bytecodes.h" -#include "regexp/regexp-macro-assembler.h" -#include "regexp/regexp-stack.h" // For kMaximumStackSize. -#include "regexp/regexp.h" +#include "new-regexp/regexp-bytecodes.h" +#include "new-regexp/regexp-macro-assembler.h" +#include "new-regexp/regexp-stack.h" // For kMaximumStackSize. +#include "new-regexp/regexp.h" #ifdef V8_INTL_SUPPORT #include "unicode/uchar.h" @@ -22,6 +22,7 @@ #define V8_USE_COMPUTED_GOTO 1 #endif // V8_HAS_COMPUTED_GOTO + namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-interpreter.h b/js/src/new-regexp/regexp-interpreter.h similarity index 98% rename from js/src/regexp/regexp-interpreter.h rename to js/src/new-regexp/regexp-interpreter.h index c3f6c119e8..b4c0da2b7b 100644 --- a/js/src/regexp/regexp-interpreter.h +++ b/js/src/new-regexp/regexp-interpreter.h @@ -7,7 +7,7 @@ #ifndef V8_REGEXP_REGEXP_INTERPRETER_H_ #define V8_REGEXP_REGEXP_INTERPRETER_H_ -#include "regexp/regexp.h" +#include "new-regexp/regexp.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-macro-assembler-arch.h b/js/src/new-regexp/regexp-macro-assembler-arch.h similarity index 98% rename from js/src/regexp/regexp-macro-assembler-arch.h rename to js/src/new-regexp/regexp-macro-assembler-arch.h index 1baa5ddd52..8aeb8c433f 100644 --- a/js/src/regexp/regexp-macro-assembler-arch.h +++ b/js/src/new-regexp/regexp-macro-assembler-arch.h @@ -16,7 +16,7 @@ #define RegexpMacroAssemblerArch_h #include "jit/MacroAssembler.h" -#include "regexp/regexp-macro-assembler.h" +#include "new-regexp/regexp-macro-assembler.h" namespace v8 { namespace internal { @@ -186,7 +186,7 @@ class SMRegExpMacroAssembler final : public NativeRegExpMacroAssembler { if (num_registers_ <= register_index) { num_registers_ = register_index + 1; } - static_assert(alignof(uintptr_t) <= alignof(FrameData)); + static_assert(alignof(uintptr_t) <= alignof(FrameData),"Regexp: Alignment of uintptr_t and FrameData mismatch"); return sizeof(FrameData) + register_index * sizeof(uintptr_t*); } diff --git a/js/src/regexp/regexp-macro-assembler-tracer.cc b/js/src/new-regexp/regexp-macro-assembler-tracer.cc similarity index 99% rename from js/src/regexp/regexp-macro-assembler-tracer.cc rename to js/src/new-regexp/regexp-macro-assembler-tracer.cc index b71a0f48e9..8eb587c3c8 100644 --- a/js/src/regexp/regexp-macro-assembler-tracer.cc +++ b/js/src/new-regexp/regexp-macro-assembler-tracer.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-macro-assembler-tracer.h" +#include "new-regexp/regexp-macro-assembler-tracer.h" namespace v8 { diff --git a/js/src/regexp/regexp-macro-assembler-tracer.h b/js/src/new-regexp/regexp-macro-assembler-tracer.h similarity index 98% rename from js/src/regexp/regexp-macro-assembler-tracer.h rename to js/src/new-regexp/regexp-macro-assembler-tracer.h index 5332e59b89..0596a18ba1 100644 --- a/js/src/regexp/regexp-macro-assembler-tracer.h +++ b/js/src/new-regexp/regexp-macro-assembler-tracer.h @@ -5,7 +5,7 @@ #ifndef V8_REGEXP_REGEXP_MACRO_ASSEMBLER_TRACER_H_ #define V8_REGEXP_REGEXP_MACRO_ASSEMBLER_TRACER_H_ -#include "regexp/regexp-macro-assembler.h" +#include "new-regexp/regexp-macro-assembler.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-macro-assembler.cc b/js/src/new-regexp/regexp-macro-assembler.cc similarity index 99% rename from js/src/regexp/regexp-macro-assembler.cc rename to js/src/new-regexp/regexp-macro-assembler.cc index 7f8de25437..52c1cb1ba3 100644 --- a/js/src/regexp/regexp-macro-assembler.cc +++ b/js/src/new-regexp/regexp-macro-assembler.cc @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-macro-assembler.h" +#include "new-regexp/regexp-macro-assembler.h" -#include "regexp/regexp-stack.h" +#include "new-regexp/regexp-stack.h" #ifdef V8_INTL_SUPPORT #include "unicode/uchar.h" diff --git a/js/src/regexp/regexp-macro-assembler.h b/js/src/new-regexp/regexp-macro-assembler.h similarity index 99% rename from js/src/regexp/regexp-macro-assembler.h rename to js/src/new-regexp/regexp-macro-assembler.h index ef3961a70a..60d712dfc3 100644 --- a/js/src/regexp/regexp-macro-assembler.h +++ b/js/src/new-regexp/regexp-macro-assembler.h @@ -5,9 +5,9 @@ #ifndef V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_ #define V8_REGEXP_REGEXP_MACRO_ASSEMBLER_H_ -#include "regexp/regexp-ast.h" -#include "regexp/regexp-shim.h" -#include "regexp/regexp.h" +#include "new-regexp/regexp-ast.h" +#include "new-regexp/regexp-shim.h" +#include "new-regexp/regexp.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-native-macro-assembler.cc b/js/src/new-regexp/regexp-native-macro-assembler.cc similarity index 97% rename from js/src/regexp/regexp-native-macro-assembler.cc rename to js/src/new-regexp/regexp-native-macro-assembler.cc index 15182ad713..01453a9374 100644 --- a/js/src/regexp/regexp-native-macro-assembler.cc +++ b/js/src/new-regexp/regexp-native-macro-assembler.cc @@ -9,12 +9,17 @@ // found in the LICENSE file. #include "jit/Linker.h" -#include "regexp/regexp-macro-assembler-arch.h" -#include "regexp/regexp-stack.h" +#include "gc/Zone.h" +#include "new-regexp/regexp-macro-assembler-arch.h" +#include "new-regexp/regexp-stack.h" #include "vm/MatchPairs.h" #include "jit/MacroAssembler-inl.h" +using namespace js; +using namespace js::irregexp; +using namespace js::jit; + namespace v8 { namespace internal { @@ -84,19 +89,9 @@ void SMRegExpMacroAssembler::AdvanceRegister(int reg, int by) { } void SMRegExpMacroAssembler::Backtrack() { - // Check for an interrupt. We have to restart from the beginning if we - // are interrupted, so we only check for urgent interrupts. - js::jit::Label noInterrupt; - masm_.branchTest32( - Assembler::Zero, AbsoluteAddress(cx_->addressOfInterruptBits()), - Imm32(uint32_t(js::InterruptReason::CallbackUrgent)), &noInterrupt); - masm_.movePtr(ImmWord(js::RegExpRunStatus_Error), temp0_); - masm_.jump(&exit_label_); - masm_.bind(&noInterrupt); - - // Pop code location from backtrack stack and jump to location. - Pop(temp0_); - masm_.jump(temp0_); + // Pop code location from backtrack stack and jump to location. + Pop(temp0_); + masm_.jump(temp0_); } void SMRegExpMacroAssembler::Bind(Label* label) { @@ -546,7 +541,8 @@ bool SMRegExpMacroAssembler::CheckSpecialCharacterClass(uc16 type, masm_.branch32(Assembler::Above, current_character_, Imm32('z'), no_match); } - static_assert(arraysize(word_character_map) > unibrow::Latin1::kMaxChar); + static_assert(arraysize(word_character_map) > unibrow::Latin1::kMaxChar, + "regex: arraysize(word_character_map) > unibrow::Latin1::kMaxChar"); masm_.movePtr(ImmPtr(word_character_map), temp0_); masm_.load8ZeroExtend( BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_); @@ -558,7 +554,8 @@ bool SMRegExpMacroAssembler::CheckSpecialCharacterClass(uc16 type, if (mode_ != LATIN1) { masm_.branch32(Assembler::Above, current_character_, Imm32('z'), &done); } - static_assert(arraysize(word_character_map) > unibrow::Latin1::kMaxChar); + static_assert(arraysize(word_character_map) > unibrow::Latin1::kMaxChar, + "regex: arraysize(word_character_map) > unibrow::Latin1::kMaxChar"); masm_.movePtr(ImmPtr(word_character_map), temp0_); masm_.load8ZeroExtend( BaseIndex(temp0_, current_character_, js::jit::TimesOne), temp0_); @@ -824,7 +821,7 @@ static Handle DummyCode() { // Finalize code. This is called last, so that we know how many // registers we need. Handle SMRegExpMacroAssembler::GetCode(Handle source) { - if (!cx_->realm()->ensureJitRealmExists(cx_)) { + if (!cx_->compartment()->ensureJitCompartmentExists(cx_)) { return DummyCode(); } @@ -841,8 +838,9 @@ Handle SMRegExpMacroAssembler::GetCode(Handle source) { stackOverflowHandler(); Linker linker(masm_); - JitCode* code = linker.newCode(cx_, js::jit::CodeKind::RegExp); + JitCode* code = linker.newCode(cx_, REGEXP_CODE); if (!code) { + ReportOutOfMemory(cx_); return DummyCode(); } @@ -1161,7 +1159,7 @@ SMRegExpMacroAssembler::Implementation() { /*static */ uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareStrings( const char16_t* substring1, const char16_t* substring2, size_t byteLength) { - js::AutoUnsafeCallWithABI unsafe; + JS::AutoCheckCannotGC nogc; MOZ_ASSERT(byteLength % sizeof(char16_t) == 0); size_t length = byteLength / sizeof(char16_t); @@ -1184,7 +1182,7 @@ uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareStrings( /*static */ uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareUCStrings( const char16_t* substring1, const char16_t* substring2, size_t byteLength) { - js::AutoUnsafeCallWithABI unsafe; + JS::AutoCheckCannotGC nogc; MOZ_ASSERT(byteLength % sizeof(char16_t) == 0); size_t length = byteLength / sizeof(char16_t); @@ -1206,7 +1204,7 @@ uint32_t SMRegExpMacroAssembler::CaseInsensitiveCompareUCStrings( /* static */ bool SMRegExpMacroAssembler::GrowBacktrackStack(RegExpStack* regexp_stack) { - js::AutoUnsafeCallWithABI unsafe; + JS::AutoCheckCannotGC nogc; size_t size = regexp_stack->stack_capacity(); return !!regexp_stack->EnsureCapacity(size * 2); } diff --git a/js/src/regexp/regexp-nodes.h b/js/src/new-regexp/regexp-nodes.h similarity index 99% rename from js/src/regexp/regexp-nodes.h rename to js/src/new-regexp/regexp-nodes.h index 50c843c20c..099687c25e 100644 --- a/js/src/regexp/regexp-nodes.h +++ b/js/src/new-regexp/regexp-nodes.h @@ -5,7 +5,7 @@ #ifndef V8_REGEXP_REGEXP_NODES_H_ #define V8_REGEXP_REGEXP_NODES_H_ -#include "regexp/regexp-macro-assembler.h" +#include "new-regexp/regexp-macro-assembler.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp-parser.cc b/js/src/new-regexp/regexp-parser.cc similarity index 99% rename from js/src/regexp/regexp-parser.cc rename to js/src/new-regexp/regexp-parser.cc index e2bbb6ed03..a26e354389 100644 --- a/js/src/regexp/regexp-parser.cc +++ b/js/src/new-regexp/regexp-parser.cc @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-parser.h" +#include "new-regexp/regexp-parser.h" #include -#include "regexp/property-sequences.h" -#include "regexp/regexp-macro-assembler.h" -#include "regexp/regexp.h" +#include "new-regexp/property-sequences.h" +#include "new-regexp/regexp-macro-assembler.h" +#include "new-regexp/regexp.h" #ifdef V8_INTL_SUPPORT #include "unicode/uniset.h" diff --git a/js/src/regexp/regexp-parser.h b/js/src/new-regexp/regexp-parser.h similarity index 98% rename from js/src/regexp/regexp-parser.h rename to js/src/new-regexp/regexp-parser.h index 131d12161f..1b2a9fe18c 100644 --- a/js/src/regexp/regexp-parser.h +++ b/js/src/new-regexp/regexp-parser.h @@ -5,8 +5,8 @@ #ifndef V8_REGEXP_REGEXP_PARSER_H_ #define V8_REGEXP_REGEXP_PARSER_H_ -#include "regexp/regexp-ast.h" -#include "regexp/regexp-error.h" +#include "new-regexp/regexp-ast.h" +#include "new-regexp/regexp-error.h" namespace v8 { namespace internal { @@ -327,7 +327,9 @@ class V8_EXPORT_PRIVATE RegExpParser { bool operator()(const RegExpCapture* lhs, const RegExpCapture* rhs) const { DCHECK_NOT_NULL(lhs); DCHECK_NOT_NULL(rhs); - return *lhs->name() < *rhs->name(); + ZoneVector lhname = *lhs->name(); + ZoneVector rhname = *rhs->name(); + return lhname < rhname; } }; diff --git a/js/src/regexp/regexp-shim.cc b/js/src/new-regexp/regexp-shim.cc similarity index 98% rename from js/src/regexp/regexp-shim.cc rename to js/src/new-regexp/regexp-shim.cc index 3f3fa40eb0..51a9e2d83b 100644 --- a/js/src/regexp/regexp-shim.cc +++ b/js/src/new-regexp/regexp-shim.cc @@ -10,8 +10,10 @@ #include -#include "regexp/regexp-shim.h" -#include "regexp/regexp-stack.h" +#include "new-regexp/regexp-shim.h" +#include "new-regexp/regexp-stack.h" + +#include "mozilla/Sprintf.h" // for SprintfLiteral namespace v8 { namespace internal { @@ -125,8 +127,6 @@ PseudoHandle ByteArray::takeOwnership(Isolate* isolate) { } void Isolate::trace(JSTracer* trc) { - js::gc::AssertRootMarkingPhase(trc); - for (auto iter = handleArena_.Iter(); !iter.Done(); iter.Next()) { auto& elem = iter.Get(); JS::GCPolicy::trace(trc, &elem, "Isolate handle arena"); diff --git a/js/src/regexp/regexp-shim.h b/js/src/new-regexp/regexp-shim.h similarity index 99% rename from js/src/regexp/regexp-shim.h rename to js/src/new-regexp/regexp-shim.h index 7677da084b..c49c25ff13 100644 --- a/js/src/regexp/regexp-shim.h +++ b/js/src/new-regexp/regexp-shim.h @@ -20,14 +20,15 @@ #include #include +#include // needed for gcc 10 #include "jit/Label.h" #include "jit/shared/Assembler-shared.h" #include "js/Value.h" -#include "regexp/RegExpTypes.h" -#include "regexp/util/flags.h" -#include "regexp/util/vector.h" -#include "regexp/util/zone.h" +#include "new-regexp/RegExpTypes.h" +#include "new-regexp/util/flags.h" +#include "new-regexp/util/vector.h" +#include "new-regexp/util/zone.h" #include "vm/NativeObject.h" // Forward declaration of classes @@ -1172,7 +1173,6 @@ extern bool FLAG_trace_regexp_bytecodes; extern bool FLAG_trace_regexp_parser; extern bool FLAG_trace_regexp_peephole_optimization; -#define V8_USE_COMPUTED_GOTO 1 #define COMPILING_IRREGEXP_FOR_EXTERNAL_EMBEDDER } // namespace internal diff --git a/js/src/regexp/regexp-stack.cc b/js/src/new-regexp/regexp-stack.cc similarity index 98% rename from js/src/regexp/regexp-stack.cc rename to js/src/new-regexp/regexp-stack.cc index b8819e48b6..c8944541c7 100644 --- a/js/src/regexp/regexp-stack.cc +++ b/js/src/new-regexp/regexp-stack.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "regexp/regexp-stack.h" +#include "new-regexp/regexp-stack.h" namespace v8 { diff --git a/js/src/regexp/regexp-stack.h b/js/src/new-regexp/regexp-stack.h similarity index 99% rename from js/src/regexp/regexp-stack.h rename to js/src/new-regexp/regexp-stack.h index 0b452c0059..e32d0ed1f5 100644 --- a/js/src/regexp/regexp-stack.h +++ b/js/src/new-regexp/regexp-stack.h @@ -5,7 +5,7 @@ #ifndef V8_REGEXP_REGEXP_STACK_H_ #define V8_REGEXP_REGEXP_STACK_H_ -#include "regexp/regexp-shim.h" +#include "new-regexp/regexp-shim.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/regexp.h b/js/src/new-regexp/regexp.h similarity index 99% rename from js/src/regexp/regexp.h rename to js/src/new-regexp/regexp.h index a36662b78a..f1e403bf03 100644 --- a/js/src/regexp/regexp.h +++ b/js/src/new-regexp/regexp.h @@ -5,8 +5,8 @@ #ifndef V8_REGEXP_REGEXP_H_ #define V8_REGEXP_REGEXP_H_ -#include "regexp/regexp-error.h" -#include "regexp/regexp-shim.h" +#include "new-regexp/regexp-error.h" +#include "new-regexp/regexp-shim.h" namespace v8 { namespace internal { diff --git a/js/src/regexp/special-case.cc b/js/src/new-regexp/special-case.cc similarity index 98% rename from js/src/regexp/special-case.cc rename to js/src/new-regexp/special-case.cc index 6b12d28d7d..d767b94c20 100644 --- a/js/src/regexp/special-case.cc +++ b/js/src/new-regexp/special-case.cc @@ -11,7 +11,7 @@ // Semantics: Canonicalize) step 3. #ifdef V8_INTL_SUPPORT -#include "regexp/special-case.h" +#include "new-regexp/special-case.h" #include "unicode/uniset.h" namespace v8 { diff --git a/js/src/regexp/special-case.h b/js/src/new-regexp/special-case.h similarity index 99% rename from js/src/regexp/special-case.h rename to js/src/new-regexp/special-case.h index 3aca983028..31dfd78582 100644 --- a/js/src/regexp/special-case.h +++ b/js/src/new-regexp/special-case.h @@ -6,7 +6,7 @@ #define V8_REGEXP_SPECIAL_CASE_H_ #ifdef V8_INTL_SUPPORT -#include "regexp/regexp-shim.h" +#include "new-regexp/regexp-shim.h" #include "unicode/uchar.h" #include "unicode/uniset.h" diff --git a/js/src/regexp/util/flags.h b/js/src/new-regexp/util/flags.h similarity index 100% rename from js/src/regexp/util/flags.h rename to js/src/new-regexp/util/flags.h diff --git a/js/src/regexp/util/unicode.cc b/js/src/new-regexp/util/unicode.cc similarity index 99% rename from js/src/regexp/util/unicode.cc rename to js/src/new-regexp/util/unicode.cc index da8cef4445..ba9ea607cc 100644 --- a/js/src/regexp/util/unicode.cc +++ b/js/src/new-regexp/util/unicode.cc @@ -5,7 +5,7 @@ // This file is a subset of: // https://github.com/v8/v8/blob/master/src/strings/unicode.cc -#include "regexp/regexp-shim.h" +#include "new-regexp/regexp-shim.h" #ifdef V8_INTL_SUPPORT #include "unicode/uchar.h" diff --git a/js/src/regexp/util/vector.h b/js/src/new-regexp/util/vector.h similarity index 97% rename from js/src/regexp/util/vector.h rename to js/src/new-regexp/util/vector.h index 2419447d67..435318ce71 100644 --- a/js/src/regexp/util/vector.h +++ b/js/src/new-regexp/util/vector.h @@ -45,9 +45,9 @@ void DeleteArray(T* array) { template class Vector { public: - constexpr Vector() : start_(nullptr), length_(0) {} + Vector() : start_(nullptr), length_(0) {} - constexpr Vector(T* data, size_t length) : start_(data), length_(length) { + Vector(T* data, size_t length) : start_(data), length_(length) { MOZ_ASSERT_IF(length != 0, data != nullptr); } diff --git a/js/src/regexp/util/zone.h b/js/src/new-regexp/util/zone.h similarity index 99% rename from js/src/regexp/util/zone.h rename to js/src/new-regexp/util/zone.h index 5a963dd562..7183f77b70 100644 --- a/js/src/regexp/util/zone.h +++ b/js/src/new-regexp/util/zone.h @@ -13,7 +13,7 @@ #include "ds/LifoAlloc.h" #include "ds/Sort.h" -#include "regexp/util/vector.h" +#include "new-regexp/util/vector.h" namespace v8 { namespace internal { diff --git a/netwerk/cache2/CacheIndex.cpp b/netwerk/cache2/CacheIndex.cpp index 2c6451d72d..0c46647c63 100644 --- a/netwerk/cache2/CacheIndex.cpp +++ b/netwerk/cache2/CacheIndex.cpp @@ -41,14 +41,17 @@ namespace { class FrecencyComparator { public: - bool Equals(CacheIndexRecord* a, CacheIndexRecord* b) const { + bool Equals(const RefPtr& a, + const RefPtr& b) const { if (!a || !b) { return false; } - return a->mFrecency == b->mFrecency; + return a->Get()->mFrecency == b->Get()->mFrecency; } - bool LessThan(CacheIndexRecord* a, CacheIndexRecord* b) const { + + bool LessThan(const RefPtr& a, + const RefPtr& b) const { // Removed (=null) entries must be at the end of the array. if (!a) { return false; @@ -58,14 +61,14 @@ public: } // Place entries with frecency 0 at the end of the non-removed entries. - if (a->mFrecency == 0) { + if (a->Get()->mFrecency == 0) { return false; } - if (b->mFrecency == 0) { + if (b->Get()->mFrecency == 0) { return true; } - return a->mFrecency < b->mFrecency; + return a->Get()->mFrecency < b->Get()->mFrecency; } }; @@ -75,31 +78,28 @@ public: * This helper class is responsible for keeping CacheIndex::mIndexStats and * CacheIndex::mFrecencyArray up to date. */ -class CacheIndexEntryAutoManage +class MOZ_RAII CacheIndexEntryAutoManage { public: - CacheIndexEntryAutoManage(const SHA1Sum::Hash *aHash, CacheIndex *aIndex) + CacheIndexEntryAutoManage(const SHA1Sum::Hash *aHash, CacheIndex *aIndex, + const StaticMutexAutoLock& aProofOfLock) : mIndex(aIndex) - , mOldRecord(nullptr) , mOldFrecency(0) , mDoNotSearchInIndex(false) , mDoNotSearchInUpdates(false) + , mProofOfLock(aProofOfLock) { - CacheIndex::sLock.AssertCurrentThreadOwns(); - mHash = aHash; const CacheIndexEntry *entry = FindEntry(); mIndex->mIndexStats.BeforeChange(entry); if (entry && entry->IsInitialized() && !entry->IsRemoved()) { mOldRecord = entry->mRec; - mOldFrecency = entry->mRec->mFrecency; + mOldFrecency = entry->mRec->Get()->mFrecency; } } ~CacheIndexEntryAutoManage() { - CacheIndex::sLock.AssertCurrentThreadOwns(); - const CacheIndexEntry *entry = FindEntry(); mIndex->mIndexStats.AfterChange(entry); if (!entry || !entry->IsInitialized() || entry->IsRemoved()) { @@ -107,28 +107,28 @@ public: } if (entry && !mOldRecord) { - mIndex->mFrecencyArray.AppendRecord(entry->mRec); - mIndex->AddRecordToIterators(entry->mRec); + mIndex->mFrecencyArray.AppendRecord(entry->mRec, mProofOfLock); + mIndex->AddRecordToIterators(entry->mRec, mProofOfLock); } else if (!entry && mOldRecord) { - mIndex->mFrecencyArray.RemoveRecord(mOldRecord); - mIndex->RemoveRecordFromIterators(mOldRecord); + mIndex->mFrecencyArray.RemoveRecord(mOldRecord, mProofOfLock); + mIndex->RemoveRecordFromIterators(mOldRecord, mProofOfLock); } else if (entry && mOldRecord) { if (entry->mRec != mOldRecord) { // record has a different address, we have to replace it - mIndex->ReplaceRecordInIterators(mOldRecord, entry->mRec); + mIndex->ReplaceRecordInIterators(mOldRecord, entry->mRec, mProofOfLock); - if (entry->mRec->mFrecency == mOldFrecency) { + if (entry->mRec->Get()->mFrecency == mOldFrecency) { // If frecency hasn't changed simply replace the pointer - mIndex->mFrecencyArray.ReplaceRecord(mOldRecord, entry->mRec); + mIndex->mFrecencyArray.ReplaceRecord(mOldRecord, entry->mRec, mProofOfLock); } else { // Remove old pointer and insert the new one at the end of the array - mIndex->mFrecencyArray.RemoveRecord(mOldRecord); - mIndex->mFrecencyArray.AppendRecord(entry->mRec); + mIndex->mFrecencyArray.RemoveRecord(mOldRecord, mProofOfLock); + mIndex->mFrecencyArray.AppendRecord(entry->mRec, mProofOfLock); } - } else if (entry->mRec->mFrecency != mOldFrecency) { + } else if (entry->mRec->Get()->mFrecency != mOldFrecency) { // Move the element at the end of the array - mIndex->mFrecencyArray.RemoveRecord(entry->mRec); - mIndex->mFrecencyArray.AppendRecord(entry->mRec); + mIndex->mFrecencyArray.RemoveRecord(entry->mRec, mProofOfLock); + mIndex->mFrecencyArray.AppendRecord(entry->mRec, mProofOfLock); } } else { // both entries were removed or not initialized, do nothing @@ -169,12 +169,13 @@ private: return entry; } - const SHA1Sum::Hash *mHash; + const SHA1Sum::Hash* mHash; RefPtr mIndex; - CacheIndexRecord *mOldRecord; - uint32_t mOldFrecency; - bool mDoNotSearchInIndex; - bool mDoNotSearchInUpdates; + RefPtr mOldRecord; + uint32_t mOldFrecency; + bool mDoNotSearchInIndex; + bool mDoNotSearchInUpdates; + const StaticMutexAutoLock& mProofOfLock; }; class FileOpenHelper : public CacheFileIOListener @@ -236,7 +237,7 @@ NS_IMETHODIMP FileOpenHelper::OnFileOpened(CacheFileHandle *aHandle, return NS_OK; } - mIndex->OnFileOpenedInternal(this, aHandle, aResult); + mIndex->OnFileOpenedInternal(this, aHandle, aResult, lock); return NS_OK; } @@ -306,7 +307,7 @@ CacheIndex::Init(nsIFile *aCacheDirectory) RefPtr idx = new CacheIndex(); - nsresult rv = idx->InitInternal(aCacheDirectory); + nsresult rv = idx->InitInternal(aCacheDirectory, lock); NS_ENSURE_SUCCESS(rv, rv); gInstance = idx.forget(); @@ -314,7 +315,8 @@ CacheIndex::Init(nsIFile *aCacheDirectory) } nsresult -CacheIndex::InitInternal(nsIFile *aCacheDirectory) +CacheIndex::InitInternal(nsIFile *aCacheDirectory, + const StaticMutexAutoLock& aProofOfLock) { nsresult rv; @@ -323,7 +325,7 @@ CacheIndex::InitInternal(nsIFile *aCacheDirectory) mStartTime = TimeStamp::NowLoRes(); - ReadIndexFromDisk(); + ReadIndexFromDisk(aProofOfLock); return NS_OK; } @@ -402,17 +404,17 @@ CacheIndex::PreShutdownInternal() switch (mState) { case WRITING: - FinishWrite(false); + FinishWrite(false, lock); break; case READY: // nothing to do, write the journal in Shutdown() break; case READING: - FinishRead(false); + FinishRead(false, lock); break; case BUILDING: case UPDATING: - FinishUpdate(false); + FinishUpdate(false, lock); break; default: MOZ_ASSERT(false, "Implement me!"); @@ -447,7 +449,7 @@ CacheIndex::Shutdown() MOZ_ASSERT(index->mShuttingDown); EState oldState = index->mState; - index->ChangeState(SHUTDOWN); + index->ChangeState(SHUTDOWN, lock); if (oldState != READY) { LOG(("CacheIndex::Shutdown() - Unexpected state. Did posting of " @@ -456,7 +458,7 @@ CacheIndex::Shutdown() switch (oldState) { case WRITING: - index->FinishWrite(false); + index->FinishWrite(false, lock); MOZ_FALLTHROUGH; case READY: if (index->mIndexOnDiskIsValid && !index->mDontMarkIndexClean) { @@ -468,11 +470,11 @@ CacheIndex::Shutdown() } break; case READING: - index->FinishRead(false); + index->FinishRead(false, lock); break; case BUILDING: case UPDATING: - index->FinishUpdate(false); + index->FinishUpdate(false, lock); break; default: MOZ_ASSERT(false, "Unexpected state!"); @@ -512,7 +514,7 @@ CacheIndex::AddEntry(const SHA1Sum::Hash *aHash) bool updateIfNonFreshEntriesExist = false; { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); bool entryRemoved = entry && entry->IsRemoved(); @@ -593,8 +595,8 @@ CacheIndex::AddEntry(const SHA1Sum::Hash *aHash) index->mIndexNeedsUpdate = true; } - index->StartUpdatingIndexIfNeeded(); - index->WriteIndexToDiskIfNeeded(); + index->StartUpdatingIndexIfNeeded(lock); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -621,7 +623,7 @@ CacheIndex::EnsureEntryExists(const SHA1Sum::Hash *aHash) } { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); bool entryRemoved = entry && entry->IsRemoved(); @@ -699,8 +701,8 @@ CacheIndex::EnsureEntryExists(const SHA1Sum::Hash *aHash) } } - index->StartUpdatingIndexIfNeeded(); - index->WriteIndexToDiskIfNeeded(); + index->StartUpdatingIndexIfNeeded(lock); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -731,7 +733,7 @@ CacheIndex::InitEntry(const SHA1Sum::Hash *aHash, } { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); CacheIndexEntryUpdate *updated = nullptr; @@ -812,8 +814,8 @@ CacheIndex::InitEntry(const SHA1Sum::Hash *aHash, } } - index->StartUpdatingIndexIfNeeded(); - index->WriteIndexToDiskIfNeeded(); + index->StartUpdatingIndexIfNeeded(lock); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -840,7 +842,7 @@ CacheIndex::RemoveEntry(const SHA1Sum::Hash *aHash) } { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); bool entryRemoved = entry && entry->IsRemoved(); @@ -907,8 +909,8 @@ CacheIndex::RemoveEntry(const SHA1Sum::Hash *aHash) } } - index->StartUpdatingIndexIfNeeded(); - index->WriteIndexToDiskIfNeeded(); + index->StartUpdatingIndexIfNeeded(lock); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -941,7 +943,7 @@ CacheIndex::UpdateEntry(const SHA1Sum::Hash *aHash, } { - CacheIndexEntryAutoManage entryMng(aHash, index); + CacheIndexEntryAutoManage entryMng(aHash, index, lock); CacheIndexEntry *entry = index->mIndex.GetEntry(*aHash); @@ -1012,7 +1014,7 @@ CacheIndex::UpdateEntry(const SHA1Sum::Hash *aHash, } } - index->WriteIndexToDiskIfNeeded(); + index->WriteIndexToDiskIfNeeded(lock); return NS_OK; } @@ -1061,17 +1063,17 @@ CacheIndex::RemoveAll() switch (index->mState) { case WRITING: - index->FinishWrite(false); + index->FinishWrite(false, lock); break; case READY: // nothing to do break; case READING: - index->FinishRead(false); + index->FinishRead(false, lock); break; case BUILDING: case UPDATING: - index->FinishUpdate(false); + index->FinishUpdate(false, lock); break; default: MOZ_ASSERT(false, "Unexpected state!"); @@ -1088,7 +1090,7 @@ CacheIndex::RemoveAll() index->mIndexNeedsUpdate = false; index->mIndexStats.Clear(); - index->mFrecencyArray.Clear(); + index->mFrecencyArray.Clear(lock); index->mIndex.Clear(); for (uint32_t i = 0; i < index->mIterators.Length(); ) { @@ -1213,10 +1215,10 @@ CacheIndex::GetEntryForEviction(bool aIgnoreEmptyEntries, SHA1Sum::Hash *aHash, uint32_t skipped = 0; // find first non-forced valid and unpinned entry with the lowest frecency - index->mFrecencyArray.SortIfNeeded(); + index->mFrecencyArray.SortIfNeeded(lock); for (auto iter = index->mFrecencyArray.Iter(); !iter.Done(); iter.Next()) { - CacheIndexRecord *rec = iter.Get(); + CacheIndexRecord *rec = iter.Get()->Get(); memcpy(&hash, rec->mHash, sizeof(SHA1Sum::Hash)); @@ -1318,11 +1320,10 @@ CacheIndex::GetCacheStats(nsILoadContextInfo *aInfo, uint32_t *aSize, uint32_t * *aCount = 0; for (auto iter = index->mFrecencyArray.Iter(); !iter.Done(); iter.Next()) { - CacheIndexRecord *record = iter.Get(); - if (!CacheIndexEntry::RecordMatchesLoadContextInfo(record, aInfo)) + if (aInfo && !CacheIndexEntry::RecordMatchesLoadContextInfo(iter.Get(), aInfo)) continue; - *aSize += CacheIndexEntry::GetFileSize(record); + *aSize += CacheIndexEntry::GetFileSize(iter.Get()->Get()); ++*aCount; } @@ -1374,7 +1375,7 @@ CacheIndex::AsyncGetDiskConsumption(nsICacheStorageConsumptionObserver* aObserve RefPtr index = gInstance; if (index && index->mUpdateTimer) { index->mUpdateTimer->Cancel(); - index->DelayedUpdateLocked(); + index->DelayedUpdateLocked(lock); } }), CacheIOThread::INDEX); } @@ -1408,10 +1409,10 @@ CacheIndex::GetIterator(nsILoadContextInfo *aInfo, bool aAddNew, idxIter = new CacheIndexIterator(index, aAddNew); } - index->mFrecencyArray.SortIfNeeded(); + index->mFrecencyArray.SortIfNeeded(lock); for (auto iter = index->mFrecencyArray.Iter(); !iter.Done(); iter.Next()) { - idxIter->AddRecord(iter.Get()); + idxIter->AddRecord(iter.Get(), lock); } index->mIterators.AppendElement(idxIter); @@ -1512,12 +1513,10 @@ CacheIndex::HasEntryChanged(CacheIndexEntry *aEntry, } void -CacheIndex::ProcessPendingOperations() +CacheIndex::ProcessPendingOperations(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ProcessPendingOperations()")); - sLock.AssertCurrentThreadOwns(); - for (auto iter = mPendingUpdates.Iter(); !iter.Done(); iter.Next()) { CacheIndexEntryUpdate* update = iter.Get(); @@ -1529,7 +1528,7 @@ CacheIndex::ProcessPendingOperations() CacheIndexEntry* entry = mIndex.GetEntry(*update->Hash()); { - CacheIndexEntryAutoManage emng(update->Hash(), this); + CacheIndexEntryAutoManage emng(update->Hash(), this, aProofOfLock); emng.DoNotSearchInUpdates(); if (update->IsRemoved()) { @@ -1571,7 +1570,7 @@ CacheIndex::ProcessPendingOperations() } bool -CacheIndex::WriteIndexToDiskIfNeeded() +CacheIndex::WriteIndexToDiskIfNeeded(const StaticMutexAutoLock& aProofOfLock) { if (mState != READY || mShuttingDown || mRWPending) { return false; @@ -1587,25 +1586,24 @@ CacheIndex::WriteIndexToDiskIfNeeded() return false; } - WriteIndexToDisk(); + WriteIndexToDisk(aProofOfLock); return true; } void -CacheIndex::WriteIndexToDisk() +CacheIndex::WriteIndexToDisk(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::WriteIndexToDisk()")); mIndexStats.Log(); nsresult rv; - sLock.AssertCurrentThreadOwns(); MOZ_ASSERT(mState == READY); MOZ_ASSERT(!mRWBuf); MOZ_ASSERT(!mRWHash); MOZ_ASSERT(!mRWPending); - ChangeState(WRITING); + ChangeState(WRITING, aProofOfLock); mProcessEntries = mIndexStats.ActiveEntriesCount(); @@ -1616,7 +1614,7 @@ CacheIndex::WriteIndexToDisk() mIndexFileOpener); if (NS_FAILED(rv)) { LOG(("CacheIndex::WriteIndexToDisk() - Can't open file [rv=0x%08x]", rv)); - FinishWrite(false); + FinishWrite(false, aProofOfLock); return; } @@ -1641,13 +1639,12 @@ CacheIndex::WriteIndexToDisk() } void -CacheIndex::WriteRecords() +CacheIndex::WriteRecords(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::WriteRecords()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); MOZ_ASSERT(mState == WRITING); MOZ_ASSERT(!mRWPending); @@ -1725,7 +1722,7 @@ CacheIndex::WriteRecords() if (NS_FAILED(rv)) { LOG(("CacheIndex::WriteRecords() - CacheFileIOManager::Write() failed " "synchronously [rv=0x%08x]", rv)); - FinishWrite(false); + FinishWrite(false, aProofOfLock); } else { mRWPending = true; } @@ -1734,14 +1731,12 @@ CacheIndex::WriteRecords() } void -CacheIndex::FinishWrite(bool aSucceeded) +CacheIndex::FinishWrite(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FinishWrite() [succeeded=%d]", aSucceeded)); MOZ_ASSERT((!aSucceeded && mState == SHUTDOWN) || mState == WRITING); - sLock.AssertCurrentThreadOwns(); - // If there is write operation pending we must be cancelling writing of the // index when shutting down or removing the whole index. MOZ_ASSERT(!mRWPending || (!aSucceeded && (mShuttingDown || mRemovingAll))); @@ -1759,7 +1754,7 @@ CacheIndex::FinishWrite(bool aSucceeded) bool remove = false; { - CacheIndexEntryAutoManage emng(entry->Hash(), this); + CacheIndexEntryAutoManage emng(entry->Hash(), this, aProofOfLock); if (entry->IsRemoved()) { emng.DoNotSearchInIndex(); @@ -1784,11 +1779,11 @@ CacheIndex::FinishWrite(bool aSucceeded) } } - ProcessPendingOperations(); + ProcessPendingOperations(aProofOfLock); mIndexStats.Log(); if (mState == WRITING) { - ChangeState(READY); + ChangeState(READY, aProofOfLock); mLastDumpTime = TimeStamp::NowLoRes(); } } @@ -2011,16 +2006,15 @@ CacheIndex::WriteLogToDisk() } void -CacheIndex::ReadIndexFromDisk() +CacheIndex::ReadIndexFromDisk(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ReadIndexFromDisk()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); MOZ_ASSERT(mState == INITIAL); - ChangeState(READING); + ChangeState(READING, aProofOfLock); mIndexFileOpener = new FileOpenHelper(this); rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(INDEX_NAME), @@ -2030,7 +2024,7 @@ CacheIndex::ReadIndexFromDisk() if (NS_FAILED(rv)) { LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() " "failed [rv=0x%08x, file=%s]", rv, INDEX_NAME)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2042,7 +2036,7 @@ CacheIndex::ReadIndexFromDisk() if (NS_FAILED(rv)) { LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() " "failed [rv=0x%08x, file=%s]", rv, JOURNAL_NAME)); - FinishRead(false); + FinishRead(false, aProofOfLock); } mTmpFileOpener = new FileOpenHelper(this); @@ -2053,19 +2047,17 @@ CacheIndex::ReadIndexFromDisk() if (NS_FAILED(rv)) { LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() " "failed [rv=0x%08x, file=%s]", rv, TEMP_INDEX_NAME)); - FinishRead(false); + FinishRead(false, aProofOfLock); } } void -CacheIndex::StartReadingIndex() +CacheIndex::StartReadingIndex(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::StartReadingIndex()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(mIndexHandle); MOZ_ASSERT(mState == READING); MOZ_ASSERT(!mIndexOnDiskIsValid); @@ -2079,7 +2071,7 @@ CacheIndex::StartReadingIndex() if (entriesSize < 0 || entriesSize % sizeof(CacheIndexRecord)) { LOG(("CacheIndex::StartReadingIndex() - Index is corrupted")); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2094,21 +2086,19 @@ CacheIndex::StartReadingIndex() if (NS_FAILED(rv)) { LOG(("CacheIndex::StartReadingIndex() - CacheFileIOManager::Read() failed " "synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); } else { mRWPending = true; } } void -CacheIndex::ParseRecords() +CacheIndex::ParseRecords(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ParseRecords()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(!mRWPending); uint32_t entryCnt = (mIndexHandle->FileSize() - sizeof(CacheIndexHeader) - @@ -2117,7 +2107,7 @@ CacheIndex::ParseRecords() if (!mSkipEntries) { if (NetworkEndian::readUint32(mRWBuf + pos) != kIndexVersion) { - FinishRead(false); + FinishRead(false, aProofOfLock); return; } pos += sizeof(uint32_t); @@ -2163,11 +2153,11 @@ CacheIndex::ParseRecords() " whole index [dirty=%d, initialized=%d, fileEmpty=%d, fresh=%d, " "removed=%d]", tmpEntry.IsDirty(), tmpEntry.IsInitialized(), tmpEntry.IsFileEmpty(), tmpEntry.IsFresh(), tmpEntry.IsRemoved())); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } - CacheIndexEntryAutoManage emng(tmpEntry.Hash(), this); + CacheIndexEntryAutoManage emng(tmpEntry.Hash(), this, aProofOfLock); CacheIndexEntry *entry = mIndex.PutEntry(*tmpEntry.Hash()); *entry = tmpEntry; @@ -2194,7 +2184,7 @@ CacheIndex::ParseRecords() if (mRWHash->GetHash() != expectedHash) { LOG(("CacheIndex::ParseRecords() - Hash mismatch, [is %x, should be %x]", mRWHash->GetHash(), expectedHash)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2202,9 +2192,9 @@ CacheIndex::ParseRecords() mJournalReadSuccessfully = false; if (mJournalHandle) { - StartReadingJournal(); + StartReadingJournal(aProofOfLock); } else { - FinishRead(false); + FinishRead(false, aProofOfLock); } return; @@ -2221,7 +2211,7 @@ CacheIndex::ParseRecords() if (NS_FAILED(rv)) { LOG(("CacheIndex::ParseRecords() - CacheFileIOManager::Read() failed " "synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } else { mRWPending = true; @@ -2229,14 +2219,12 @@ CacheIndex::ParseRecords() } void -CacheIndex::StartReadingJournal() +CacheIndex::StartReadingJournal(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::StartReadingJournal()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(mJournalHandle); MOZ_ASSERT(mIndexOnDiskIsValid); MOZ_ASSERT(mTmpJournal.Count() == 0); @@ -2248,7 +2236,7 @@ CacheIndex::StartReadingJournal() if (entriesSize < 0 || entriesSize % sizeof(CacheIndexRecord)) { LOG(("CacheIndex::StartReadingJournal() - Journal is corrupted")); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2262,21 +2250,19 @@ CacheIndex::StartReadingJournal() if (NS_FAILED(rv)) { LOG(("CacheIndex::StartReadingJournal() - CacheFileIOManager::Read() failed" " synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); } else { mRWPending = true; } } void -CacheIndex::ParseJournal() +CacheIndex::ParseJournal(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ParseJournal()")); nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(!mRWPending); uint32_t entryCnt = (mJournalHandle->FileSize() - @@ -2296,7 +2282,7 @@ CacheIndex::ParseJournal() LOG(("CacheIndex::ParseJournal() - Invalid entry found in journal, " "ignoring whole journal [dirty=%d, fresh=%d]", entry->IsDirty(), entry->IsFresh())); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } @@ -2321,12 +2307,12 @@ CacheIndex::ParseJournal() if (mRWHash->GetHash() != expectedHash) { LOG(("CacheIndex::ParseJournal() - Hash mismatch, [is %x, should be %x]", mRWHash->GetHash(), expectedHash)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } mJournalReadSuccessfully = true; - FinishRead(true); + FinishRead(true, aProofOfLock); return; } @@ -2341,7 +2327,7 @@ CacheIndex::ParseJournal() if (NS_FAILED(rv)) { LOG(("CacheIndex::ParseJournal() - CacheFileIOManager::Read() failed " "synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); return; } else { mRWPending = true; @@ -2349,12 +2335,10 @@ CacheIndex::ParseJournal() } void -CacheIndex::MergeJournal() +CacheIndex::MergeJournal(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::MergeJournal()")); - sLock.AssertCurrentThreadOwns(); - for (auto iter = mTmpJournal.Iter(); !iter.Done(); iter.Next()) { CacheIndexEntry* entry = iter.Get(); @@ -2363,7 +2347,7 @@ CacheIndex::MergeJournal() CacheIndexEntry* entry2 = mIndex.GetEntry(*entry->Hash()); { - CacheIndexEntryAutoManage emng(entry->Hash(), this); + CacheIndexEntryAutoManage emng(entry->Hash(), this, aProofOfLock); if (entry->IsRemoved()) { if (entry2) { entry2->MarkRemoved(); @@ -2414,10 +2398,9 @@ CacheIndex::EnsureCorrectStats() } void -CacheIndex::FinishRead(bool aSucceeded) +CacheIndex::FinishRead(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FinishRead() [succeeded=%d]", aSucceeded)); - sLock.AssertCurrentThreadOwns(); MOZ_ASSERT((!aSucceeded && mState == SHUTDOWN) || mState == READING); @@ -2471,27 +2454,27 @@ CacheIndex::FinishRead(bool aSucceeded) if (!mIndexOnDiskIsValid) { MOZ_ASSERT(mTmpJournal.Count() == 0); EnsureNoFreshEntry(); - ProcessPendingOperations(); + ProcessPendingOperations(aProofOfLock); // Remove all entries that we haven't seen during this session - RemoveNonFreshEntries(); - StartUpdatingIndex(true); + RemoveNonFreshEntries(aProofOfLock); + StartUpdatingIndex(true, aProofOfLock); return; } if (!mJournalReadSuccessfully) { mTmpJournal.Clear(); EnsureNoFreshEntry(); - ProcessPendingOperations(); - StartUpdatingIndex(false); + ProcessPendingOperations(aProofOfLock); + StartUpdatingIndex(false, aProofOfLock); return; } - MergeJournal(); + MergeJournal(aProofOfLock); EnsureNoFreshEntry(); - ProcessPendingOperations(); + ProcessPendingOperations(aProofOfLock); mIndexStats.Log(); - ChangeState(READY); + ChangeState(READY, aProofOfLock); mLastDumpTime = TimeStamp::NowLoRes(); // Do not dump new index immediately } @@ -2508,17 +2491,15 @@ CacheIndex::DelayedUpdate(nsITimer *aTimer, void *aClosure) return; } - index->DelayedUpdateLocked(); + index->DelayedUpdateLocked(lock); } // static void -CacheIndex::DelayedUpdateLocked() +CacheIndex::DelayedUpdateLocked(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::DelayedUpdateLocked()")); - sLock.AssertCurrentThreadOwns(); - nsresult rv; mUpdateTimer = nullptr; @@ -2549,7 +2530,7 @@ CacheIndex::DelayedUpdateLocked() mUpdateEventPending = false; NS_WARNING("CacheIndex::DelayedUpdateLocked() - Can't dispatch event"); LOG(("CacheIndex::DelayedUpdate() - Can't dispatch event" )); - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); } } @@ -2655,12 +2636,10 @@ CacheIndex::IsUpdatePending() } void -CacheIndex::BuildIndex() +CacheIndex::BuildIndex(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::BuildIndex()")); - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(mPendingUpdates.Count() == 0); nsresult rv; @@ -2678,7 +2657,7 @@ CacheIndex::BuildIndex() } if (NS_FAILED(rv)) { - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); return; } } @@ -2700,7 +2679,7 @@ CacheIndex::BuildIndex() return; } if (!file) { - FinishUpdate(NS_SUCCEEDED(rv)); + FinishUpdate(NS_SUCCEEDED(rv), aProofOfLock); return; } @@ -2780,7 +2759,7 @@ CacheIndex::BuildIndex() "failed, removing file. [name=%s]", leaf.get())); file->Remove(false); } else { - CacheIndexEntryAutoManage entryMng(&hash, this); + CacheIndexEntryAutoManage entryMng(&hash, this, aProofOfLock); entry = mIndex.PutEntry(hash); InitEntryFromDiskData(entry, meta, size); LOG(("CacheIndex::BuildIndex() - Added entry to index. [hash=%s]", @@ -2793,7 +2772,8 @@ CacheIndex::BuildIndex() } bool -CacheIndex::StartUpdatingIndexIfNeeded(bool aSwitchingToReadyState) +CacheIndex::StartUpdatingIndexIfNeeded(const StaticMutexAutoLock& aProofOfLock, + bool aSwitchingToReadyState) { // Start updating process when we are in or we are switching to READY state // and index needs update, but not during shutdown or when removing all @@ -2802,7 +2782,7 @@ CacheIndex::StartUpdatingIndexIfNeeded(bool aSwitchingToReadyState) !mShuttingDown && !mRemovingAll) { LOG(("CacheIndex::StartUpdatingIndexIfNeeded() - starting update process")); mIndexNeedsUpdate = false; - StartUpdatingIndex(false); + StartUpdatingIndex(false, aProofOfLock); return true; } @@ -2810,21 +2790,20 @@ CacheIndex::StartUpdatingIndexIfNeeded(bool aSwitchingToReadyState) } void -CacheIndex::StartUpdatingIndex(bool aRebuild) +CacheIndex::StartUpdatingIndex(bool aRebuild, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::StartUpdatingIndex() [rebuild=%d]", aRebuild)); - sLock.AssertCurrentThreadOwns(); - nsresult rv; mIndexStats.Log(); - ChangeState(aRebuild ? BUILDING : UPDATING); + ChangeState(aRebuild ? BUILDING : UPDATING, aProofOfLock); mDontMarkIndexClean = false; if (mShuttingDown || mRemovingAll) { - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); return; } @@ -2861,17 +2840,15 @@ CacheIndex::StartUpdatingIndex(bool aRebuild) mUpdateEventPending = false; NS_WARNING("CacheIndex::StartUpdatingIndex() - Can't dispatch event"); LOG(("CacheIndex::StartUpdatingIndex() - Can't dispatch event" )); - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); } } void -CacheIndex::UpdateIndex() +CacheIndex::UpdateIndex(const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::UpdateIndex()")); - sLock.AssertCurrentThreadOwns(); - MOZ_ASSERT(mPendingUpdates.Count() == 0); nsresult rv; @@ -2889,7 +2866,7 @@ CacheIndex::UpdateIndex() } if (NS_FAILED(rv)) { - FinishUpdate(false); + FinishUpdate(false, aProofOfLock); return; } } @@ -2912,7 +2889,7 @@ CacheIndex::UpdateIndex() return; } if (!file) { - FinishUpdate(NS_SUCCEEDED(rv)); + FinishUpdate(NS_SUCCEEDED(rv), aProofOfLock); return; } @@ -2983,7 +2960,7 @@ CacheIndex::UpdateIndex() "lastModifiedTime=%u]", leaf.get(), mIndexTimeStamp, lastModifiedTime / PR_MSEC_PER_SEC)); - CacheIndexEntryAutoManage entryMng(&hash, this); + CacheIndexEntryAutoManage entryMng(&hash, this, aProofOfLock); entry->MarkFresh(); continue; } @@ -3015,7 +2992,7 @@ CacheIndex::UpdateIndex() entry = mIndex.GetEntry(hash); MOZ_ASSERT(!entry || !entry->IsFresh()); - CacheIndexEntryAutoManage entryMng(&hash, this); + CacheIndexEntryAutoManage entryMng(&hash, this, aProofOfLock); if (NS_FAILED(rv)) { LOG(("CacheIndex::UpdateIndex() - CacheFileMetadata::SyncReadMetadata() " @@ -3039,15 +3016,13 @@ CacheIndex::UpdateIndex() } void -CacheIndex::FinishUpdate(bool aSucceeded) +CacheIndex::FinishUpdate(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FinishUpdate() [succeeded=%d]", aSucceeded)); MOZ_ASSERT(mState == UPDATING || mState == BUILDING || (!aSucceeded && mState == SHUTDOWN)); - sLock.AssertCurrentThreadOwns(); - if (mDirEnumerator) { if (NS_IsMainThread()) { LOG(("CacheIndex::FinishUpdate() - posting of PreShutdownInternal failed?" @@ -3074,19 +3049,19 @@ CacheIndex::FinishUpdate(bool aSucceeded) // If we've iterated over all entries successfully then all entries that // really exist on the disk are now marked as fresh. All non-fresh entries // don't exist anymore and must be removed from the index. - RemoveNonFreshEntries(); + RemoveNonFreshEntries(aProofOfLock); } // Make sure we won't start update. If the build or update failed, there is no // reason to believe that it will succeed next time. mIndexNeedsUpdate = false; - ChangeState(READY); + ChangeState(READY, aProofOfLock); mLastDumpTime = TimeStamp::NowLoRes(); // Do not dump new index immediately } void -CacheIndex::RemoveNonFreshEntries() +CacheIndex::RemoveNonFreshEntries(const StaticMutexAutoLock& aProofOfLock) { for (auto iter = mIndex.Iter(); !iter.Done(); iter.Next()) { CacheIndexEntry* entry = iter.Get(); @@ -3098,7 +3073,7 @@ CacheIndex::RemoveNonFreshEntries() "[hash=%08x%08x%08x%08x%08x]", LOGSHA1(entry->Hash()))); { - CacheIndexEntryAutoManage emng(entry->Hash(), this); + CacheIndexEntryAutoManage emng(entry->Hash(), this, aProofOfLock); emng.DoNotSearchInIndex(); } @@ -3125,7 +3100,7 @@ CacheIndex::StateString(EState aState) } void -CacheIndex::ChangeState(EState aNewState) +CacheIndex::ChangeState(EState aNewState, const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::ChangeState() changing state %s -> %s", StateString(mState), StateString(aNewState))); @@ -3139,7 +3114,7 @@ CacheIndex::ChangeState(EState aNewState) MOZ_ASSERT(!mShuttingDown || mState != READY || aNewState == SHUTDOWN); // Start updating process when switching to READY state if needed - if (aNewState == READY && StartUpdatingIndexIfNeeded(true)) { + if (aNewState == READY && StartUpdatingIndexIfNeeded(aProofOfLock, true)) { return; } @@ -3213,23 +3188,25 @@ CacheIndex::ReleaseBuffer() } void -CacheIndex::FrecencyArray::AppendRecord(CacheIndexRecord *aRecord) +CacheIndex::FrecencyArray::AppendRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FrecencyArray::AppendRecord() [record=%p, hash=%08x%08x%08x" - "%08x%08x]", aRecord, LOGSHA1(aRecord->mHash))); + "%08x%08x]", aRecord, LOGSHA1(aRecord->Get()->mHash))); MOZ_ASSERT(!mRecs.Contains(aRecord)); mRecs.AppendElement(aRecord); // If the new frecency is 0, the element should be at the end of the array, // i.e. this change doesn't affect order of the array - if (aRecord->mFrecency != 0) { + if (aRecord->Get()->mFrecency != 0) { ++mUnsortedElements; } } void -CacheIndex::FrecencyArray::RemoveRecord(CacheIndexRecord *aRecord) +CacheIndex::FrecencyArray::RemoveRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FrecencyArray::RemoveRecord() [record=%p]", aRecord)); @@ -3241,12 +3218,13 @@ CacheIndex::FrecencyArray::RemoveRecord(CacheIndexRecord *aRecord) // Calling SortIfNeeded ensures that we get rid of removed elements in the // array once we hit the limit. - SortIfNeeded(); + SortIfNeeded(aProofOfLock); } void -CacheIndex::FrecencyArray::ReplaceRecord(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord) +CacheIndex::FrecencyArray::ReplaceRecord(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::FrecencyArray::ReplaceRecord() [oldRecord=%p, " "newRecord=%p]", aOldRecord, aNewRecord)); @@ -3258,7 +3236,7 @@ CacheIndex::FrecencyArray::ReplaceRecord(CacheIndexRecord *aOldRecord, } void -CacheIndex::FrecencyArray::SortIfNeeded() +CacheIndex::FrecencyArray::SortIfNeeded(const StaticMutexAutoLock& aProofOfLock) { const uint32_t kMaxUnsortedCount = 512; const uint32_t kMaxUnsortedPercent = 10; @@ -3290,44 +3268,41 @@ CacheIndex::FrecencyArray::SortIfNeeded() } void -CacheIndex::AddRecordToIterators(CacheIndexRecord *aRecord) +CacheIndex::AddRecordToIterators(CacheIndexRecordWrapper *aRecord, + const StaticMutexAutoLock& aProofOfLock) { - sLock.AssertCurrentThreadOwns(); - for (uint32_t i = 0; i < mIterators.Length(); ++i) { // Add a new record only when iterator is supposed to be updated. if (mIterators[i]->ShouldBeNewAdded()) { - mIterators[i]->AddRecord(aRecord); + mIterators[i]->AddRecord(aRecord, aProofOfLock); } } } void -CacheIndex::RemoveRecordFromIterators(CacheIndexRecord *aRecord) +CacheIndex::RemoveRecordFromIterators(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { - sLock.AssertCurrentThreadOwns(); - for (uint32_t i = 0; i < mIterators.Length(); ++i) { // Remove the record from iterator always, it makes no sence to return // non-existing entries. Also the pointer to the record is no longer valid // once the entry is removed from index. - mIterators[i]->RemoveRecord(aRecord); + mIterators[i]->RemoveRecord(aRecord, aProofOfLock); } } void -CacheIndex::ReplaceRecordInIterators(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord) +CacheIndex::ReplaceRecordInIterators(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock) { - sLock.AssertCurrentThreadOwns(); - for (uint32_t i = 0; i < mIterators.Length(); ++i) { // We have to replace the record always since the pointer is no longer // valid after this point. NOTE: Replacing the record doesn't mean that // a new entry was added, it just means that the data in the entry was // changed (e.g. a file size) and we had to track this change in // mPendingUpdates since mIndex was read-only. - mIterators[i]->ReplaceRecord(aOldRecord, aNewRecord); + mIterators[i]->ReplaceRecord(aOldRecord, aNewRecord, aProofOfLock); } } @@ -3350,10 +3325,10 @@ CacheIndex::Run() switch (mState) { case BUILDING: - BuildIndex(); + BuildIndex(lock); break; case UPDATING: - UpdateIndex(); + UpdateIndex(lock); break; default: LOG(("CacheIndex::Run() - Update/Build was canceled")); @@ -3363,8 +3338,10 @@ CacheIndex::Run() } nsresult -CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, - CacheFileHandle *aHandle, nsresult aResult) +CacheIndex::OnFileOpenedInternal(FileOpenHelper* aOpener, + CacheFileHandle* aHandle, + nsresult aResult, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndex::OnFileOpenedInternal() [opener=%p, handle=%p, " "result=0x%08x]", aOpener, aHandle, aResult)); @@ -3373,8 +3350,6 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, nsresult rv; - sLock.AssertCurrentThreadOwns(); - MOZ_RELEASE_ASSERT(IsIndexUsable()); if (mState == READY && mShuttingDown) { @@ -3389,10 +3364,10 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, if (NS_FAILED(aResult)) { LOG(("CacheIndex::OnFileOpenedInternal() - Can't open index file for " "writing [rv=0x%08x]", aResult)); - FinishWrite(false); + FinishWrite(false, aProofOfLock); } else { mIndexHandle = aHandle; - WriteRecords(); + WriteRecords(aProofOfLock); } break; case READING: @@ -3401,14 +3376,14 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, if (NS_SUCCEEDED(aResult)) { if (aHandle->FileSize() == 0) { - FinishRead(false); + FinishRead(false, aProofOfLock); CacheFileIOManager::DoomFile(aHandle, nullptr); break; } else { mIndexHandle = aHandle; } } else { - FinishRead(false); + FinishRead(false, aProofOfLock); break; } } else if (aOpener == mJournalFileOpener) { @@ -3437,7 +3412,7 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, LOG(("CacheIndex::OnFileOpenedInternal() - Unexpected state, all " "files [%s, %s, %s] should never exist. Removing whole index.", INDEX_NAME, JOURNAL_NAME, TEMP_INDEX_NAME)); - FinishRead(false); + FinishRead(false, aProofOfLock); break; } } @@ -3450,11 +3425,11 @@ CacheIndex::OnFileOpenedInternal(FileOpenHelper *aOpener, if (NS_FAILED(rv)) { LOG(("CacheIndex::OnFileOpenedInternal() - CacheFileIOManager::" "RenameFile() failed synchronously [rv=0x%08x]", rv)); - FinishRead(false); + FinishRead(false, aProofOfLock); break; } } else { - StartReadingIndex(); + StartReadingIndex(aProofOfLock); } break; @@ -3498,7 +3473,7 @@ CacheIndex::OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, MOZ_ASSERT(mIndexHandle == aHandle); if (NS_FAILED(aResult)) { - FinishWrite(false); + FinishWrite(false, lock); } else { if (mSkipEntries == mProcessEntries) { rv = CacheFileIOManager::RenameFile(mIndexHandle, @@ -3507,10 +3482,10 @@ CacheIndex::OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, if (NS_FAILED(rv)) { LOG(("CacheIndex::OnDataWritten() - CacheFileIOManager::" "RenameFile() failed synchronously [rv=0x%08x]", rv)); - FinishWrite(false); + FinishWrite(false, lock); } } else { - WriteRecords(); + WriteRecords(lock); } } break; @@ -3543,12 +3518,12 @@ CacheIndex::OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) MOZ_ASSERT(mIndexHandle == aHandle || mJournalHandle == aHandle); if (NS_FAILED(aResult)) { - FinishRead(false); + FinishRead(false, lock); } else { if (!mIndexOnDiskIsValid) { - ParseRecords(); + ParseRecords(lock); } else { - ParseJournal(); + ParseJournal(lock); } } break; @@ -3604,7 +3579,7 @@ CacheIndex::OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) break; } - FinishWrite(NS_SUCCEEDED(aResult)); + FinishWrite(NS_SUCCEEDED(aResult), lock); break; case READING: // This is a result of renaming journal file to tmpfile. It is renamed @@ -3618,9 +3593,9 @@ CacheIndex::OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) } if (NS_FAILED(aResult)) { - FinishRead(false); + FinishRead(false, lock); } else { - StartReadingIndex(); + StartReadingIndex(lock); } break; default: diff --git a/netwerk/cache2/CacheIndex.h b/netwerk/cache2/CacheIndex.h index acb3bdd250..7d875da626 100644 --- a/netwerk/cache2/CacheIndex.h +++ b/netwerk/cache2/CacheIndex.h @@ -93,6 +93,19 @@ static_assert( sizeof(CacheIndexRecord::mFlags) == sizeof(CacheIndexRecord), "Unexpected sizeof(CacheIndexRecord)!"); +class CacheIndexRecordWrapper final +{ +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CacheIndexRecordWrapper) + + CacheIndexRecordWrapper() : mRec(MakeUnique()) {} + CacheIndexRecord* Get() { return mRec.get(); } + +private: + ~CacheIndexRecordWrapper() = default; + UniquePtr mRec; +}; + class CacheIndexEntry : public PLDHashEntryHdr { public: @@ -102,9 +115,9 @@ public: explicit CacheIndexEntry(KeyTypePointer aKey) { MOZ_COUNT_CTOR(CacheIndexEntry); - mRec = new CacheIndexRecord(); - LOG(("CacheIndexEntry::CacheIndexEntry() - Created record [rec=%p]", mRec.get())); - memcpy(&mRec->mHash, aKey, sizeof(SHA1Sum::Hash)); + mRec = new CacheIndexRecordWrapper(); + LOG(("CacheIndexEntry::CacheIndexEntry() - Created record [rec=%p]", mRec->Get())); + memcpy(&mRec->Get()->mHash, aKey, sizeof(SHA1Sum::Hash)); } CacheIndexEntry(const CacheIndexEntry& aOther) { @@ -114,13 +127,13 @@ public: { MOZ_COUNT_DTOR(CacheIndexEntry); LOG(("CacheIndexEntry::~CacheIndexEntry() - Deleting record [rec=%p]", - mRec.get())); + mRec->Get())); } // KeyEquals(): does this entry match this key? bool KeyEquals(KeyTypePointer aKey) const { - return memcmp(&mRec->mHash, aKey, sizeof(SHA1Sum::Hash)) == 0; + return memcmp(&mRec->Get()->mHash, aKey, sizeof(SHA1Sum::Hash)) == 0; } // KeyToPointer(): Convert KeyType to KeyTypePointer @@ -138,74 +151,74 @@ public: bool operator==(const CacheIndexEntry& aOther) const { - return KeyEquals(&aOther.mRec->mHash); + return KeyEquals(&aOther.mRec->Get()->mHash); } CacheIndexEntry& operator=(const CacheIndexEntry& aOther) { - MOZ_ASSERT(memcmp(&mRec->mHash, &aOther.mRec->mHash, + MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aOther.mRec->Get()->mHash, sizeof(SHA1Sum::Hash)) == 0); - mRec->mFrecency = aOther.mRec->mFrecency; - mRec->mExpirationTime = aOther.mRec->mExpirationTime; - mRec->mOriginAttrsHash = aOther.mRec->mOriginAttrsHash; - mRec->mFlags = aOther.mRec->mFlags; + mRec->Get()->mFrecency = aOther.mRec->Get()->mFrecency; + mRec->Get()->mExpirationTime = aOther.mRec->Get()->mExpirationTime; + mRec->Get()->mOriginAttrsHash = aOther.mRec->Get()->mOriginAttrsHash; + mRec->Get()->mFlags = aOther.mRec->Get()->mFlags; return *this; } void InitNew() { - mRec->mFrecency = 0; - mRec->mExpirationTime = nsICacheEntry::NO_EXPIRATION_TIME; - mRec->mOriginAttrsHash = 0; - mRec->mFlags = 0; + mRec->Get()->mFrecency = 0; + mRec->Get()->mExpirationTime = nsICacheEntry::NO_EXPIRATION_TIME; + mRec->Get()->mOriginAttrsHash = 0; + mRec->Get()->mFlags = 0; } void Init(OriginAttrsHash aOriginAttrsHash, bool aAnonymous, bool aPinned) { - MOZ_ASSERT(mRec->mFrecency == 0); - MOZ_ASSERT(mRec->mExpirationTime == nsICacheEntry::NO_EXPIRATION_TIME); - MOZ_ASSERT(mRec->mOriginAttrsHash == 0); + MOZ_ASSERT(mRec->Get()->mFrecency == 0); + MOZ_ASSERT(mRec->Get()->mExpirationTime == nsICacheEntry::NO_EXPIRATION_TIME); + MOZ_ASSERT(mRec->Get()->mOriginAttrsHash == 0); // When we init the entry it must be fresh and may be dirty - MOZ_ASSERT((mRec->mFlags & ~kDirtyMask) == kFreshMask); + MOZ_ASSERT((mRec->Get()->mFlags & ~kDirtyMask) == kFreshMask); - mRec->mOriginAttrsHash = aOriginAttrsHash; - mRec->mFlags |= kInitializedMask; + mRec->Get()->mOriginAttrsHash = aOriginAttrsHash; + mRec->Get()->mFlags |= kInitializedMask; if (aAnonymous) { - mRec->mFlags |= kAnonymousMask; + mRec->Get()->mFlags |= kAnonymousMask; } if (aPinned) { - mRec->mFlags |= kPinnedMask; + mRec->Get()->mFlags |= kPinnedMask; } } - const SHA1Sum::Hash * Hash() const { return &mRec->mHash; } + const SHA1Sum::Hash * Hash() const { return &mRec->Get()->mHash; } - bool IsInitialized() const { return !!(mRec->mFlags & kInitializedMask); } + bool IsInitialized() const { return !!(mRec->Get()->mFlags & kInitializedMask); } - mozilla::net::OriginAttrsHash OriginAttrsHash() const { return mRec->mOriginAttrsHash; } + mozilla::net::OriginAttrsHash OriginAttrsHash() const { return mRec->Get()->mOriginAttrsHash; } - bool Anonymous() const { return !!(mRec->mFlags & kAnonymousMask); } + bool Anonymous() const { return !!(mRec->Get()->mFlags & kAnonymousMask); } - bool IsRemoved() const { return !!(mRec->mFlags & kRemovedMask); } - void MarkRemoved() { mRec->mFlags |= kRemovedMask; } + bool IsRemoved() const { return !!(mRec->Get()->mFlags & kRemovedMask); } + void MarkRemoved() { mRec->Get()->mFlags |= kRemovedMask; } - bool IsDirty() const { return !!(mRec->mFlags & kDirtyMask); } - void MarkDirty() { mRec->mFlags |= kDirtyMask; } - void ClearDirty() { mRec->mFlags &= ~kDirtyMask; } + bool IsDirty() const { return !!(mRec->Get()->mFlags & kDirtyMask); } + void MarkDirty() { mRec->Get()->mFlags |= kDirtyMask; } + void ClearDirty() { mRec->Get()->mFlags &= ~kDirtyMask; } - bool IsFresh() const { return !!(mRec->mFlags & kFreshMask); } - void MarkFresh() { mRec->mFlags |= kFreshMask; } + bool IsFresh() const { return !!(mRec->Get()->mFlags & kFreshMask); } + void MarkFresh() { mRec->Get()->mFlags |= kFreshMask; } - bool IsPinned() const { return !!(mRec->mFlags & kPinnedMask); } + bool IsPinned() const { return !!(mRec->Get()->mFlags & kPinnedMask); } - void SetFrecency(uint32_t aFrecency) { mRec->mFrecency = aFrecency; } - uint32_t GetFrecency() const { return mRec->mFrecency; } + void SetFrecency(uint32_t aFrecency) { mRec->Get()->mFrecency = aFrecency; } + uint32_t GetFrecency() const { return mRec->Get()->mFrecency; } void SetExpirationTime(uint32_t aExpirationTime) { - mRec->mExpirationTime = aExpirationTime; + mRec->Get()->mExpirationTime = aExpirationTime; } - uint32_t GetExpirationTime() const { return mRec->mExpirationTime; } + uint32_t GetExpirationTime() const { return mRec->Get()->mExpirationTime; } // Sets filesize in kilobytes. void SetFileSize(uint32_t aFileSize) @@ -215,11 +228,11 @@ public: "truncating to %u", kFileSizeMask)); aFileSize = kFileSizeMask; } - mRec->mFlags &= ~kFileSizeMask; - mRec->mFlags |= aFileSize; + mRec->Get()->mFlags &= ~kFileSizeMask; + mRec->Get()->mFlags |= aFileSize; } // Returns filesize in kilobytes. - uint32_t GetFileSize() const { return GetFileSize(mRec); } + uint32_t GetFileSize() const { return GetFileSize(mRec->Get()); } static uint32_t GetFileSize(CacheIndexRecord *aRec) { return aRec->mFlags & kFileSizeMask; @@ -233,40 +246,48 @@ public: void WriteToBuf(void *aBuf) { uint8_t* ptr = static_cast(aBuf); - memcpy(ptr, mRec->mHash, sizeof(SHA1Sum::Hash)); ptr += sizeof(SHA1Sum::Hash); - NetworkEndian::writeUint32(ptr, mRec->mFrecency); ptr += sizeof(uint32_t); - NetworkEndian::writeUint64(ptr, mRec->mOriginAttrsHash); ptr += sizeof(uint64_t); - NetworkEndian::writeUint32(ptr, mRec->mExpirationTime); ptr += sizeof(uint32_t); + memcpy(ptr, mRec->Get()->mHash, sizeof(SHA1Sum::Hash)); + ptr += sizeof(SHA1Sum::Hash); + NetworkEndian::writeUint32(ptr, mRec->Get()->mFrecency); + ptr += sizeof(uint32_t); + NetworkEndian::writeUint64(ptr, mRec->Get()->mOriginAttrsHash); + ptr += sizeof(uint64_t); + NetworkEndian::writeUint32(ptr, mRec->Get()->mExpirationTime); + ptr += sizeof(uint32_t); // Dirty and fresh flags should never go to disk, since they make sense only // during current session. - NetworkEndian::writeUint32(ptr, mRec->mFlags & ~(kDirtyMask | kFreshMask)); + NetworkEndian::writeUint32(ptr, mRec->Get()->mFlags & ~(kDirtyMask | kFreshMask)); } void ReadFromBuf(void *aBuf) { const uint8_t* ptr = static_cast(aBuf); - MOZ_ASSERT(memcmp(&mRec->mHash, ptr, sizeof(SHA1Sum::Hash)) == 0); ptr += sizeof(SHA1Sum::Hash); - mRec->mFrecency = NetworkEndian::readUint32(ptr); ptr += sizeof(uint32_t); - mRec->mOriginAttrsHash = NetworkEndian::readUint64(ptr); ptr += sizeof(uint64_t); - mRec->mExpirationTime = NetworkEndian::readUint32(ptr); ptr += sizeof(uint32_t); - mRec->mFlags = NetworkEndian::readUint32(ptr); + MOZ_ASSERT(memcmp(&mRec->Get()->mHash, ptr, sizeof(SHA1Sum::Hash)) == 0); + ptr += sizeof(SHA1Sum::Hash); + mRec->Get()->mFrecency = NetworkEndian::readUint32(ptr); + ptr += sizeof(uint32_t); + mRec->Get()->mOriginAttrsHash = NetworkEndian::readUint64(ptr); + ptr += sizeof(uint64_t); + mRec->Get()->mExpirationTime = NetworkEndian::readUint32(ptr); + ptr += sizeof(uint32_t); + mRec->Get()->mFlags = NetworkEndian::readUint32(ptr); } void Log() const { LOG(("CacheIndexEntry::Log() [this=%p, hash=%08x%08x%08x%08x%08x, fresh=%u," " initialized=%u, removed=%u, dirty=%u, anonymous=%u, " "originAttrsHash=%llx, frecency=%u, expirationTime=%u, size=%u]", - this, LOGSHA1(mRec->mHash), IsFresh(), IsInitialized(), IsRemoved(), - IsDirty(), Anonymous(), OriginAttrsHash(), GetFrecency(), + this, LOGSHA1(mRec->Get()->mHash), IsFresh(), IsInitialized(), + IsRemoved(), IsDirty(), Anonymous(), OriginAttrsHash(), GetFrecency(), GetExpirationTime(), GetFileSize())); } - static bool RecordMatchesLoadContextInfo(CacheIndexRecord *aRec, + static bool RecordMatchesLoadContextInfo(CacheIndexRecordWrapper *aRec, nsILoadContextInfo *aInfo) { if (!aInfo->IsPrivate() && - GetOriginAttrsHash(*aInfo->OriginAttributesPtr()) == aRec->mOriginAttrsHash && - aInfo->IsAnonymous() == !!(aRec->mFlags & kAnonymousMask)) { + GetOriginAttrsHash(*aInfo->OriginAttributesPtr()) == aRec->Get()->mOriginAttrsHash && + aInfo->IsAnonymous() == !!(aRec->Get()->mFlags & kAnonymousMask)) { return true; } @@ -276,7 +297,7 @@ public: // Memory reporting size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const { - return mallocSizeOf(mRec.get()); + return mallocSizeOf(mRec->Get()); } size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const @@ -313,7 +334,7 @@ private: // FileSize in kilobytes static const uint32_t kFileSizeMask = 0x00FFFFFF; - nsAutoPtr mRec; + RefPtr mRec; }; class CacheIndexEntryUpdate : public CacheIndexEntry @@ -334,7 +355,7 @@ public: CacheIndexEntryUpdate& operator=(const CacheIndexEntry& aOther) { - MOZ_ASSERT(memcmp(&mRec->mHash, &aOther.mRec->mHash, + MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aOther.mRec->Get()->mHash, sizeof(SHA1Sum::Hash)) == 0); mUpdateFlags = 0; *(static_cast(this)) = aOther; @@ -367,21 +388,21 @@ public: } void ApplyUpdate(CacheIndexEntry *aDst) { - MOZ_ASSERT(memcmp(&mRec->mHash, &aDst->mRec->mHash, + MOZ_ASSERT(memcmp(&mRec->Get()->mHash, &aDst->mRec->Get()->mHash, sizeof(SHA1Sum::Hash)) == 0); if (mUpdateFlags & kFrecencyUpdatedMask) { - aDst->mRec->mFrecency = mRec->mFrecency; + aDst->mRec->Get()->mFrecency = mRec->Get()->mFrecency; } if (mUpdateFlags & kExpirationUpdatedMask) { - aDst->mRec->mExpirationTime = mRec->mExpirationTime; + aDst->mRec->Get()->mExpirationTime = mRec->Get()->mExpirationTime; } - aDst->mRec->mOriginAttrsHash = mRec->mOriginAttrsHash; + aDst->mRec->Get()->mOriginAttrsHash = mRec->Get()->mOriginAttrsHash; if (mUpdateFlags & kFileSizeUpdatedMask) { - aDst->mRec->mFlags = mRec->mFlags; + aDst->mRec->Get()->mFlags = mRec->Get()->mFlags; } else { // Copy all flags except file size. - aDst->mRec->mFlags &= kFileSizeMask; - aDst->mRec->mFlags |= (mRec->mFlags & ~kFileSizeMask); + aDst->mRec->Get()->mFlags &= kFileSizeMask; + aDst->mRec->Get()->mFlags |= (mRec->Get()->mFlags & ~kFileSizeMask); } } @@ -698,7 +719,9 @@ private: NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) override; nsresult OnFileOpenedInternal(FileOpenHelper *aOpener, - CacheFileHandle *aHandle, nsresult aResult); + CacheFileHandle *aHandle, + nsresult aResult, + const StaticMutexAutoLock& aProofOfLock); NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, nsresult aResult) override; NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) override; @@ -706,7 +729,7 @@ private: NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override; NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override; - nsresult InitInternal(nsIFile *aCacheDirectory); + nsresult InitInternal(nsIFile *aCacheDirectory, const StaticMutexAutoLock& aProofOfLock); void PreShutdownInternal(); // This method returns false when index is not initialized or is shut down. @@ -727,7 +750,7 @@ private: const uint32_t *aSize); // Merge all pending operations from mPendingUpdates into mIndex. - void ProcessPendingOperations(); + void ProcessPendingOperations(const StaticMutexAutoLock& aProofOfLock); // Following methods perform writing of the index file. // @@ -739,14 +762,14 @@ private: // // Starts writing of index when both limits (minimal delay between writes and // minimum number of changes in index) were exceeded. - bool WriteIndexToDiskIfNeeded(); + bool WriteIndexToDiskIfNeeded(const StaticMutexAutoLock& aProofOfLock); // Starts writing of index file. - void WriteIndexToDisk(); + void WriteIndexToDisk(const StaticMutexAutoLock& aProofOfLock); // Serializes part of mIndex hashtable to the write buffer a writes the buffer // to the file. - void WriteRecords(); + void WriteRecords(const StaticMutexAutoLock& aProofOfLock); // Finalizes writing process. - void FinishWrite(bool aSucceeded); + void FinishWrite(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock); // Following methods perform writing of the journal during shutdown. All these // methods must be called only during shutdown since they write/delete files @@ -799,17 +822,17 @@ private: // FF crashes during parsing of the index. // // Initiates reading index from disk. - void ReadIndexFromDisk(); + void ReadIndexFromDisk(const StaticMutexAutoLock& aProofOfLock); // Starts reading data from index file. - void StartReadingIndex(); + void StartReadingIndex(const StaticMutexAutoLock& aProofOfLock); // Parses data read from index file. - void ParseRecords(); + void ParseRecords(const StaticMutexAutoLock& aProofOfLock); // Starts reading data from journal file. - void StartReadingJournal(); + void StartReadingJournal(const StaticMutexAutoLock& aProofOfLock); // Parses data read from journal file. - void ParseJournal(); + void ParseJournal(const StaticMutexAutoLock& aProofOfLock); // Merges entries from journal into mIndex. - void MergeJournal(); + void MergeJournal(const StaticMutexAutoLock& aProofOfLock); // In debug build this method checks that we have no fresh entry in mIndex // after we finish reading index and before we process pending operations. void EnsureNoFreshEntry(); @@ -817,12 +840,12 @@ private: // to make sure mIndexStats contains correct information. void EnsureCorrectStats(); // Finalizes reading process. - void FinishRead(bool aSucceeded); + void FinishRead(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock); // Following methods perform updating and building of the index. // Timer callback that starts update or build process. static void DelayedUpdate(nsITimer *aTimer, void *aClosure); - void DelayedUpdateLocked(); + void DelayedUpdateLocked(const StaticMutexAutoLock& aProofOfLock); // Posts timer event that start update or build process. nsresult ScheduleUpdateTimer(uint32_t aDelay); nsresult SetupDirectoryEnumerator(); @@ -833,20 +856,22 @@ private: bool IsUpdatePending(); // Iterates through all files in entries directory that we didn't create/open // during this session, parses them and adds the entries to the index. - void BuildIndex(); + void BuildIndex(const StaticMutexAutoLock& aProofOfLock); - bool StartUpdatingIndexIfNeeded(bool aSwitchingToReadyState = false); + bool StartUpdatingIndexIfNeeded(const StaticMutexAutoLock& aProofOfLock, + bool aSwitchingToReadyState = false); // Starts update or build process or fires a timer when it is too early after // startup. - void StartUpdatingIndex(bool aRebuild); + void StartUpdatingIndex(bool aRebuild, + const StaticMutexAutoLock& aProofOfLock); // Iterates through all files in entries directory that we didn't create/open // during this session and theirs last modified time is newer than timestamp // in the index header. Parses the files and adds the entries to the index. - void UpdateIndex(); + void UpdateIndex(const StaticMutexAutoLock& aProofOfLock); // Finalizes update or build process. - void FinishUpdate(bool aSucceeded); + void FinishUpdate(bool aSucceeded, const StaticMutexAutoLock& aProofOfLock); - void RemoveNonFreshEntries(); + void RemoveNonFreshEntries(const StaticMutexAutoLock& aProofOfLock); enum EState { // Initial state in which the index is not usable @@ -899,7 +924,7 @@ private: }; static char const * StateString(EState aState); - void ChangeState(EState aNewState); + void ChangeState(EState aNewState, const StaticMutexAutoLock& aProofOfLock); void NotifyAsyncGetDiskConsumptionCallbacks(); // Allocates and releases buffer used for reading and writing index. @@ -907,10 +932,13 @@ private: void ReleaseBuffer(); // Methods used by CacheIndexEntryAutoManage to keep the iterators up to date. - void AddRecordToIterators(CacheIndexRecord *aRecord); - void RemoveRecordFromIterators(CacheIndexRecord *aRecord); - void ReplaceRecordInIterators(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord); + void AddRecordToIterators(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + void RemoveRecordFromIterators(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + void ReplaceRecordInIterators(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock); // Memory reporting (private part) size_t SizeOfExcludingThisInternal(mozilla::MallocSizeOf mallocSizeOf) const; @@ -1023,7 +1051,7 @@ private: class Iterator { public: - explicit Iterator(nsTArray *aRecs) + explicit Iterator(nsTArray>* aRecs) : mRecs(aRecs) , mIdx(0) { @@ -1034,7 +1062,7 @@ private: bool Done() const { return mIdx == mRecs->Length(); } - CacheIndexRecord* Get() const + CacheIndexRecordWrapper* Get() const { MOZ_ASSERT(!Done()); return (*mRecs)[mIdx]; @@ -1050,7 +1078,7 @@ private: } private: - nsTArray *mRecs; + nsTArray>* mRecs; uint32_t mIdx; }; @@ -1061,19 +1089,22 @@ private: , mRemovedElements(0) {} // Methods used by CacheIndexEntryAutoManage to keep the array up to date. - void AppendRecord(CacheIndexRecord *aRecord); - void RemoveRecord(CacheIndexRecord *aRecord); - void ReplaceRecord(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord); - void SortIfNeeded(); + void AppendRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + void RemoveRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + void ReplaceRecord(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock); + void SortIfNeeded(const StaticMutexAutoLock& aProofOfLock); size_t Length() const { return mRecs.Length() - mRemovedElements; } - void Clear() { mRecs.Clear(); } + void Clear(const StaticMutexAutoLock& aProofOfLock) { mRecs.Clear(); } private: friend class CacheIndex; - nsTArray mRecs; + nsTArray> mRecs; uint32_t mUnsortedElements; // Instead of removing elements from the array immediately, we null them out // and the iterator skips them when accessing the array. The null pointers diff --git a/netwerk/cache2/CacheIndexContextIterator.cpp b/netwerk/cache2/CacheIndexContextIterator.cpp index 5f3cb7bd7c..570df2e058 100644 --- a/netwerk/cache2/CacheIndexContextIterator.cpp +++ b/netwerk/cache2/CacheIndexContextIterator.cpp @@ -24,20 +24,11 @@ CacheIndexContextIterator::~CacheIndexContextIterator() } void -CacheIndexContextIterator::AddRecord(CacheIndexRecord *aRecord) +CacheIndexContextIterator::AddRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { if (CacheIndexEntry::RecordMatchesLoadContextInfo(aRecord, mInfo)) { - CacheIndexIterator::AddRecord(aRecord); - } -} - -void -CacheIndexContextIterator::AddRecords( - const nsTArray &aRecords) -{ - // We need to add one by one so that those with wrong context are ignored. - for (uint32_t i = 0; i < aRecords.Length(); ++i) { - AddRecord(aRecords[i]); + CacheIndexIterator::AddRecord(aRecord, aProofOfLock); } } diff --git a/netwerk/cache2/CacheIndexContextIterator.h b/netwerk/cache2/CacheIndexContextIterator.h index 32eb9c4789..a0a595ae68 100644 --- a/netwerk/cache2/CacheIndexContextIterator.h +++ b/netwerk/cache2/CacheIndexContextIterator.h @@ -20,8 +20,8 @@ public: virtual ~CacheIndexContextIterator(); private: - virtual void AddRecord(CacheIndexRecord *aRecord); - virtual void AddRecords(const nsTArray &aRecords); + virtual void AddRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) override; nsCOMPtr mInfo; }; diff --git a/netwerk/cache2/CacheIndexIterator.cpp b/netwerk/cache2/CacheIndexIterator.cpp index 0d56ec81f5..6715b70835 100644 --- a/netwerk/cache2/CacheIndexIterator.cpp +++ b/netwerk/cache2/CacheIndexIterator.cpp @@ -24,7 +24,9 @@ CacheIndexIterator::~CacheIndexIterator() { LOG(("CacheIndexIterator::~CacheIndexIterator() [this=%p]", this)); - Close(); + StaticMutexAutoLock lock(CacheIndex::sLock); + ClearRecords(lock); + CloseInternal(NS_ERROR_NOT_AVAILABLE); } nsresult @@ -43,7 +45,7 @@ CacheIndexIterator::GetNextHash(SHA1Sum::Hash *aHash) return mStatus; } - memcpy(aHash, mRecords[mRecords.Length() - 1]->mHash, sizeof(SHA1Sum::Hash)); + memcpy(aHash, mRecords[mRecords.Length() - 1]->Get()->mHash, sizeof(SHA1Sum::Hash)); mRecords.RemoveElementAt(mRecords.Length() - 1); return NS_OK; @@ -82,8 +84,13 @@ CacheIndexIterator::CloseInternal(nsresult aStatus) return NS_OK; } -void -CacheIndexIterator::AddRecord(CacheIndexRecord *aRecord) +void CacheIndexIterator::ClearRecords(const StaticMutexAutoLock& aProofOfLock) +{ + mRecords.Clear(); +} + +void CacheIndexIterator::AddRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndexIterator::AddRecord() [this=%p, record=%p]", this, aRecord)); @@ -91,7 +98,8 @@ CacheIndexIterator::AddRecord(CacheIndexRecord *aRecord) } bool -CacheIndexIterator::RemoveRecord(CacheIndexRecord *aRecord) +CacheIndexIterator::RemoveRecord(CacheIndexRecordWrapper *aRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndexIterator::RemoveRecord() [this=%p, record=%p]", this, aRecord)); @@ -100,14 +108,15 @@ CacheIndexIterator::RemoveRecord(CacheIndexRecord *aRecord) } bool -CacheIndexIterator::ReplaceRecord(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord) +CacheIndexIterator::ReplaceRecord(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock) { LOG(("CacheIndexIterator::ReplaceRecord() [this=%p, oldRecord=%p, " "newRecord=%p]", this, aOldRecord, aNewRecord)); - if (RemoveRecord(aOldRecord)) { - AddRecord(aNewRecord); + if (RemoveRecord(aOldRecord, aProofOfLock)) { + AddRecord(aNewRecord, aProofOfLock); return true; } diff --git a/netwerk/cache2/CacheIndexIterator.h b/netwerk/cache2/CacheIndexIterator.h index 9fe96989ec..fd38fc2a03 100644 --- a/netwerk/cache2/CacheIndexIterator.h +++ b/netwerk/cache2/CacheIndexIterator.h @@ -9,12 +9,13 @@ #include "nsCOMPtr.h" #include "nsAutoPtr.h" #include "mozilla/SHA1.h" +#include "mozilla/StaticMutex.h" namespace mozilla { namespace net { class CacheIndex; -struct CacheIndexRecord; +class CacheIndexRecordWrapper; class CacheIndexIterator { @@ -42,14 +43,18 @@ protected: nsresult CloseInternal(nsresult aStatus); bool ShouldBeNewAdded() { return mAddNew; } - virtual void AddRecord(CacheIndexRecord *aRecord); - bool RemoveRecord(CacheIndexRecord *aRecord); - bool ReplaceRecord(CacheIndexRecord *aOldRecord, - CacheIndexRecord *aNewRecord); + virtual void AddRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + bool RemoveRecord(CacheIndexRecordWrapper* aRecord, + const StaticMutexAutoLock& aProofOfLock); + bool ReplaceRecord(CacheIndexRecordWrapper* aOldRecord, + CacheIndexRecordWrapper* aNewRecord, + const StaticMutexAutoLock& aProofOfLock); + void ClearRecords(const StaticMutexAutoLock& aProofOfLock); nsresult mStatus; RefPtr mIndex; - nsTArray mRecords; + nsTArray> mRecords; bool mAddNew; };